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> 4674ae819SStefano Zampini #include <petscblaslapack.h> 5daf8a457SStefano Zampini #include <petsc/private/sfimpl.h> 6674ae819SStefano Zampini 7*1e0482f5SStefano Zampini static PetscErrorCode MatMPIAIJRestrict(Mat,MPI_Comm,Mat*); 8*1e0482f5SStefano Zampini 9a13144ffSStefano Zampini /* returns B s.t. range(B) _|_ range(A) */ 10a13144ffSStefano Zampini #undef __FUNCT__ 11a13144ffSStefano Zampini #define __FUNCT__ "MatDense_OrthogonalComplement" 12a13144ffSStefano Zampini PetscErrorCode MatDense_OrthogonalComplement(Mat A, PetscInt lw, PetscScalar *work, PetscReal *rwork, Mat *B) 13a13144ffSStefano Zampini { 14a13144ffSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 15a13144ffSStefano Zampini PetscScalar *uwork,*data,*U, ds = 0.; 16a13144ffSStefano Zampini PetscReal *sing; 17a13144ffSStefano Zampini PetscBLASInt bM,bN,lwork,lierr,di = 1; 18a13144ffSStefano Zampini PetscInt ulw,i,nr,nc,n; 19a13144ffSStefano Zampini PetscErrorCode ierr; 20a13144ffSStefano Zampini 21a13144ffSStefano Zampini PetscFunctionBegin; 22a13144ffSStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 23a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"LAPACK _GESVD not available"); 24a13144ffSStefano Zampini #endif 25a13144ffSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 26a13144ffSStefano Zampini if (!nr || !nc) PetscFunctionReturn(0); 27a13144ffSStefano Zampini 28a13144ffSStefano Zampini /* workspace */ 29a13144ffSStefano Zampini if (!work) { 30a13144ffSStefano Zampini ulw = PetscMax(PetscMax(1,5*PetscMin(nr,nc)),3*PetscMin(nr,nc)+PetscMax(nr,nc)); 31f913dca9SStefano Zampini ierr = PetscMalloc1(ulw,&uwork);CHKERRQ(ierr); 32a13144ffSStefano Zampini } else { 33a13144ffSStefano Zampini ulw = lw; 34a13144ffSStefano Zampini uwork = work; 35a13144ffSStefano Zampini } 36a13144ffSStefano Zampini n = PetscMin(nr,nc); 37a13144ffSStefano Zampini if (!rwork) { 38a13144ffSStefano Zampini ierr = PetscMalloc1(n,&sing);CHKERRQ(ierr); 39a13144ffSStefano Zampini } else { 40a13144ffSStefano Zampini sing = rwork; 41a13144ffSStefano Zampini } 42a13144ffSStefano Zampini 43a13144ffSStefano Zampini /* SVD */ 44a13144ffSStefano Zampini ierr = PetscMalloc1(nr*nr,&U);CHKERRQ(ierr); 45a13144ffSStefano Zampini ierr = PetscBLASIntCast(nr,&bM);CHKERRQ(ierr); 46a13144ffSStefano Zampini ierr = PetscBLASIntCast(nc,&bN);CHKERRQ(ierr); 47a13144ffSStefano Zampini ierr = PetscBLASIntCast(ulw,&lwork);CHKERRQ(ierr); 48a13144ffSStefano Zampini ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); 49a13144ffSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 50a13144ffSStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,&lierr)); 51a13144ffSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 52a13144ffSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 53a13144ffSStefano Zampini ierr = MatDenseRestoreArray(A,&data);CHKERRQ(ierr); 54a13144ffSStefano Zampini for (i=0;i<n;i++) if (sing[i] < PETSC_SMALL) break; 55a13144ffSStefano Zampini if (!rwork) { 56a13144ffSStefano Zampini ierr = PetscFree(sing);CHKERRQ(ierr); 57a13144ffSStefano Zampini } 58a13144ffSStefano Zampini if (!work) { 59a13144ffSStefano Zampini ierr = PetscFree(uwork);CHKERRQ(ierr); 60a13144ffSStefano Zampini } 61a13144ffSStefano Zampini /* create B */ 62a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 63a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 64a13144ffSStefano Zampini ierr = PetscMemcpy(data,U+nr*i,(nr-i)*nr*sizeof(PetscScalar));CHKERRQ(ierr); 65a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 66a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 67a13144ffSStefano Zampini #else 68a13144ffSStefano Zampini PetscFunctionBegin; 69a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for complexes"); 70a13144ffSStefano Zampini #endif 71a13144ffSStefano Zampini PetscFunctionReturn(0); 72a13144ffSStefano Zampini } 73a13144ffSStefano Zampini 74*1e0482f5SStefano Zampini /* TODO REMOVE */ 75*1e0482f5SStefano Zampini #if defined(PRINT_GDET) 76*1e0482f5SStefano Zampini static int inc = 0; 77*1e0482f5SStefano Zampini static int lev = 0; 78*1e0482f5SStefano Zampini #endif 79*1e0482f5SStefano Zampini 80a13144ffSStefano Zampini #undef __FUNCT__ 81a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCComputeNedelecChangeEdge" 82*1e0482f5SStefano Zampini PetscErrorCode PCBDDCComputeNedelecChangeEdge(Mat lG, IS edge, IS extrow, IS extcol, IS corners, Mat* Gins, Mat* GKins, PetscScalar cvals[2], PetscScalar *work, PetscReal *rwork) 83a13144ffSStefano Zampini { 84a13144ffSStefano Zampini PetscErrorCode ierr; 85a13144ffSStefano Zampini Mat GE,GEd; 86a13144ffSStefano Zampini PetscInt rsize,csize,esize; 87a13144ffSStefano Zampini PetscScalar *ptr; 88a13144ffSStefano Zampini 89a13144ffSStefano Zampini PetscFunctionBegin; 90a13144ffSStefano Zampini ierr = ISGetSize(edge,&esize);CHKERRQ(ierr); 91c3c0e390SStefano Zampini if (!esize) PetscFunctionReturn(0); 92a13144ffSStefano Zampini ierr = ISGetSize(extrow,&rsize);CHKERRQ(ierr); 93a13144ffSStefano Zampini ierr = ISGetSize(extcol,&csize);CHKERRQ(ierr); 94a13144ffSStefano Zampini 95a13144ffSStefano Zampini /* gradients */ 96a13144ffSStefano Zampini ptr = work + 5*esize; 97a13144ffSStefano Zampini ierr = MatGetSubMatrix(lG,extrow,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 98a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,rsize,csize,ptr,Gins);CHKERRQ(ierr); 99a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,Gins);CHKERRQ(ierr); 100a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 101a13144ffSStefano Zampini 102a13144ffSStefano Zampini /* constants */ 103a13144ffSStefano Zampini ptr += rsize*csize; 104a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,esize,csize,ptr,&GEd);CHKERRQ(ierr); 105a13144ffSStefano Zampini ierr = MatGetSubMatrix(lG,edge,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 106a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,&GEd);CHKERRQ(ierr); 107a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 108a13144ffSStefano Zampini ierr = MatDense_OrthogonalComplement(GEd,5*esize,work,rwork,GKins);CHKERRQ(ierr); 109a13144ffSStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 110*1e0482f5SStefano Zampini 111*1e0482f5SStefano Zampini if (corners) { 112*1e0482f5SStefano Zampini Mat GEc; 113*1e0482f5SStefano Zampini PetscScalar *vals,v; 114*1e0482f5SStefano Zampini 115*1e0482f5SStefano Zampini ierr = MatGetSubMatrix(lG,edge,corners,MAT_INITIAL_MATRIX,&GEc);CHKERRQ(ierr); 116*1e0482f5SStefano Zampini ierr = MatTransposeMatMult(GEc,*GKins,MAT_INITIAL_MATRIX,1.0,&GEd);CHKERRQ(ierr); 117*1e0482f5SStefano Zampini ierr = MatDenseGetArray(GEd,&vals);CHKERRQ(ierr); 118*1e0482f5SStefano Zampini /* TODO fix me */ 119*1e0482f5SStefano Zampini v = PetscAbsScalar(vals[0]); 120*1e0482f5SStefano Zampini v = 1.; 121*1e0482f5SStefano Zampini cvals[0] = vals[0]/v; 122*1e0482f5SStefano Zampini cvals[1] = vals[1]/v; 123*1e0482f5SStefano Zampini ierr = MatDenseRestoreArray(GEd,&vals);CHKERRQ(ierr); 124*1e0482f5SStefano Zampini ierr = MatScale(*GKins,1./v);CHKERRQ(ierr); 125*1e0482f5SStefano Zampini #if defined(PRINT_GDET) 126*1e0482f5SStefano Zampini { 127*1e0482f5SStefano Zampini PetscViewer viewer; 128*1e0482f5SStefano Zampini char filename[256]; 129*1e0482f5SStefano Zampini sprintf(filename,"Gdet_l%d_r%d_cc%d.m",lev,PetscGlobalRank,inc++); 130*1e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 131*1e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 132*1e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEc,"GEc");CHKERRQ(ierr); 133*1e0482f5SStefano Zampini ierr = MatView(GEc,viewer);CHKERRQ(ierr); 134*1e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)(*GKins),"GK");CHKERRQ(ierr); 135*1e0482f5SStefano Zampini ierr = MatView(*GKins,viewer);CHKERRQ(ierr); 136*1e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEd,"Gproj");CHKERRQ(ierr); 137*1e0482f5SStefano Zampini ierr = MatView(GEd,viewer);CHKERRQ(ierr); 138*1e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 139*1e0482f5SStefano Zampini } 140*1e0482f5SStefano Zampini #endif 141*1e0482f5SStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 142*1e0482f5SStefano Zampini ierr = MatDestroy(&GEc);CHKERRQ(ierr); 143*1e0482f5SStefano Zampini } 144*1e0482f5SStefano Zampini 145a13144ffSStefano Zampini PetscFunctionReturn(0); 146a13144ffSStefano Zampini } 147a13144ffSStefano Zampini 148a13144ffSStefano Zampini #undef __FUNCT__ 149a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCNedelecSupport" 150a13144ffSStefano Zampini PetscErrorCode PCBDDCNedelecSupport(PC pc) 151a13144ffSStefano Zampini { 152a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 153a13144ffSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1540569b399SStefano Zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe,lGinit; 155a13144ffSStefano Zampini MatNullSpace nnsp; 156a13144ffSStefano Zampini Vec tvec,*quads; 157a13144ffSStefano Zampini PetscSF sfv; 158*1e0482f5SStefano Zampini ISLocalToGlobalMapping el2g,vl2g,fl2g,al2g; 159a13144ffSStefano Zampini MPI_Comm comm; 160c2151214SStefano Zampini IS lned,primals,allprimals,nedfieldlocal; 161c2151214SStefano Zampini IS *eedges,*extrows,*extcols,*alleedges; 162b03ebc13SStefano Zampini PetscBT btv,bte,btvc,btb,btvcand,btvi,btee,bter; 163a13144ffSStefano Zampini PetscScalar *vals,*work; 164a13144ffSStefano Zampini PetscReal *rwork; 165a13144ffSStefano Zampini const PetscInt *idxs,*ii,*jj,*iit,*jjt; 166*1e0482f5SStefano Zampini PetscInt ne,nv,Lv,order,n,field; 167a13144ffSStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 168b03ebc13SStefano Zampini PetscInt i,j,extmem,cum,maxsize,nee,nquads=2; 169b03ebc13SStefano Zampini PetscInt *extrow,*extrowcum,*marks,*vmarks,*gidxs; 170a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 171b03ebc13SStefano Zampini PetscInt *corners,*cedges; 172b03ebc13SStefano Zampini #if defined(PETSC_USE_DEBUG) 173b03ebc13SStefano Zampini PetscInt *emarks; 174b03ebc13SStefano Zampini #endif 175*1e0482f5SStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,global; 176a13144ffSStefano Zampini PetscErrorCode ierr; 177a13144ffSStefano Zampini 178a13144ffSStefano Zampini PetscFunctionBegin; 179a13144ffSStefano Zampini /* test variable order code and print debug info TODO: to be removed */ 180a13144ffSStefano Zampini print = PETSC_FALSE; 181a13144ffSStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_print_nedelec",&print,NULL);CHKERRQ(ierr); 182a13144ffSStefano Zampini ierr = PetscOptionsGetInt(NULL,NULL,"-pc_bddc_nedelec_order",&pcbddc->nedorder,NULL);CHKERRQ(ierr); 183a13144ffSStefano Zampini 184a13144ffSStefano Zampini /* Return to caller if there are no edges in the decomposition */ 185a13144ffSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 186*1e0482f5SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&al2g,NULL);CHKERRQ(ierr); 187*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(al2g,&n);CHKERRQ(ierr); 188a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 189a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 190c2151214SStefano Zampini for (i=0;i<n;i++) { 191a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 192a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 193a13144ffSStefano Zampini break; 194a13144ffSStefano Zampini } 195a13144ffSStefano Zampini } 196a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 197a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 198a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 199a13144ffSStefano Zampini 200*1e0482f5SStefano Zampini /* If the discrete gradient is defined for a subset of dofs and global is true, 201*1e0482f5SStefano Zampini it assumes G is given in global ordering for all the dofs. 202*1e0482f5SStefano Zampini Otherwise, the ordering is global for the Nedelec field */ 203a13144ffSStefano Zampini order = pcbddc->nedorder; 204a13144ffSStefano Zampini conforming = pcbddc->conforming; 205c2151214SStefano Zampini field = pcbddc->nedfield; 206*1e0482f5SStefano Zampini global = pcbddc->nedglobal; 207c2151214SStefano 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); 208c2151214SStefano Zampini if (pcbddc->n_ISForDofsLocal && field > -1) { 209*1e0482f5SStefano Zampini PetscBool setprimal = PETSC_FALSE; 210*1e0482f5SStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_nedelec_field_primal",&setprimal,NULL);CHKERRQ(ierr); 211c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 212c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 213c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 214*1e0482f5SStefano Zampini if (setprimal) { 215*1e0482f5SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,nedfieldlocal);CHKERRQ(ierr); 216*1e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 217*1e0482f5SStefano Zampini PetscFunctionReturn(0); 218*1e0482f5SStefano Zampini } 219*1e0482f5SStefano Zampini } else if (!pcbddc->n_ISForDofsLocal) { 220c2151214SStefano Zampini PetscBool testnedfield = PETSC_FALSE; 221c2151214SStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_nedelec_field",&testnedfield,NULL);CHKERRQ(ierr); 222c2151214SStefano Zampini if (!testnedfield) { 223c2151214SStefano Zampini ne = n; 224c2151214SStefano Zampini nedfieldlocal = NULL; 225c2151214SStefano Zampini } else { 226c2151214SStefano Zampini /* ierr = ISCreateStride(comm,n,0,1,&nedfieldlocal);CHKERRQ(ierr); */ 227c2151214SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 228c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 229c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 230c2151214SStefano Zampini for (i=0;i<n;i++) matis->sf_leafdata[i] = 1; 231c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 232c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 233c2151214SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 234c2151214SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 235c2151214SStefano Zampini for (i=0,cum=0;i<n;i++) { 236c2151214SStefano Zampini if (matis->sf_leafdata[i] > 1) { 237c2151214SStefano Zampini matis->sf_leafdata[cum++] = i; 238c2151214SStefano Zampini } 239c2151214SStefano Zampini } 240c2151214SStefano Zampini ierr = ISCreateGeneral(comm,cum,matis->sf_leafdata,PETSC_COPY_VALUES,&nedfieldlocal);CHKERRQ(ierr); 241c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 242c2151214SStefano Zampini } 243*1e0482f5SStefano Zampini global = PETSC_TRUE; 244*1e0482f5SStefano Zampini } else { 245*1e0482f5SStefano Zampini SETERRQ(comm,PETSC_ERR_USER,"When multiple fields are present, the Nedelec field has to be specified"); 246c2151214SStefano Zampini } 247a13144ffSStefano Zampini 248c2151214SStefano Zampini if (nedfieldlocal) { /* merge with previous code when testing is done */ 249c2151214SStefano Zampini IS is; 250c2151214SStefano Zampini 251c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 252c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 253*1e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering for the whole dofs*/ 254*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(al2g,nedfieldlocal,&is);CHKERRQ(ierr); 255*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&al2g);CHKERRQ(ierr); 256*1e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering (for Nedelec only) */ 257*1e0482f5SStefano Zampini if (global) { 258*1e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 259*1e0482f5SStefano Zampini el2g = al2g; 260*1e0482f5SStefano Zampini } else { 261*1e0482f5SStefano Zampini IS gis; 262*1e0482f5SStefano Zampini 263*1e0482f5SStefano Zampini ierr = ISRenumber(is,NULL,NULL,&gis);CHKERRQ(ierr); 264*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gis,&el2g);CHKERRQ(ierr); 265*1e0482f5SStefano Zampini ierr = ISDestroy(&gis);CHKERRQ(ierr); 266*1e0482f5SStefano Zampini } 267c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 268c2151214SStefano Zampini } else { 269*1e0482f5SStefano Zampini /* restore default */ 270*1e0482f5SStefano Zampini pcbddc->nedfield = -1; 271*1e0482f5SStefano Zampini /* one ref for the destruction of al2g, one for el2g */ 272*1e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 273*1e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 274*1e0482f5SStefano Zampini el2g = al2g; 275c2151214SStefano Zampini fl2g = NULL; 276c2151214SStefano Zampini } 277a13144ffSStefano Zampini 278a13144ffSStefano Zampini /* Sanity checks */ 279a13144ffSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 280a13144ffSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 281a13144ffSStefano 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); 282a13144ffSStefano Zampini 283*1e0482f5SStefano Zampini /* Drop connections for interior edges */ 284*1e0482f5SStefano Zampini ierr = MatDuplicate(pcbddc->discretegradient,MAT_COPY_VALUES,&G);CHKERRQ(ierr); 285*1e0482f5SStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 286c2151214SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 287c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 288c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 289c2151214SStefano Zampini if (nedfieldlocal) { 290c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 291c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 292c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 293c2151214SStefano Zampini } else { 294c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 295c2151214SStefano Zampini } 296c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 297c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 298*1e0482f5SStefano Zampini if (global) { 299*1e0482f5SStefano Zampini PetscInt rst; 300*1e0482f5SStefano Zampini 301c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 302c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 303c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 304c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 305c2151214SStefano Zampini } 306c2151214SStefano Zampini } 307a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 308c2151214SStefano Zampini ierr = MatZeroRows(G,cum,matis->sf_rootdata,0.,NULL,NULL);CHKERRQ(ierr); 309*1e0482f5SStefano Zampini } else { 310*1e0482f5SStefano Zampini PetscInt *tbz; 311*1e0482f5SStefano Zampini 312*1e0482f5SStefano Zampini ierr = PetscMalloc1(ne,&tbz);CHKERRQ(ierr); 313*1e0482f5SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 314*1e0482f5SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 315*1e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 316*1e0482f5SStefano Zampini for (i=0,cum=0;i<ne;i++) 317*1e0482f5SStefano Zampini if (matis->sf_leafdata[idxs[i]] == 1) 318*1e0482f5SStefano Zampini tbz[cum++] = i; 319*1e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 320*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApply(el2g,cum,tbz,tbz);CHKERRQ(ierr); 321*1e0482f5SStefano Zampini ierr = MatZeroRows(G,cum,tbz,0.,NULL,NULL);CHKERRQ(ierr); 322*1e0482f5SStefano Zampini ierr = PetscFree(tbz);CHKERRQ(ierr); 323*1e0482f5SStefano Zampini } 324a13144ffSStefano Zampini 325a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 326a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 327a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 328a13144ffSStefano Zampini ierr = MatGetSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 329a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 330a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 331a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 332a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 333a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 334a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 335a13144ffSStefano Zampini if (print) { 336a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 337a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 338a13144ffSStefano Zampini } 339a13144ffSStefano Zampini 340a13144ffSStefano Zampini /* SF for nodal communications */ 341c2151214SStefano Zampini ierr = MatGetLocalSize(G,NULL,&Lv);CHKERRQ(ierr); 342a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 343a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 344a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 345a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 346a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 347a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 348a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 349a13144ffSStefano Zampini ierr = PetscMalloc2(nv,&sfvleaves,Lv,&sfvroots);CHKERRQ(ierr); 350a13144ffSStefano Zampini 351*1e0482f5SStefano Zampini /* Destroy temporary G created in MATIS format and modified G */ 352*1e0482f5SStefano Zampini ierr = MatDestroy(&G);CHKERRQ(ierr); 353a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 354a13144ffSStefano Zampini 3550569b399SStefano Zampini /* Save lG */ 3560569b399SStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGinit);CHKERRQ(ierr); 3570569b399SStefano Zampini 358a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 3594e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 3604e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 361a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 362a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 363a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 364c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 365a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 366a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 367a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 368c2151214SStefano Zampini IS is; 369c2151214SStefano Zampini 370c2151214SStefano Zampini if (fl2g) { 371c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 372c2151214SStefano Zampini } else { 373c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 374c2151214SStefano Zampini } 375c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 376c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 377a13144ffSStefano Zampini for (i=0;i<cum;i++) { 378a13144ffSStefano Zampini if (idxs[i] >= 0) { 379a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 380a13144ffSStefano Zampini } 381a13144ffSStefano Zampini } 382c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 383c2151214SStefano Zampini if (fl2g) { 384c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 385c2151214SStefano Zampini } 386a13144ffSStefano Zampini } 387a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 388c2151214SStefano Zampini IS is; 389c2151214SStefano Zampini 390c2151214SStefano Zampini if (fl2g) { 391c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 392c2151214SStefano Zampini } else { 393c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 394c2151214SStefano Zampini } 395c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 396c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 397a13144ffSStefano Zampini for (i=0;i<cum;i++) { 398a13144ffSStefano Zampini if (idxs[i] >= 0) { 399a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 400a13144ffSStefano Zampini } 401a13144ffSStefano Zampini } 402c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 403c2151214SStefano Zampini if (fl2g) { 404c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 405a13144ffSStefano Zampini } 406c2151214SStefano Zampini } 407c2151214SStefano Zampini 408a13144ffSStefano Zampini /* need to remove coarse faces' dofs to ensure the 409a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 410a13144ffSStefano Zampini ierr = PetscCalloc1(ne,&marks);CHKERRQ(ierr); 41162b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 412a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 41362b0c6f7SStefano Zampini for (i=1;i<n_neigh;i++) 41462b0c6f7SStefano Zampini for (j=0;j<n_shared[i];j++) 41562b0c6f7SStefano Zampini marks[shared[i][j]]++; 416a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 41762b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 41862b0c6f7SStefano Zampini if (marks[i] > 1 || (marks[i] == 1 && PetscBTLookup(btb,i))) { 41962b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 42062b0c6f7SStefano Zampini } 42162b0c6f7SStefano Zampini } 42262b0c6f7SStefano Zampini 42362b0c6f7SStefano Zampini if (!conforming) { 42462b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 42562b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 42662b0c6f7SStefano Zampini } 4274e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 428dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 42962b0c6f7SStefano Zampini cum = 0; 430a13144ffSStefano Zampini for (i=0;i<ne;i++) { 431dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 43262b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 433a13144ffSStefano Zampini marks[cum++] = i; 434dec27d64SStefano Zampini continue; 435dec27d64SStefano Zampini } 436dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 43762b0c6f7SStefano Zampini if (!conforming) { 43862b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 439a13144ffSStefano Zampini marks[cum++] = i; 440a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 441a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 442a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 443a13144ffSStefano Zampini } 44462b0c6f7SStefano Zampini } else { 44562b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 44662b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 44762b0c6f7SStefano Zampini - at most 2 endpoints 44862b0c6f7SStefano Zampini - order-1 interior nodal dofs 44962b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 45062b0c6f7SStefano Zampini */ 45162b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 45262b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 45362b0c6f7SStefano Zampini PetscInt v = jj[j],k; 45462b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 45562b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 45662b0c6f7SStefano Zampini if (nconn > order) ends++; 45762b0c6f7SStefano Zampini else if (nconn == order) ints++; 45862b0c6f7SStefano Zampini else undef++; 45962b0c6f7SStefano Zampini } 46062b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 46162b0c6f7SStefano Zampini marks[cum++] = i; 46262b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 46362b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 46462b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 46562b0c6f7SStefano Zampini } 46662b0c6f7SStefano Zampini } 46762b0c6f7SStefano Zampini } 468a13144ffSStefano Zampini } 469dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 470dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 471dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 472dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 473a13144ffSStefano Zampini } 474dec27d64SStefano Zampini } 47562b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 476dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 4774e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 47862b0c6f7SStefano Zampini if (!conforming) { 47962b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 48062b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 48162b0c6f7SStefano Zampini } 4824e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 483b03ebc13SStefano Zampini /* identify splitpoints and corner candidates */ 4844e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 485a13144ffSStefano Zampini if (print) { 4864e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 4874e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 4884e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 489a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 490a13144ffSStefano Zampini } 491a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 492dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 493a13144ffSStefano Zampini for (i=0;i<nv;i++) { 494dec27d64SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i]; 495b03ebc13SStefano Zampini if (!order) { /* variable order */ 496dec27d64SStefano Zampini PetscReal vorder = 0.; 497dec27d64SStefano Zampini 498dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 499dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 500dec27d64SStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%d)",vorder,test); 501dec27d64SStefano Zampini ord = 1; 502dec27d64SStefano Zampini } 503a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 504dec27d64SStefano 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); 505a13144ffSStefano Zampini #endif 506dec27d64SStefano Zampini if (test >= 3*ord) { /* splitpoints */ 507a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d\n",i); 508a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 509dec27d64SStefano Zampini } else if (test == ord) { 510b03ebc13SStefano Zampini if (order == 1 || (!order && ii[i+1]-ii[i] == 1)) { 511a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 512a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 513a13144ffSStefano Zampini } else { 514a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 515a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 516a13144ffSStefano Zampini } 517a13144ffSStefano Zampini } 518a13144ffSStefano Zampini } 519b03ebc13SStefano Zampini 520b03ebc13SStefano Zampini /* a candidate is valid if it is connected to another candidate via a non-primal edge dof */ 521b03ebc13SStefano Zampini if (order != 1) { 522b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSPECTING CANDIDATES\n"); 523b03ebc13SStefano Zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 524b03ebc13SStefano Zampini for (i=0;i<nv;i++) { 525b03ebc13SStefano Zampini if (PetscBTLookup(btvcand,i)) { 526b03ebc13SStefano Zampini PetscBool found = PETSC_FALSE; 527b03ebc13SStefano Zampini for (j=ii[i];j<ii[i+1] && !found;j++) { 528b03ebc13SStefano Zampini PetscInt k,e = jj[j]; 529b03ebc13SStefano Zampini if (PetscBTLookup(bte,e)) continue; 530b03ebc13SStefano Zampini for (k=iit[e];k<iit[e+1];k++) { 531b03ebc13SStefano Zampini PetscInt v = jjt[k]; 532b03ebc13SStefano Zampini if (v != i && PetscBTLookup(btvcand,v)) { 533b03ebc13SStefano Zampini found = PETSC_TRUE; 534b03ebc13SStefano Zampini break; 535b03ebc13SStefano Zampini } 536b03ebc13SStefano Zampini } 537b03ebc13SStefano Zampini } 538b03ebc13SStefano Zampini if (!found) { 539b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d CLEARED\n",i); 540b03ebc13SStefano Zampini ierr = PetscBTClear(btvcand,i);CHKERRQ(ierr); 541b03ebc13SStefano Zampini } else { 542b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d ACCEPTED\n",i); 543b03ebc13SStefano Zampini } 544b03ebc13SStefano Zampini } 545b03ebc13SStefano Zampini } 546b03ebc13SStefano Zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 547b03ebc13SStefano Zampini } 548dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 549a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 550b03ebc13SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 551a13144ffSStefano Zampini 552a13144ffSStefano Zampini /* Get the local G^T explicitly */ 5530569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 554a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 5554e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 556a13144ffSStefano Zampini 5574e64d54eSstefano_zampini /* Mark interior nodal dofs */ 558a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 5594e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 560a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 561a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 5624e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 563a13144ffSStefano Zampini } 564a13144ffSStefano Zampini } 565a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 566a13144ffSStefano Zampini 567a13144ffSStefano Zampini /* communicate corners and splitpoints */ 568a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 569a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 570a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 571a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 572a13144ffSStefano Zampini 573a13144ffSStefano Zampini if (print) { 574a13144ffSStefano Zampini IS tbz; 575a13144ffSStefano Zampini 576a13144ffSStefano Zampini cum = 0; 577a13144ffSStefano Zampini for (i=0;i<nv;i++) 578a13144ffSStefano Zampini if (sfvleaves[i]) 579a13144ffSStefano Zampini vmarks[cum++] = i; 580a13144ffSStefano Zampini 581a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 582a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 583a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 584a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 585a13144ffSStefano Zampini } 586a13144ffSStefano Zampini 587a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 588a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 589a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 590a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 591a13144ffSStefano Zampini 5924e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 5934e64d54eSstefano_zampini and interior nodal dofs */ 594a13144ffSStefano Zampini cum = 0; 595a13144ffSStefano Zampini for (i=0;i<nv;i++) { 596a13144ffSStefano Zampini if (sfvleaves[i]) { 597a13144ffSStefano Zampini vmarks[cum++] = i; 598a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 599a13144ffSStefano Zampini } 6004e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 601a13144ffSStefano Zampini } 6024e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 603a13144ffSStefano Zampini if (print) { 604a13144ffSStefano Zampini IS tbz; 605a13144ffSStefano Zampini 606a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 6074e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 608a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 609a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 610a13144ffSStefano Zampini } 611a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 612a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 613a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 614a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 615a13144ffSStefano Zampini 616a13144ffSStefano Zampini /* Recompute G */ 617a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 618a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 619a13144ffSStefano Zampini if (print) { 620a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 621a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 622a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 623a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 624a13144ffSStefano Zampini } 625a13144ffSStefano Zampini 626a13144ffSStefano Zampini /* Get primal dofs (if any) */ 627a13144ffSStefano Zampini cum = 0; 628a13144ffSStefano Zampini for (i=0;i<ne;i++) { 629a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 630a13144ffSStefano Zampini } 631c2151214SStefano Zampini if (fl2g) { 632c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 633c2151214SStefano Zampini } 634a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 635a13144ffSStefano Zampini if (print) { 636a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 637a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 638a13144ffSStefano Zampini } 639a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 640c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 641a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 642a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 643a13144ffSStefano Zampini 644a13144ffSStefano Zampini /* Compute edge connectivity */ 645a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 646a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 647a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 648c2151214SStefano Zampini if (fl2g) { 649c2151214SStefano Zampini PetscBT btf; 650c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 651c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 652c2151214SStefano Zampini 653c2151214SStefano Zampini /* create CSR for all local dofs */ 654c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 655c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 656c2151214SStefano 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); 657c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 658c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 659c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 660c2151214SStefano Zampini rest = PETSC_TRUE; 661c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 662c2151214SStefano Zampini } else { 663c2151214SStefano Zampini free = PETSC_TRUE; 664c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 665c2151214SStefano Zampini iiu[0] = 0; 666c2151214SStefano Zampini for (i=0;i<n;i++) { 667c2151214SStefano Zampini iiu[i+1] = i+1; 668c2151214SStefano Zampini jju[i] = -1; 669d904f53bSStefano Zampini } 670c2151214SStefano Zampini } 671c2151214SStefano Zampini 672c2151214SStefano Zampini /* import sizes of CSR */ 673c2151214SStefano Zampini iia[0] = 0; 674c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 675c2151214SStefano Zampini 676c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 677c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 678c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 679c2151214SStefano Zampini for (i=0;i<ne;i++) { 680c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 681c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 682c2151214SStefano Zampini } 683c2151214SStefano Zampini 684c2151214SStefano Zampini /* iia in CSR */ 685c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 686c2151214SStefano Zampini 687c2151214SStefano Zampini /* jja in CSR */ 688c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 689c2151214SStefano Zampini for (i=0;i<n;i++) 690c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 691c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 692c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 693c2151214SStefano Zampini 694c2151214SStefano Zampini /* map edge dofs connectivity */ 695*1e0482f5SStefano Zampini if (jj) { 696c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 697c2151214SStefano Zampini for (i=0;i<ne;i++) { 698c2151214SStefano Zampini PetscInt e = idxs[i]; 699c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 700c2151214SStefano Zampini } 701*1e0482f5SStefano Zampini } 702c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 703c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 704c2151214SStefano Zampini if (rest) { 705c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 706c2151214SStefano Zampini } 707c2151214SStefano Zampini if (free) { 708c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 709c2151214SStefano Zampini } 710c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 711c2151214SStefano Zampini } else { 712*1e0482f5SStefano Zampini if (jj) { 713c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 714c2151214SStefano Zampini } 715c2151214SStefano Zampini } 716c2151214SStefano Zampini 717a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 718a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 719a13144ffSStefano Zampini 720a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 721c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 722a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 723a13144ffSStefano Zampini 724c2151214SStefano Zampini if (fl2g) { 725c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 726c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 727c2151214SStefano Zampini for (i=0;i<nee;i++) { 728c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 729c2151214SStefano Zampini } 730c2151214SStefano Zampini } else { 731c2151214SStefano Zampini eedges = alleedges; 732c2151214SStefano Zampini primals = allprimals; 733c2151214SStefano Zampini } 734c2151214SStefano Zampini 735a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 736a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 737c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 738c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 739c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 740c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 741c2151214SStefano Zampini if (print) { 742c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 743c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 744c2151214SStefano Zampini } 745c2151214SStefano Zampini 746c2151214SStefano Zampini maxsize = 0; 747a13144ffSStefano Zampini for (i=0;i<nee;i++) { 748a13144ffSStefano Zampini PetscInt size,mark = i+1; 749a13144ffSStefano Zampini 750a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 751a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 752a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 753a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 754a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 755a13144ffSStefano Zampini } 756a13144ffSStefano Zampini 757a13144ffSStefano Zampini /* Find coarse edge endpoints */ 758a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 759a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 760a13144ffSStefano Zampini for (i=0;i<nee;i++) { 761a13144ffSStefano Zampini PetscInt mark = i+1,size; 762a13144ffSStefano Zampini 763a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 764*1e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 765*1e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 766a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 767a13144ffSStefano Zampini if (print) { 768a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 769a13144ffSStefano Zampini ISView(eedges[i],NULL); 770a13144ffSStefano Zampini } 771a13144ffSStefano Zampini for (j=0;j<size;j++) { 772a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 773a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 774a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 775a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 776a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 777a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 778a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 779a13144ffSStefano Zampini PetscInt k2; 780a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 781a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 782c2151214SStefano 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])); 783c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 784c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 785c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 786a13144ffSStefano Zampini corner = PETSC_TRUE; 787a13144ffSStefano Zampini break; 788a13144ffSStefano Zampini } 789a13144ffSStefano Zampini } 790a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 791a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 792a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 793a13144ffSStefano Zampini } else { 794a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 795a13144ffSStefano Zampini } 796a13144ffSStefano Zampini } 797a13144ffSStefano Zampini } 798a13144ffSStefano Zampini } 799a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 800a13144ffSStefano Zampini } 801a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 802a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 803c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 804a13144ffSStefano Zampini 805a13144ffSStefano Zampini /* Reset marked primal dofs */ 806a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 807a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 808a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 809a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 810a13144ffSStefano Zampini 8110569b399SStefano Zampini /* Now use the initial lG */ 8120569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 8130569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 8140569b399SStefano Zampini lG = lGinit; 8150569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 8160569b399SStefano Zampini 817a13144ffSStefano Zampini /* Compute extended cols indices */ 818b03ebc13SStefano Zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 819b03ebc13SStefano Zampini ierr = PetscBTCreate(nee,&bter);CHKERRQ(ierr); 820a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 821a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 822a13144ffSStefano Zampini i *= maxsize; 823b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 824a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 825a13144ffSStefano Zampini eerr = PETSC_FALSE; 826a13144ffSStefano Zampini for (i=0;i<nee;i++) { 827b03ebc13SStefano Zampini PetscInt size,found = 0; 828a13144ffSStefano Zampini 829a13144ffSStefano Zampini cum = 0; 830a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 831*1e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 832*1e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 833a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 834b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 835a13144ffSStefano Zampini for (j=0;j<size;j++) { 836a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 837b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 838b03ebc13SStefano Zampini PetscInt vv = jj[k]; 839b03ebc13SStefano Zampini if (!PetscBTLookup(btv,vv)) extrow[cum++] = vv; 840b03ebc13SStefano Zampini else if (!PetscBTLookupSet(btvc,vv)) found++; 841b03ebc13SStefano Zampini } 842a13144ffSStefano Zampini } 843a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 844a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 845a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 846a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 847a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 848a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 849a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 850b03ebc13SStefano Zampini if (cum != size -1 || found != 2) { 851b03ebc13SStefano Zampini ierr = PetscBTSet(bter,i);CHKERRQ(ierr); 852a13144ffSStefano Zampini if (print) { 853a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 854a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 855a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 856a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 857a13144ffSStefano Zampini } 858a13144ffSStefano Zampini eerr = PETSC_TRUE; 859a13144ffSStefano Zampini } 860a13144ffSStefano Zampini } 8614e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 862a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 863a13144ffSStefano Zampini if (done) { 864a13144ffSStefano Zampini PetscInt *newprimals; 865a13144ffSStefano Zampini 866a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 867a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 868a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 869a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 870a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 8710569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 872b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"DOING SECOND PASS (eerr %d)\n",eerr); 873a13144ffSStefano Zampini for (i=0;i<nee;i++) { 874b03ebc13SStefano Zampini PetscBool has_candidates = PETSC_FALSE; 875b03ebc13SStefano Zampini if (PetscBTLookup(bter,i)) { 876a13144ffSStefano Zampini PetscInt size,mark = i+1; 877a13144ffSStefano Zampini 878a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 879a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 880c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 881a13144ffSStefano Zampini for (j=0;j<size;j++) { 882a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 883b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"Inspecting edge dof %d [%d %d)\n",ee,ii[ee],ii[ee+1]); 884a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 885a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 886a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 887a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 888b03ebc13SStefano Zampini has_candidates = PETSC_TRUE; 889b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Candidate set to vertex %d\n",vv); 890a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 891a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 892a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 893a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 894a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 895b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected edge dof set to primal %d\n",ee2); 896a13144ffSStefano Zampini newprimals[cum++] = ee2; 897a13144ffSStefano Zampini /* finally set the new corners */ 898a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 899b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected nodal dof set to vertex %d\n",jj[k3]); 900a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 901a13144ffSStefano Zampini } 902a13144ffSStefano Zampini } 903a13144ffSStefano Zampini } 904b03ebc13SStefano Zampini } else { 905b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Not a candidate vertex %d\n",jj[k]); 906a13144ffSStefano Zampini } 907a13144ffSStefano Zampini } 908a13144ffSStefano Zampini } 909b03ebc13SStefano Zampini if (!has_candidates) { /* circular edge */ 910b03ebc13SStefano Zampini PetscInt k, ee = idxs[0],*tmarks; 911b03ebc13SStefano Zampini 912b03ebc13SStefano Zampini ierr = PetscCalloc1(ne,&tmarks);CHKERRQ(ierr); 913b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Circular edge %d\n",i); 914b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 915b03ebc13SStefano Zampini PetscInt k2; 916b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Set to corner %d\n",jj[k]); 917b03ebc13SStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 918b03ebc13SStefano Zampini for (k2=iit[jj[k]];k2<iit[jj[k]+1];k2++) tmarks[jjt[k2]]++; 919b03ebc13SStefano Zampini } 920b03ebc13SStefano Zampini for (j=0;j<size;j++) { 921b03ebc13SStefano Zampini if (tmarks[idxs[j]] > 1) { 922b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Edge dof set to primal %d\n",idxs[j]); 923b03ebc13SStefano Zampini newprimals[cum++] = idxs[j]; 924b03ebc13SStefano Zampini } 925b03ebc13SStefano Zampini } 926b03ebc13SStefano Zampini ierr = PetscFree(tmarks);CHKERRQ(ierr); 927b03ebc13SStefano Zampini } 928a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 929a13144ffSStefano Zampini } 930a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 931a13144ffSStefano Zampini } 932b03ebc13SStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 9330569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 934a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 935c2151214SStefano Zampini if (fl2g) { 936c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 937c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 938c2151214SStefano Zampini for (i=0;i<nee;i++) { 939c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 940c2151214SStefano Zampini } 941c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 942c2151214SStefano Zampini } 943c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 944a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 945a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 946a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 947a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 948a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 949c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 950c2151214SStefano Zampini if (fl2g) { 951c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 952c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 953c2151214SStefano Zampini for (i=0;i<nee;i++) { 954c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 955c2151214SStefano Zampini } 956c2151214SStefano Zampini } else { 957c2151214SStefano Zampini eedges = alleedges; 958c2151214SStefano Zampini primals = allprimals; 959c2151214SStefano Zampini } 960b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 961a13144ffSStefano Zampini 962a13144ffSStefano Zampini /* Mark again */ 963a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 964a13144ffSStefano Zampini for (i=0;i<nee;i++) { 965a13144ffSStefano Zampini PetscInt size,mark = i+1; 966a13144ffSStefano Zampini 967a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 968a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 969a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 970a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 971a13144ffSStefano Zampini } 972a13144ffSStefano Zampini if (print) { 973a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 974a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 975a13144ffSStefano Zampini } 976a13144ffSStefano Zampini 977a13144ffSStefano Zampini /* Recompute extended cols */ 978a13144ffSStefano Zampini eerr = PETSC_FALSE; 979a13144ffSStefano Zampini for (i=0;i<nee;i++) { 980a13144ffSStefano Zampini PetscInt size; 981a13144ffSStefano Zampini 982a13144ffSStefano Zampini cum = 0; 983a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 984*1e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 985*1e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 986a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 987a13144ffSStefano Zampini for (j=0;j<size;j++) { 988a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 989*1e0482f5SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 990a13144ffSStefano Zampini } 991a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 992a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 993a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 994a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 995a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 996a13144ffSStefano Zampini if (cum != size -1) { 997a13144ffSStefano Zampini if (print) { 998a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 999a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 1000a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 1001a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 1002a13144ffSStefano Zampini } 1003a13144ffSStefano Zampini eerr = PETSC_TRUE; 1004a13144ffSStefano Zampini } 1005a13144ffSStefano Zampini } 1006a13144ffSStefano Zampini } 1007a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1008a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 1009b03ebc13SStefano Zampini ierr = PetscBTDestroy(&bter);CHKERRQ(ierr); 1010a13144ffSStefano Zampini /* an error should not occur at this point */ 1011a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 1012b03ebc13SStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 1013a13144ffSStefano Zampini 10144e64d54eSstefano_zampini /* Check the number of endpoints */ 10150569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1016b03ebc13SStefano Zampini ierr = PetscMalloc1(2*nee,&corners);CHKERRQ(ierr); 1017b03ebc13SStefano Zampini ierr = PetscMalloc1(nee,&cedges);CHKERRQ(ierr); 10184e64d54eSstefano_zampini for (i=0;i<nee;i++) { 1019b03ebc13SStefano Zampini PetscInt size, found = 0, gc[2]; 10204e64d54eSstefano_zampini 1021b03ebc13SStefano Zampini /* init with defaults */ 1022b03ebc13SStefano Zampini cedges[i] = corners[i*2] = corners[i*2+1] = -1; 10234e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1024*1e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 1025*1e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 10264e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1027b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 10284e64d54eSstefano_zampini for (j=0;j<size;j++) { 10294e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 10304e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 10314e64d54eSstefano_zampini PetscInt vv = jj[k]; 10324e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 1033b03ebc13SStefano Zampini if (found == 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found more then two corners for edge %d\n",i); 1034b03ebc13SStefano Zampini corners[i*2+found++] = vv; 10354e64d54eSstefano_zampini } 10364e64d54eSstefano_zampini } 10374e64d54eSstefano_zampini } 1038b03ebc13SStefano Zampini if (found != 2) { 1039b03ebc13SStefano Zampini PetscInt e; 1040b03ebc13SStefano Zampini if (fl2g) { 1041b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,1,idxs,&e);CHKERRQ(ierr); 1042b03ebc13SStefano Zampini } else { 1043b03ebc13SStefano Zampini e = idxs[0]; 1044b03ebc13SStefano Zampini } 1045b03ebc13SStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %d corners for edge %d (astart %d, estart %d)\n",found,i,e,idxs[0]); 1046b03ebc13SStefano Zampini } 1047b03ebc13SStefano Zampini /* WARNING : this depends on how pcbddc->primal_indices_local_idxs is filled up in PCBDDConstraintsSetUp */ 1048b03ebc13SStefano Zampini cedges[i] = idxs[0]; 1049b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,2,corners+2*i,gc);CHKERRQ(ierr); 1050b03ebc13SStefano Zampini if (gc[0] > gc[1]) { 1051b03ebc13SStefano Zampini PetscInt swap = corners[2*i]; 1052b03ebc13SStefano Zampini corners[2*i] = corners[2*i+1]; 1053b03ebc13SStefano Zampini corners[2*i+1] = swap; 1054b03ebc13SStefano Zampini } 10554e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1056b03ebc13SStefano 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]); 10574e64d54eSstefano_zampini } 10580569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 10594e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 10604e64d54eSstefano_zampini 1061a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 1062a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 1063a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 1064a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 1065a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1066a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1067a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 1068a13144ffSStefano Zampini 1069a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1070a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 1071a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 1072a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 1073a13144ffSStefano Zampini if (emax < emarks[j]) { 1074a13144ffSStefano Zampini emax = emarks[j]; 1075a13144ffSStefano Zampini eemax = j; 1076a13144ffSStefano Zampini } 1077a13144ffSStefano Zampini } 1078a13144ffSStefano Zampini /* not relevant for edges */ 1079a13144ffSStefano Zampini if (!eemax) continue; 1080a13144ffSStefano Zampini 1081a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 1082a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 1083c2151214SStefano 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]); 1084a13144ffSStefano Zampini } 1085a13144ffSStefano Zampini } 1086a13144ffSStefano Zampini } 1087a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 1088a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1089a13144ffSStefano Zampini #endif 1090a13144ffSStefano Zampini 1091a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 1092a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1093a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 1094a13144ffSStefano Zampini extmem *= maxsize; 1095a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 1096a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 1097a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 1098a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1099a13144ffSStefano Zampini PetscInt mark = 0,size,start; 1100a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1101a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 1102a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 1103a13144ffSStefano Zampini mark = marks[jj[j]]; 1104a13144ffSStefano Zampini 1105a13144ffSStefano Zampini /* not relevant */ 1106a13144ffSStefano Zampini if (!mark) continue; 1107a13144ffSStefano Zampini 1108a13144ffSStefano Zampini /* import extended row */ 1109a13144ffSStefano Zampini mark--; 1110a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 1111a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 1112a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 1113a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 1114a13144ffSStefano Zampini extrowcum[mark] += size; 1115a13144ffSStefano Zampini } 1116a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1117a13144ffSStefano Zampini cum = 0; 1118a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1119a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 1120a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 1121a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 1122a13144ffSStefano Zampini cum = PetscMax(cum,size); 1123a13144ffSStefano Zampini } 1124a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 1125a13144ffSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 1126a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 1127a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 1128a13144ffSStefano Zampini 1129a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 1130a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 1131a13144ffSStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1132a13144ffSStefano Zampini for (i=0;i<maxsize;i++) vals[i] = 1.; 1133a13144ffSStefano Zampini 1134a13144ffSStefano Zampini /* Create vectors for quadrature rules */ 1135c2151214SStefano Zampini /* TODO preserve other quadratures */ 1136a13144ffSStefano Zampini ierr = PetscMalloc1(nquads,&quads);CHKERRQ(ierr); 1137a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 1138a13144ffSStefano Zampini ierr = MatCreateVecs(pc->pmat,&quads[i],NULL);CHKERRQ(ierr); 1139*1e0482f5SStefano Zampini ierr = VecSetLocalToGlobalMapping(quads[i],al2g);CHKERRQ(ierr); 1140a13144ffSStefano Zampini } 1141a13144ffSStefano Zampini ierr = PCBDDCNullSpaceCreate(comm,PETSC_FALSE,nquads,quads,&nnsp);CHKERRQ(ierr); 1142a13144ffSStefano Zampini 1143a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 1144a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1145c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 1146c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 1147a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 1148a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 1149a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 1150*1e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(T,al2g,al2g);CHKERRQ(ierr); 1151a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 1152a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1153a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 1154a13144ffSStefano Zampini 1155a13144ffSStefano Zampini /* Defaults to identity */ 1156c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 1157a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 1158a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 1159a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 1160a13144ffSStefano Zampini 1161*1e0482f5SStefano Zampini /* Create discrete gradient for the coarser level if needed */ 1162*1e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 1163*1e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 1164*1e0482f5SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 1165*1e0482f5SStefano Zampini ISLocalToGlobalMapping cel2g,cvl2g; 1166*1e0482f5SStefano Zampini IS wis,gwis; 1167*1e0482f5SStefano Zampini PetscInt cnv,cne; 1168*1e0482f5SStefano Zampini 1169*1e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,nee,cedges,PETSC_COPY_VALUES,&wis);CHKERRQ(ierr); 1170*1e0482f5SStefano Zampini if (fl2g) { 1171*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(fl2g,wis,&pcbddc->nedclocal);CHKERRQ(ierr); 1172*1e0482f5SStefano Zampini } else { 1173*1e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)wis);CHKERRQ(ierr); 1174*1e0482f5SStefano Zampini pcbddc->nedclocal = wis; 1175*1e0482f5SStefano Zampini } 1176*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,wis,&gwis);CHKERRQ(ierr); 1177*1e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 1178*1e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cne,&wis);CHKERRQ(ierr); 1179*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cel2g);CHKERRQ(ierr); 1180*1e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 1181*1e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 1182*1e0482f5SStefano Zampini 1183*1e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,2*nee,corners,PETSC_USE_POINTER,&wis);CHKERRQ(ierr); 1184*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(vl2g,wis,&gwis);CHKERRQ(ierr); 1185*1e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 1186*1e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cnv,&wis);CHKERRQ(ierr); 1187*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cvl2g);CHKERRQ(ierr); 1188*1e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 1189*1e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 1190*1e0482f5SStefano Zampini 1191*1e0482f5SStefano Zampini ierr = MatCreate(comm,&pcbddc->nedcG);CHKERRQ(ierr); 1192*1e0482f5SStefano Zampini ierr = MatSetSizes(pcbddc->nedcG,PETSC_DECIDE,PETSC_DECIDE,cne,cnv);CHKERRQ(ierr); 1193*1e0482f5SStefano Zampini ierr = MatSetType(pcbddc->nedcG,MATAIJ);CHKERRQ(ierr); 1194*1e0482f5SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->nedcG,2,NULL);CHKERRQ(ierr); 1195*1e0482f5SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->nedcG,2,NULL,2,NULL);CHKERRQ(ierr); 1196*1e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->nedcG,cel2g,cvl2g);CHKERRQ(ierr); 1197*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cel2g);CHKERRQ(ierr); 1198*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cvl2g);CHKERRQ(ierr); 1199*1e0482f5SStefano Zampini } 1200*1e0482f5SStefano Zampini 1201*1e0482f5SStefano Zampini #if defined(PRINT_GDET) 1202*1e0482f5SStefano Zampini inc = 0; 1203*1e0482f5SStefano Zampini lev = pcbddc->current_level; 1204*1e0482f5SStefano Zampini #endif 1205a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1206a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 1207*1e0482f5SStefano Zampini IS cornersis = NULL; 1208*1e0482f5SStefano Zampini PetscScalar cvals[2]; 1209a13144ffSStefano Zampini 1210*1e0482f5SStefano Zampini if (pcbddc->nedcG) { 1211*1e0482f5SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners+2*i,PETSC_USE_POINTER,&cornersis);CHKERRQ(ierr); 1212*1e0482f5SStefano Zampini } 1213*1e0482f5SStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],cornersis,&Gins,&GKins,cvals,work,rwork);CHKERRQ(ierr); 1214a13144ffSStefano Zampini if (Gins && GKins) { 1215a13144ffSStefano Zampini PetscScalar *data; 1216a13144ffSStefano Zampini const PetscInt *rows,*cols; 1217a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 1218a13144ffSStefano Zampini 1219a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 1220a13144ffSStefano Zampini /* H1 */ 1221a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 1222a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 1223a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 1224a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 1225a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 1226a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 1227a13144ffSStefano Zampini /* complement */ 1228a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 1229*1e0482f5SStefano Zampini if (!ncc) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Constant function has not been generated for coarse edge %d",i); 1230a13144ffSStefano Zampini if (ncc > nquads-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet supported ncc %d nquads %d",ncc,nquads); 1231a13144ffSStefano Zampini if (ncc + nch != nrc) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"The sum of the number of columns of GKins %d and Gins %d does not match %d",ncc,nch,nrc); 1232*1e0482f5SStefano Zampini if (ncc != 1 && pcbddc->nedcG) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot generate the dicrete gradient for the next level with ncc %d",ncc); 1233a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 1234a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 1235a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 1236a13144ffSStefano Zampini /* Gins kernel quadratures */ 1237a13144ffSStefano Zampini for (j=0;j<ncc;j++) { 1238a13144ffSStefano Zampini ierr = VecSetValueLocal(quads[j],cols[nch+j],1.,INSERT_VALUES);CHKERRQ(ierr); 1239a13144ffSStefano Zampini } 1240a13144ffSStefano Zampini /* H1 average */ 1241a13144ffSStefano Zampini ierr = VecSetValuesLocal(quads[nquads-1],nch,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 1242*1e0482f5SStefano Zampini 1243*1e0482f5SStefano Zampini /* coarse discrete gradient */ 1244*1e0482f5SStefano Zampini if (pcbddc->nedcG) { 1245*1e0482f5SStefano Zampini PetscInt cols[2]; 1246*1e0482f5SStefano Zampini 1247*1e0482f5SStefano Zampini cols[0] = 2*i; 1248*1e0482f5SStefano Zampini cols[1] = 2*i+1; 1249*1e0482f5SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSERT at local row %d, cols (%d,%d), cvals (%g,%g)\n",i,cols[0],cols[1],cvals[0],cvals[1]); 1250*1e0482f5SStefano Zampini ierr = MatSetValuesLocal(pcbddc->nedcG,1,&i,2,cols,cvals,INSERT_VALUES);CHKERRQ(ierr); 1251*1e0482f5SStefano Zampini } 1252a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1253a13144ffSStefano Zampini } 1254a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1255a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 1256*1e0482f5SStefano Zampini ierr = ISDestroy(&cornersis);CHKERRQ(ierr); 1257a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1258a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1259a13144ffSStefano Zampini } 1260a13144ffSStefano Zampini 1261a13144ffSStefano Zampini /* Start assembling */ 1262a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1263a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 1264a13144ffSStefano Zampini ierr = VecAssemblyBegin(quads[i]);CHKERRQ(ierr); 1265a13144ffSStefano Zampini } 1266*1e0482f5SStefano Zampini if (pcbddc->nedcG) { 1267*1e0482f5SStefano Zampini ierr = MatAssemblyBegin(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1268*1e0482f5SStefano Zampini } 1269a13144ffSStefano Zampini 1270a13144ffSStefano Zampini /* Free */ 1271c2151214SStefano Zampini if (fl2g) { 1272c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1273c2151214SStefano Zampini for (i=0;i<nee;i++) { 1274c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1275c2151214SStefano Zampini } 1276c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1277c2151214SStefano Zampini } 1278c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1279c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1280c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1281a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1282a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 1283c2151214SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 1284*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&al2g);CHKERRQ(ierr); 1285c2151214SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1286a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1287a13144ffSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1288b03ebc13SStefano Zampini ierr = PetscFree(corners);CHKERRQ(ierr); 1289b03ebc13SStefano Zampini ierr = PetscFree(cedges);CHKERRQ(ierr); 1290a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1291a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1292a13144ffSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1293a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1294a13144ffSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1295a13144ffSStefano Zampini 1296a13144ffSStefano Zampini /* Complete assembling */ 1297a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1298a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 1299a13144ffSStefano Zampini ierr = VecAssemblyEnd(quads[i]);CHKERRQ(ierr); 1300a13144ffSStefano Zampini } 1301a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 1302a13144ffSStefano Zampini ierr = VecDestroy(&quads[i]);CHKERRQ(ierr); 1303a13144ffSStefano Zampini } 1304a13144ffSStefano Zampini ierr = PetscFree(quads);CHKERRQ(ierr); 1305*1e0482f5SStefano Zampini if (pcbddc->nedcG) { 1306*1e0482f5SStefano Zampini ierr = MatAssemblyEnd(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1307*1e0482f5SStefano Zampini #if 0 1308*1e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->nedcG,"coarse_G");CHKERRQ(ierr); 1309*1e0482f5SStefano Zampini ierr = MatView(pcbddc->nedcG,NULL);CHKERRQ(ierr); 1310*1e0482f5SStefano Zampini #endif 1311*1e0482f5SStefano Zampini } 1312a13144ffSStefano Zampini 1313a13144ffSStefano Zampini /* set change of basis */ 1314a13144ffSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,PETSC_FALSE);CHKERRQ(ierr); 1315*1e0482f5SStefano Zampini #if 0 1316*1e0482f5SStefano Zampini if (pcbddc->current_level) { 1317*1e0482f5SStefano Zampini PetscViewer viewer; 1318*1e0482f5SStefano Zampini char filename[256]; 1319*1e0482f5SStefano Zampini Mat Tned; 1320*1e0482f5SStefano Zampini IS sub; 1321*1e0482f5SStefano Zampini PetscInt rst; 1322*1e0482f5SStefano Zampini 1323*1e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 1324*1e0482f5SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 1325*1e0482f5SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 1326*1e0482f5SStefano Zampini if (nedfieldlocal) { 1327*1e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 1328*1e0482f5SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 1329*1e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 1330*1e0482f5SStefano Zampini } else { 1331*1e0482f5SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 1332*1e0482f5SStefano Zampini } 1333*1e0482f5SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 1334*1e0482f5SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 1335*1e0482f5SStefano Zampini ierr = MatGetOwnershipRange(pc->pmat,&rst,NULL);CHKERRQ(ierr); 1336*1e0482f5SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 1337*1e0482f5SStefano Zampini if (matis->sf_rootdata[i]) { 1338*1e0482f5SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 1339*1e0482f5SStefano Zampini } 1340*1e0482f5SStefano Zampini } 1341*1e0482f5SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%D] LEVEL %d MY ne %d cum %d\n",PetscGlobalRank,pcbddc->current_level,ne,cum); 1342*1e0482f5SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),cum,matis->sf_rootdata,PETSC_USE_POINTER,&sub);CHKERRQ(ierr); 1343*1e0482f5SStefano Zampini ierr = MatGetSubMatrix(T,sub,sub,MAT_INITIAL_MATRIX,&Tned);CHKERRQ(ierr); 1344*1e0482f5SStefano Zampini ierr = ISDestroy(&sub);CHKERRQ(ierr); 1345*1e0482f5SStefano Zampini 1346*1e0482f5SStefano Zampini sprintf(filename,"Change_l%d.m",pcbddc->current_level); 1347*1e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)Tned),filename,&viewer);CHKERRQ(ierr); 1348*1e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1349*1e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)Tned,"T");CHKERRQ(ierr); 1350*1e0482f5SStefano Zampini ierr = MatView(Tned,viewer);CHKERRQ(ierr); 1351*1e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1352*1e0482f5SStefano Zampini ierr = MatDestroy(&Tned);CHKERRQ(ierr); 1353*1e0482f5SStefano Zampini } 1354*1e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1355*1e0482f5SStefano Zampini #endif 1356a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1357a13144ffSStefano Zampini 1358a13144ffSStefano Zampini /* set quadratures */ 1359a13144ffSStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnsp);CHKERRQ(ierr); 1360a13144ffSStefano Zampini ierr = MatNullSpaceDestroy(&nnsp);CHKERRQ(ierr); 1361a13144ffSStefano Zampini 1362a13144ffSStefano Zampini PetscFunctionReturn(0); 1363a13144ffSStefano Zampini } 1364a13144ffSStefano Zampini 1365d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1366d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1367d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1368d8203eabSStefano Zampini #undef __FUNCT__ 1369d8203eabSStefano Zampini #define __FUNCT__ "PCBDDCNullSpaceCreate" 1370d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1371d8203eabSStefano Zampini { 1372d8203eabSStefano Zampini PetscErrorCode ierr; 1373d8203eabSStefano Zampini PetscInt i; 1374d8203eabSStefano Zampini 1375d8203eabSStefano Zampini PetscFunctionBegin; 1376d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1377d8203eabSStefano Zampini PetscInt first,last; 1378d8203eabSStefano Zampini 1379d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 138086fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1381d8203eabSStefano Zampini if (i>=first && i < last) { 1382d8203eabSStefano Zampini PetscScalar *data; 1383d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1384d8203eabSStefano Zampini if (!has_const) { 1385d8203eabSStefano Zampini data[i-first] = 1.; 1386d8203eabSStefano Zampini } else { 138786fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 138886fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1389d8203eabSStefano Zampini } 1390d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1391d8203eabSStefano Zampini } 1392d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1393d8203eabSStefano Zampini } 1394d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1395d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1396d8203eabSStefano Zampini PetscInt first,last; 1397d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1398d8203eabSStefano Zampini if (i>=first && i < last) { 1399d8203eabSStefano Zampini PetscScalar *data; 1400d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1401d8203eabSStefano Zampini if (!has_const) { 1402d8203eabSStefano Zampini data[i-first] = 0.; 1403d8203eabSStefano Zampini } else { 140486fa73c5SStefano Zampini data[2*i-first] = 0.; 140586fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1406d8203eabSStefano Zampini } 1407d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1408d8203eabSStefano Zampini } 1409d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1410d8203eabSStefano Zampini } 1411d8203eabSStefano Zampini PetscFunctionReturn(0); 1412d8203eabSStefano Zampini } 1413d8203eabSStefano Zampini 1414669cc0f4SStefano Zampini #undef __FUNCT__ 1415669cc0f4SStefano Zampini #define __FUNCT__ "PCBDDCComputeNoNetFlux" 14168ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1417669cc0f4SStefano Zampini { 1418a198735bSStefano Zampini Mat loc_divudotp; 1419fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 14208ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1421669cc0f4SStefano Zampini IS *faces,*edges; 1422669cc0f4SStefano Zampini PetscScalar *vals; 1423669cc0f4SStefano Zampini const PetscScalar *array; 1424669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 14251ae86dd6SStefano Zampini PetscMPIInt rank; 1426a198735bSStefano Zampini PetscErrorCode ierr; 1427669cc0f4SStefano Zampini 1428669cc0f4SStefano Zampini PetscFunctionBegin; 1429669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1430669cc0f4SStefano Zampini if (graph->twodim) { 1431669cc0f4SStefano Zampini lmaxneighs = 2; 1432669cc0f4SStefano Zampini } else { 1433669cc0f4SStefano Zampini lmaxneighs = 1; 1434669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1435669cc0f4SStefano Zampini const PetscInt *idxs; 1436669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1437669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 1438669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1439669cc0f4SStefano Zampini } 1440669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 1441669cc0f4SStefano Zampini } 1442669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 1443669cc0f4SStefano Zampini maxsize = 0; 1444669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1445669cc0f4SStefano Zampini PetscInt nn; 1446669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1447669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1448669cc0f4SStefano Zampini } 1449669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1450669cc0f4SStefano Zampini PetscInt nn; 1451669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1452669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1453669cc0f4SStefano Zampini } 1454669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1455669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1456669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 14578ae0ca82SStefano Zampini if (!transpose) { 14588ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 14598ae0ca82SStefano Zampini } else { 14608ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 14618ae0ca82SStefano Zampini } 1462669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 14631ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1464d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1465669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 14668ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1467669cc0f4SStefano Zampini } 1468d8203eabSStefano Zampini 1469669cc0f4SStefano Zampini /* compute local quad vec */ 1470a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 14718ae0ca82SStefano Zampini if (!transpose) { 1472a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 14738ae0ca82SStefano Zampini } else { 14748ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 14758ae0ca82SStefano Zampini } 1476669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 14778ae0ca82SStefano Zampini if (!transpose) { 1478a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 14798ae0ca82SStefano Zampini } else { 14808ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 14818ae0ca82SStefano Zampini } 1482fa23a32eSStefano Zampini if (vl2l) { 1483fa23a32eSStefano Zampini ierr = VecGetSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1484fa23a32eSStefano Zampini } else { 1485fa23a32eSStefano Zampini vins = v; 1486fa23a32eSStefano Zampini } 1487fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1488669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 14899a962809SStefano Zampini 14901ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 14911ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1492669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1493669cc0f4SStefano Zampini const PetscInt *idxs; 1494669cc0f4SStefano Zampini PetscInt idx,nn,j; 1495669cc0f4SStefano Zampini 1496669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 1497669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1498669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 14991ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1500669cc0f4SStefano Zampini idx = -(idx+1); 1501669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1502669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 1503669cc0f4SStefano Zampini } 1504669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1505669cc0f4SStefano Zampini const PetscInt *idxs; 1506669cc0f4SStefano Zampini PetscInt idx,nn,j; 1507669cc0f4SStefano Zampini 1508669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1509669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1510669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 15111ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1512669cc0f4SStefano Zampini idx = -(idx+1); 1513669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1514669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1515669cc0f4SStefano Zampini } 1516c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1517fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1518fa23a32eSStefano Zampini if (vl2l) { 1519fa23a32eSStefano Zampini ierr = VecRestoreSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1520fa23a32eSStefano Zampini } 1521669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1522669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1523669cc0f4SStefano Zampini 1524669cc0f4SStefano Zampini /* assemble near null space */ 1525669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1526669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1527669cc0f4SStefano Zampini } 1528669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1529669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 1530669cc0f4SStefano Zampini } 1531669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1532669cc0f4SStefano Zampini PetscFunctionReturn(0); 1533669cc0f4SStefano Zampini } 1534669cc0f4SStefano Zampini 1535669cc0f4SStefano Zampini 1536a3df083aSStefano Zampini #undef __FUNCT__ 15371f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 15381f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 15391f4df5f7SStefano Zampini { 15401f4df5f7SStefano Zampini PetscErrorCode ierr; 15411f4df5f7SStefano Zampini Vec local,global; 15421f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15431f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 15441f4df5f7SStefano Zampini 15451f4df5f7SStefano Zampini PetscFunctionBegin; 15461f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 15471f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 15481f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 15491f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 15501f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 15511f4df5f7SStefano Zampini PetscInt i; 15521f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 15531f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 15541f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 15551f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 15561f4df5f7SStefano Zampini } 15571f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 15581f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 15591f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 15601f4df5f7SStefano Zampini } 15611f4df5f7SStefano Zampini } else { 1562986cdee1SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering if bs > 1 */ 15631f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1564986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 1565986cdee1SStefano Zampini if (i > 1) { 1566986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 15671f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 15681f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 15691f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 15701f4df5f7SStefano Zampini } 15711f4df5f7SStefano Zampini } 15721f4df5f7SStefano Zampini } 1573986cdee1SStefano Zampini } 15741f4df5f7SStefano Zampini 15751f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 15761f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 15771f4df5f7SStefano Zampini } 15781f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 15791f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 15801f4df5f7SStefano Zampini } 15811f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 15821f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 15831f4df5f7SStefano Zampini } 15841f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 15851f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 15861f4df5f7SStefano Zampini PetscFunctionReturn(0); 15871f4df5f7SStefano Zampini } 15881f4df5f7SStefano Zampini 15891f4df5f7SStefano Zampini #undef __FUNCT__ 15903e589ea0SStefano Zampini #define __FUNCT__ "PCBDDCBenignRemoveInterior" 15913e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 15923e589ea0SStefano Zampini { 15933e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 15943e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 15953e589ea0SStefano Zampini PetscErrorCode ierr; 15963e589ea0SStefano Zampini 15973e589ea0SStefano Zampini PetscFunctionBegin; 15983e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 15993e589ea0SStefano Zampini PetscFunctionReturn(0); 16003e589ea0SStefano Zampini } 16013e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 16023e589ea0SStefano Zampini Vec swap; 16033e589ea0SStefano Zampini 16043e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 16053e589ea0SStefano Zampini swap = pcbddc->work_change; 16063e589ea0SStefano Zampini pcbddc->work_change = r; 16073e589ea0SStefano Zampini r = swap; 16083e589ea0SStefano Zampini } 16093e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16103e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16113e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 16123e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 16133e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 16143e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 16153e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1616f913dca9SStefano Zampini pcbddc->work_change = r; 16173e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 16183e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 16193e589ea0SStefano Zampini } 16203e589ea0SStefano Zampini PetscFunctionReturn(0); 16213e589ea0SStefano Zampini } 16223e589ea0SStefano Zampini 16233e589ea0SStefano Zampini #undef __FUNCT__ 1624a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 1625a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1626a3df083aSStefano Zampini { 1627a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1628a3df083aSStefano Zampini PetscErrorCode ierr; 1629a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1630a3df083aSStefano Zampini 1631a3df083aSStefano Zampini PetscFunctionBegin; 1632a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1633a3df083aSStefano Zampini if (transpose) { 1634a3df083aSStefano Zampini apply_right = ctx->apply_left; 1635a3df083aSStefano Zampini apply_left = ctx->apply_right; 1636a3df083aSStefano Zampini } else { 1637a3df083aSStefano Zampini apply_right = ctx->apply_right; 1638a3df083aSStefano Zampini apply_left = ctx->apply_left; 1639a3df083aSStefano Zampini } 1640a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1641a3df083aSStefano Zampini if (apply_right) { 1642a3df083aSStefano Zampini const PetscScalar *ax; 1643a3df083aSStefano Zampini PetscInt nl,i; 1644a3df083aSStefano Zampini 1645a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1646a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1647a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1648a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1649a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1650a3df083aSStefano Zampini PetscScalar sum,val; 1651a3df083aSStefano Zampini const PetscInt *idxs; 1652a3df083aSStefano Zampini PetscInt nz,j; 1653a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1654a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1655a3df083aSStefano Zampini sum = 0.; 1656a3df083aSStefano Zampini if (ctx->apply_p0) { 1657a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1658a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1659a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1660a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1661a3df083aSStefano Zampini } 1662a3df083aSStefano Zampini } else { 1663a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1664a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1665a3df083aSStefano Zampini } 1666a3df083aSStefano Zampini } 1667a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1668a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1669a3df083aSStefano Zampini } 1670a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1671a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1672a3df083aSStefano Zampini } 1673a3df083aSStefano Zampini if (transpose) { 1674a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1675a3df083aSStefano Zampini } else { 1676a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1677a3df083aSStefano Zampini } 1678a3df083aSStefano Zampini if (reset_x) { 1679a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1680a3df083aSStefano Zampini } 1681a3df083aSStefano Zampini if (apply_left) { 1682a3df083aSStefano Zampini PetscScalar *ay; 1683a3df083aSStefano Zampini PetscInt i; 1684a3df083aSStefano Zampini 1685a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1686a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1687a3df083aSStefano Zampini PetscScalar sum,val; 1688a3df083aSStefano Zampini const PetscInt *idxs; 1689a3df083aSStefano Zampini PetscInt nz,j; 1690a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1691a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1692a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1693a3df083aSStefano Zampini if (ctx->apply_p0) { 1694a3df083aSStefano Zampini sum = 0.; 1695a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1696a3df083aSStefano Zampini sum += ay[idxs[j]]; 1697a3df083aSStefano Zampini ay[idxs[j]] += val; 1698a3df083aSStefano Zampini } 1699a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1700a3df083aSStefano Zampini } else { 1701a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1702a3df083aSStefano Zampini ay[idxs[j]] += val; 1703a3df083aSStefano Zampini } 1704a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1705a3df083aSStefano Zampini } 1706a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1707a3df083aSStefano Zampini } 1708a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1709a3df083aSStefano Zampini } 1710a3df083aSStefano Zampini PetscFunctionReturn(0); 1711a3df083aSStefano Zampini } 1712a3df083aSStefano Zampini 1713a3df083aSStefano Zampini #undef __FUNCT__ 1714a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 1715a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1716a3df083aSStefano Zampini { 1717a3df083aSStefano Zampini PetscErrorCode ierr; 1718a3df083aSStefano Zampini 1719a3df083aSStefano Zampini PetscFunctionBegin; 1720a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1721a3df083aSStefano Zampini PetscFunctionReturn(0); 1722a3df083aSStefano Zampini } 1723a3df083aSStefano Zampini 1724a3df083aSStefano Zampini #undef __FUNCT__ 1725a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 1726a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1727a3df083aSStefano Zampini { 1728a3df083aSStefano Zampini PetscErrorCode ierr; 1729a3df083aSStefano Zampini 1730a3df083aSStefano Zampini PetscFunctionBegin; 1731a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1732a3df083aSStefano Zampini PetscFunctionReturn(0); 1733a3df083aSStefano Zampini } 1734a3df083aSStefano Zampini 1735a3df083aSStefano Zampini #undef __FUNCT__ 1736a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 1737a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1738a3df083aSStefano Zampini { 1739a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1740a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1741a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1742a3df083aSStefano Zampini PetscErrorCode ierr; 1743a3df083aSStefano Zampini 1744a3df083aSStefano Zampini PetscFunctionBegin; 1745a3df083aSStefano Zampini if (!restore) { 17461dd7afcfSStefano Zampini Mat A_IB,A_BI; 1747a3df083aSStefano Zampini PetscScalar *work; 1748b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1749a3df083aSStefano Zampini 17509a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 17519a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1752a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1753a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1754a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1755a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1756a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1757a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1758a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 1759a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 1760a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 1761a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 1762a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 1763a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 1764059032f7SStefano Zampini if (reuse) { 1765a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 17661dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 1767059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 1768059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 1769059032f7SStefano Zampini PetscInt i; 1770059032f7SStefano Zampini 1771059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 1772059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1773059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1774059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1775059032f7SStefano Zampini } 1776059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 17771dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 1778059032f7SStefano Zampini } 1779a3df083aSStefano Zampini ctx->A = pcis->A_IB; 1780a3df083aSStefano Zampini ctx->work = work; 1781a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 1782a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1783a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1784a3df083aSStefano Zampini pcis->A_IB = A_IB; 1785a3df083aSStefano Zampini 1786a3df083aSStefano Zampini /* A_BI as A_IB^T */ 1787a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 1788a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 1789a3df083aSStefano Zampini pcis->A_BI = A_BI; 1790a3df083aSStefano Zampini } else { 17911dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 17921dd7afcfSStefano Zampini PetscFunctionReturn(0); 17931dd7afcfSStefano Zampini } 1794a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 1795a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1796a3df083aSStefano Zampini pcis->A_IB = ctx->A; 17971dd7afcfSStefano Zampini ctx->A = NULL; 17981dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 17991dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 18001dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 18011dd7afcfSStefano Zampini if (ctx->free) { 1802059032f7SStefano Zampini PetscInt i; 18031dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1804059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1805059032f7SStefano Zampini } 1806059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1807059032f7SStefano Zampini } 1808a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 1809a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 1810a3df083aSStefano Zampini } 1811a3df083aSStefano Zampini PetscFunctionReturn(0); 1812a3df083aSStefano Zampini } 1813a3df083aSStefano Zampini 1814a3df083aSStefano Zampini /* used just in bddc debug mode */ 1815a3df083aSStefano Zampini #undef __FUNCT__ 1816a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 1817a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 1818a3df083aSStefano Zampini { 1819a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1820a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1821a3df083aSStefano Zampini Mat An; 1822a3df083aSStefano Zampini PetscErrorCode ierr; 1823a3df083aSStefano Zampini 1824a3df083aSStefano Zampini PetscFunctionBegin; 1825a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 1826a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 1827a3df083aSStefano Zampini if (is1) { 1828a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 1829a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 1830a3df083aSStefano Zampini } else { 1831a3df083aSStefano Zampini *B = An; 1832a3df083aSStefano Zampini } 1833a3df083aSStefano Zampini PetscFunctionReturn(0); 1834a3df083aSStefano Zampini } 1835a3df083aSStefano Zampini 18361cf9b237SStefano Zampini /* TODO: add reuse flag */ 18371cf9b237SStefano Zampini #undef __FUNCT__ 18381cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 18391cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 18401cf9b237SStefano Zampini { 18411cf9b237SStefano Zampini Mat Bt; 18421cf9b237SStefano Zampini PetscScalar *a,*bdata; 18431cf9b237SStefano Zampini const PetscInt *ii,*ij; 18441cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 18451cf9b237SStefano Zampini PetscBool flg_row; 18461cf9b237SStefano Zampini PetscErrorCode ierr; 18471cf9b237SStefano Zampini 18481cf9b237SStefano Zampini PetscFunctionBegin; 18491cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 18501cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 18511cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 18521cf9b237SStefano Zampini nnz = n; 18531cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 18541cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 18551cf9b237SStefano Zampini } 18561cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 18571cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 18581cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 18591cf9b237SStefano Zampini nnz = 0; 18601cf9b237SStefano Zampini bii[0] = 0; 18611cf9b237SStefano Zampini for (i=0;i<n;i++) { 18621cf9b237SStefano Zampini PetscInt j; 18631cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 18641cf9b237SStefano Zampini PetscScalar entry = a[j]; 18651cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 18661cf9b237SStefano Zampini bij[nnz] = ij[j]; 18671cf9b237SStefano Zampini bdata[nnz] = entry; 18681cf9b237SStefano Zampini nnz++; 18691cf9b237SStefano Zampini } 18701cf9b237SStefano Zampini } 18711cf9b237SStefano Zampini bii[i+1] = nnz; 18721cf9b237SStefano Zampini } 18731cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 18741cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 18751cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 18761cf9b237SStefano Zampini { 18771cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 18781cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 18791cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 18801cf9b237SStefano Zampini } 18811cf9b237SStefano Zampini *B = Bt; 18821cf9b237SStefano Zampini PetscFunctionReturn(0); 18831cf9b237SStefano Zampini } 18841cf9b237SStefano Zampini 1885674ae819SStefano Zampini #undef __FUNCT__ 18864f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 18874f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 18884f1b2e48SStefano Zampini { 18894f1b2e48SStefano Zampini Mat B; 18904f1b2e48SStefano Zampini IS is_dummy,*cc_n; 18914f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 18924f1b2e48SStefano Zampini PCBDDCGraph graph; 18934f1b2e48SStefano Zampini PetscInt i,n; 18944f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 18954f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 18964f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 18974f1b2e48SStefano Zampini PetscErrorCode ierr; 18984f1b2e48SStefano Zampini 18994f1b2e48SStefano Zampini PetscFunctionBegin; 190063c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 190163c961adSStefano Zampini *ncc = 0; 190263c961adSStefano Zampini *cc = NULL; 190363c961adSStefano Zampini PetscFunctionReturn(0); 190463c961adSStefano Zampini } 19054f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 19064f1b2e48SStefano Zampini if (!isseqaij && filter) { 19071cf9b237SStefano Zampini PetscBool isseqdense; 19081cf9b237SStefano Zampini 19091cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 19101cf9b237SStefano Zampini if (!isseqdense) { 19114f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 19121cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 19131cf9b237SStefano Zampini PetscScalar *array; 19141cf9b237SStefano Zampini PetscReal chop=1.e-6; 19151cf9b237SStefano Zampini 19161cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 19171cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 19181cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 19191cf9b237SStefano Zampini for (i=0;i<n;i++) { 19201cf9b237SStefano Zampini PetscInt j; 19211cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 19221cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 19231cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 19241cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 19251cf9b237SStefano Zampini } 19261cf9b237SStefano Zampini } 19271cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 19289d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 19291cf9b237SStefano Zampini } 19304f1b2e48SStefano Zampini } else { 19314f1b2e48SStefano Zampini B = A; 19324f1b2e48SStefano Zampini } 19334f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 19344f1b2e48SStefano Zampini 19354f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 19364f1b2e48SStefano Zampini if (filter) { 19374f1b2e48SStefano Zampini PetscScalar *data; 19384f1b2e48SStefano Zampini PetscInt j,cum; 19394f1b2e48SStefano Zampini 19404f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 19414f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 19424f1b2e48SStefano Zampini cum = 0; 19434f1b2e48SStefano Zampini for (i=0;i<n;i++) { 19444f1b2e48SStefano Zampini PetscInt t; 19454f1b2e48SStefano Zampini 19464f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 19474f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 19484f1b2e48SStefano Zampini continue; 19494f1b2e48SStefano Zampini } 19504f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 19514f1b2e48SStefano Zampini } 19524f1b2e48SStefano Zampini t = xadj_filtered[i]; 19534f1b2e48SStefano Zampini xadj_filtered[i] = cum; 19544f1b2e48SStefano Zampini cum += t; 19554f1b2e48SStefano Zampini } 19564f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 19574f1b2e48SStefano Zampini } else { 19584f1b2e48SStefano Zampini xadj_filtered = NULL; 19594f1b2e48SStefano Zampini adjncy_filtered = NULL; 19604f1b2e48SStefano Zampini } 19614f1b2e48SStefano Zampini 19624f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 19634f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 19644f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 19654f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 19664f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 1967be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 19684f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 19694f1b2e48SStefano Zampini if (xadj_filtered) { 19704f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 19714f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 19724f1b2e48SStefano Zampini } else { 19734f1b2e48SStefano Zampini graph->xadj = xadj; 19744f1b2e48SStefano Zampini graph->adjncy = adjncy; 19754f1b2e48SStefano Zampini } 19764f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 19774f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 19784f1b2e48SStefano Zampini /* partial clean up */ 19794f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 19804f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 19811cf9b237SStefano Zampini if (A != B) { 19824f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 19834f1b2e48SStefano Zampini } 19844f1b2e48SStefano Zampini 19854f1b2e48SStefano Zampini /* get back data */ 19861cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 19871cf9b237SStefano Zampini if (cc) { 19884f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 19894f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 19904f1b2e48SStefano 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); 19914f1b2e48SStefano Zampini } 19924f1b2e48SStefano Zampini *cc = cc_n; 19931cf9b237SStefano Zampini } 19944f1b2e48SStefano Zampini /* clean up graph */ 19954f1b2e48SStefano Zampini graph->xadj = 0; 19964f1b2e48SStefano Zampini graph->adjncy = 0; 19974f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 19984f1b2e48SStefano Zampini PetscFunctionReturn(0); 19994f1b2e48SStefano Zampini } 20004f1b2e48SStefano Zampini 20014f1b2e48SStefano Zampini #undef __FUNCT__ 20025408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 20035408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 20045408967cSStefano Zampini { 20055408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 20065408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2007dee84bffSStefano Zampini IS dirIS = NULL; 20084f1b2e48SStefano Zampini PetscInt i; 20095408967cSStefano Zampini PetscErrorCode ierr; 20105408967cSStefano Zampini 20115408967cSStefano Zampini PetscFunctionBegin; 2012dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 20135408967cSStefano Zampini if (zerodiag) { 20145408967cSStefano Zampini Mat A; 20155408967cSStefano Zampini Vec vec3_N; 20165408967cSStefano Zampini PetscScalar *vals; 20175408967cSStefano Zampini const PetscInt *idxs; 2018d12d3064SStefano Zampini PetscInt nz,*count; 20195408967cSStefano Zampini 20205408967cSStefano Zampini /* p0 */ 20215408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 20225408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 20235408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 20245408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 20254f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 20265408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 20275408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 20285408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 20295408967cSStefano Zampini /* v_I */ 20305408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 20315408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 20325408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 20335408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 20345408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 20355408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 20365408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 20375408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 20385408967cSStefano Zampini if (dirIS) { 20395408967cSStefano Zampini PetscInt n; 20405408967cSStefano Zampini 20415408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 20425408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 20435408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 20445408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 20455408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 20465408967cSStefano Zampini } 20475408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 20485408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 20495408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 20505408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2051669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 20525408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 20535408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 20549a962809SStefano 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])); 20555408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 20565408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2057d12d3064SStefano Zampini 2058d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2059d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2060d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2061d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2062d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2063d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 20649a962809SStefano 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]); 2065d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2066d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 20675408967cSStefano Zampini } 2068dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 20695408967cSStefano Zampini 20705408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 20715408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 20724f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 20735408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 20744f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 20755408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2076f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2077f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 2078f2a566d8SStefano Zampini 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);CHKERRQ(ierr); 2079f2a566d8SStefano Zampini } 20805408967cSStefano Zampini PetscFunctionReturn(0); 20815408967cSStefano Zampini } 20825408967cSStefano Zampini 20835408967cSStefano Zampini #undef __FUNCT__ 2084339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 2085339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 2086339f8db1SStefano Zampini { 2087339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 20884f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 2089b0f5fe93SStefano Zampini PetscInt nz,n; 20901f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 20914f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 2092339f8db1SStefano Zampini PetscErrorCode ierr; 2093339f8db1SStefano Zampini 2094339f8db1SStefano Zampini PetscFunctionBegin; 20959f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 20969f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2097a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2098a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2099a3df083aSStefano Zampini } 2100a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2101a3df083aSStefano Zampini pcbddc->benign_n = 0; 21021ae86dd6SStefano Zampini /* if a local info on dofs is present, assumes that the last field represents "pressures" 21034f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 21044f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 21054f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 21061ae86dd6SStefano Zampini since the local Schur complements are already SPD 21074f1b2e48SStefano Zampini */ 21084f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 21094f1b2e48SStefano Zampini have_null = PETSC_TRUE; 211040fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 21114f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 21124f1b2e48SStefano Zampini 21134f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 21144f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 21154f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 21164f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 2117ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 211840fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 211940fa8d13SStefano Zampini if (!sorted) { 212040fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 212140fa8d13SStefano Zampini } 212240fa8d13SStefano Zampini } else { 212340fa8d13SStefano Zampini pressures = NULL; 212440fa8d13SStefano Zampini } 212597d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 212697d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 212727b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 212897d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2129339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2130339f8db1SStefano Zampini if (!sorted) { 2131339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2132339f8db1SStefano Zampini } 2133339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 21344f1b2e48SStefano Zampini if (!nz) { 21354f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 21364f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 213740fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 213840fa8d13SStefano Zampini } 21394f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 21404f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 21414f1b2e48SStefano Zampini zerodiag_subs = NULL; 21424f1b2e48SStefano Zampini pcbddc->benign_n = 0; 21431f4df5f7SStefano Zampini n_interior_dofs = 0; 21441f4df5f7SStefano Zampini interior_dofs = NULL; 21451f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 21461f4df5f7SStefano Zampini PetscInt n,i,j; 21471f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 21481f4df5f7SStefano Zampini PetscInt *iwork; 21491f4df5f7SStefano Zampini 21501f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 21511f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 21521f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 21531f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 215490648384SStefano Zampini for (i=1;i<n_neigh;i++) 21551f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 21561f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 21571f4df5f7SStefano Zampini for (i=0;i<n;i++) 21581f4df5f7SStefano Zampini if (!iwork[i]) 21591f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 21601f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 21611f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 21621f4df5f7SStefano Zampini } 21634f1b2e48SStefano Zampini if (has_null_pressures) { 21644f1b2e48SStefano Zampini IS *subs; 21651f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 21661f4df5f7SStefano Zampini const PetscInt *idxs; 21671f4df5f7SStefano Zampini PetscScalar *array; 21681f4df5f7SStefano Zampini Vec *work; 21691f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 21704f1b2e48SStefano Zampini 21714f1b2e48SStefano Zampini subs = pcbddc->local_subs; 21724f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 21731f4df5f7SStefano 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) */ 21741f4df5f7SStefano Zampini if (pcbddc->current_level) { 21751f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 21761f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 21771f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 21781f4df5f7SStefano Zampini /* work[0] = 1_p */ 21791f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 21801f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 21811f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 21821f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 21831f4df5f7SStefano Zampini /* work[0] = 1_v */ 21841f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 21851f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 21861f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 21871f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 21881f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 21891f4df5f7SStefano Zampini } 21904f1b2e48SStefano Zampini if (nsubs > 1) { 21914f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 21924f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 21934f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 21944f1b2e48SStefano Zampini IS t_zerodiag_subs; 21954f1b2e48SStefano Zampini PetscInt nl; 21964f1b2e48SStefano Zampini 21974f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 21984f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 21994f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 22004f1b2e48SStefano Zampini if (nl) { 22014f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 22024f1b2e48SStefano Zampini 22031f4df5f7SStefano Zampini if (pcbddc->current_level) { 22041f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 22051f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 22061f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 22071f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 22081f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 22091f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 22101f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 22111f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 22121f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 22131f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 22141f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 22151f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 22161f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 22171f4df5f7SStefano Zampini valid = PETSC_FALSE; 22181f4df5f7SStefano Zampini break; 22191f4df5f7SStefano Zampini } 22201f4df5f7SStefano Zampini } 22211f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 22221f4df5f7SStefano Zampini } 22231f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 22241f4df5f7SStefano Zampini IS t_bc; 22251f4df5f7SStefano Zampini PetscInt nzb; 22261f4df5f7SStefano Zampini 22271f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 22281f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 22291f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 22301f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 22311f4df5f7SStefano Zampini } 22321f4df5f7SStefano Zampini if (valid && pressures) { 22334f1b2e48SStefano Zampini IS t_pressure_subs; 22344f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 22354f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 22364f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 22374f1b2e48SStefano Zampini } 22384f1b2e48SStefano Zampini if (valid) { 22394f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 22404f1b2e48SStefano Zampini pcbddc->benign_n++; 22414f1b2e48SStefano Zampini } else { 22424f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 22434f1b2e48SStefano Zampini } 22444f1b2e48SStefano Zampini } 22454f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 22464f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 22474f1b2e48SStefano Zampini } 22484f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 22494f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 22501f4df5f7SStefano Zampini 22511f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 22521f4df5f7SStefano Zampini PetscInt nzb; 22531f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 22541f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 22551f4df5f7SStefano Zampini } 22561f4df5f7SStefano Zampini if (valid && pressures) { 22574f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 22584f1b2e48SStefano Zampini } 22591f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 22601f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 22611f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 22621f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 22631f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 22641f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 22651f4df5f7SStefano Zampini valid = PETSC_FALSE; 22661f4df5f7SStefano Zampini break; 22671f4df5f7SStefano Zampini } 22681f4df5f7SStefano Zampini } 22691f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 22701f4df5f7SStefano Zampini } 22714f1b2e48SStefano Zampini if (valid) { 22724f1b2e48SStefano Zampini pcbddc->benign_n = 1; 2273ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 22744f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 22754f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 22764f1b2e48SStefano Zampini } 22774f1b2e48SStefano Zampini } 22781f4df5f7SStefano Zampini if (pcbddc->current_level) { 22791f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 22804f1b2e48SStefano Zampini } 22811f4df5f7SStefano Zampini } 22821f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 22834f1b2e48SStefano Zampini 22844f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2285b9b0e38cSStefano Zampini PetscInt n; 2286b9b0e38cSStefano Zampini 22874f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 22884f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2289b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2290b9b0e38cSStefano Zampini if (n) { 22914f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 22924f1b2e48SStefano Zampini have_null = PETSC_FALSE; 22934f1b2e48SStefano Zampini } 2294b9b0e38cSStefano Zampini } 22954f1b2e48SStefano Zampini 22964f1b2e48SStefano Zampini /* final check for null pressures */ 22974f1b2e48SStefano Zampini if (zerodiag && pressures) { 22984f1b2e48SStefano Zampini PetscInt nz,np; 22994f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 23004f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 23014f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 23024f1b2e48SStefano Zampini } 23034f1b2e48SStefano Zampini 23044f1b2e48SStefano Zampini if (recompute_zerodiag) { 23054f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 23064f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 23074f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 23084f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 23094f1b2e48SStefano Zampini } else { 23104f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 23114f1b2e48SStefano Zampini 23124f1b2e48SStefano Zampini nzn = 0; 23134f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 23144f1b2e48SStefano Zampini PetscInt ns; 23154f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 23164f1b2e48SStefano Zampini nzn += ns; 23174f1b2e48SStefano Zampini } 23184f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 23194f1b2e48SStefano Zampini nzn = 0; 23204f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 23214f1b2e48SStefano Zampini PetscInt ns,*idxs; 23224f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 23234f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 23244f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 23254f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 23264f1b2e48SStefano Zampini nzn += ns; 23274f1b2e48SStefano Zampini } 23284f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 23294f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 23304f1b2e48SStefano Zampini } 23314f1b2e48SStefano Zampini have_null = PETSC_FALSE; 23324f1b2e48SStefano Zampini } 23334f1b2e48SStefano Zampini 2334669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2335a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2336a198735bSStefano Zampini Mat A,loc_divudotp; 2337a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2338a198735bSStefano Zampini IS row,col,isused = NULL; 2339a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2340a198735bSStefano Zampini 23411f4df5f7SStefano Zampini if (pressures) { 23421f4df5f7SStefano Zampini isused = pressures; 23431f4df5f7SStefano Zampini } else { 23441f4df5f7SStefano Zampini isused = zerodiag; 23451f4df5f7SStefano Zampini } 2346a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2347669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 23481ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 23491ae86dd6SStefano 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"); 2350a198735bSStefano Zampini n_isused = 0; 2351a198735bSStefano Zampini if (isused) { 2352a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2353a198735bSStefano Zampini } 2354a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2355a198735bSStefano Zampini st = st-n_isused; 23561ae86dd6SStefano Zampini if (n) { 2357a198735bSStefano Zampini const PetscInt *gidxs; 2358a198735bSStefano Zampini 2359a198735bSStefano Zampini ierr = MatGetSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2360a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2361a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2362a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2363a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2364a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 23651ae86dd6SStefano Zampini } else { 2366a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2367a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2368a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2369a198735bSStefano Zampini } 2370a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2371a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2372a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2373a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2374a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2375a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2376a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2377a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2378a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2379a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2380a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2381a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2382a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2383a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 23841ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23851ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23861ae86dd6SStefano Zampini } 2387b3afcdbeSStefano Zampini 2388b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 23894f1b2e48SStefano Zampini if (has_null_pressures) { 23904f1b2e48SStefano Zampini IS zerodiagc; 23914f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 23924f1b2e48SStefano Zampini PetscInt i,s,*nnz; 23934f1b2e48SStefano Zampini 23944f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2395339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 2396339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 2397339f8db1SStefano Zampini /* local change of basis for pressures */ 2398339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 239997d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2400339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2401339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2402339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 24034f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 24044f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 24054f1b2e48SStefano Zampini PetscInt nzs,j; 24064f1b2e48SStefano Zampini 24074f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 24084f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 24094f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 24104f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 24114f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 24124f1b2e48SStefano Zampini } 2413339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2414339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2415339f8db1SStefano Zampini /* set identity on velocities */ 2416339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 2417339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 2418339f8db1SStefano Zampini } 24194f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 24204f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 24219f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 24224f1b2e48SStefano 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); 2423339f8db1SStefano Zampini /* set change on pressures */ 24244f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 24254f1b2e48SStefano Zampini PetscScalar *array; 24264f1b2e48SStefano Zampini PetscInt nzs; 24274f1b2e48SStefano Zampini 24284f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 24294f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 24304f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2431339f8db1SStefano Zampini PetscScalar vals[2]; 2432339f8db1SStefano Zampini PetscInt cols[2]; 2433339f8db1SStefano Zampini 2434339f8db1SStefano Zampini cols[0] = idxs[i]; 24354f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2436339f8db1SStefano Zampini vals[0] = 1.; 2437b0f5fe93SStefano Zampini vals[1] = 1.; 24384f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2439339f8db1SStefano Zampini } 24404f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 24414f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 24424f1b2e48SStefano Zampini array[nzs-1] = 1.; 24434f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 24444f1b2e48SStefano Zampini /* store local idxs for p0 */ 24454f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 24464f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2447339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 24484f1b2e48SStefano Zampini } 2449339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2450339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2451a3df083aSStefano Zampini /* project if needed */ 2452a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 24531dd7afcfSStefano Zampini Mat M; 24541dd7afcfSStefano Zampini 24551dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2456339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 24571dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 24581dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2459a3df083aSStefano Zampini } 24604f1b2e48SStefano Zampini /* store global idxs for p0 */ 24614f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2462339f8db1SStefano Zampini } 2463ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 24644f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 2465b0f5fe93SStefano Zampini 2466b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 2467b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 246827b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 246927b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2470339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2471339f8db1SStefano Zampini PetscFunctionReturn(0); 2472339f8db1SStefano Zampini } 2473339f8db1SStefano Zampini 2474339f8db1SStefano Zampini #undef __FUNCT__ 2475015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 2476015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2477efc2fbd9SStefano Zampini { 2478efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2479de9d7bd0SStefano Zampini PetscScalar *array; 2480efc2fbd9SStefano Zampini PetscErrorCode ierr; 2481efc2fbd9SStefano Zampini 2482efc2fbd9SStefano Zampini PetscFunctionBegin; 2483efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2484efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 24854f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2486efc2fbd9SStefano Zampini } 2487de9d7bd0SStefano Zampini if (get) { 2488efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 24894f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 24904f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2491efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2492de9d7bd0SStefano Zampini } else { 2493de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2494de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2495de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2496de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2497efc2fbd9SStefano Zampini } 2498efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2499efc2fbd9SStefano Zampini } 2500efc2fbd9SStefano Zampini 2501efc2fbd9SStefano Zampini #undef __FUNCT__ 2502c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 2503c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2504c263805aSStefano Zampini { 2505c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2506c263805aSStefano Zampini PetscErrorCode ierr; 2507c263805aSStefano Zampini 2508c263805aSStefano Zampini PetscFunctionBegin; 2509c263805aSStefano Zampini /* TODO: add error checking 2510c263805aSStefano Zampini - avoid nested pop (or push) calls. 2511c263805aSStefano Zampini - cannot push before pop. 25121c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2513c263805aSStefano Zampini */ 25144f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2515efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2516efc2fbd9SStefano Zampini } 2517c263805aSStefano Zampini if (pop) { 2518a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 25194f1b2e48SStefano Zampini IS is_p0; 25204f1b2e48SStefano Zampini MatReuse reuse; 2521c263805aSStefano Zampini 2522c263805aSStefano Zampini /* extract B_0 */ 25234f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 25244f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 25254f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 25264f1b2e48SStefano Zampini } 25274f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 25284f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2529c263805aSStefano Zampini /* remove rows and cols from local problem */ 2530c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 253197d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 25324f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 25334f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2534a3df083aSStefano Zampini } else { 2535a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2536a3df083aSStefano Zampini PetscScalar *vals; 2537a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2538a3df083aSStefano Zampini 2539a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2540a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2541a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 25420b5adadeSStefano Zampini PetscInt *nnz; 2543a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2544a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2545a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2546331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2547331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2548331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2549331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2550331e053bSStefano Zampini } 2551331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2552331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2553331e053bSStefano Zampini } 2554a3df083aSStefano Zampini 2555a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2556a3df083aSStefano Zampini PetscScalar *array; 2557a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2558a3df083aSStefano Zampini 2559a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2560a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2561a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2562a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2563a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2564a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2565a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2566a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2567a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2568a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2569a3df083aSStefano Zampini cum = 0; 2570a3df083aSStefano Zampini for (j=0;j<n;j++) { 257122db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2572a3df083aSStefano Zampini vals[cum] = array[j]; 2573a3df083aSStefano Zampini idxs_ins[cum] = j; 2574a3df083aSStefano Zampini cum++; 2575a3df083aSStefano Zampini } 2576a3df083aSStefano Zampini } 2577a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2578a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2579a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2580a3df083aSStefano Zampini } 2581a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2582a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2583a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2584a3df083aSStefano Zampini } 2585c263805aSStefano Zampini } else { /* push */ 2586a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 25874f1b2e48SStefano Zampini PetscInt i; 25884f1b2e48SStefano Zampini 25894f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 25904f1b2e48SStefano Zampini PetscScalar *B0_vals; 25914f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 25924f1b2e48SStefano Zampini 25934f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 25944f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 25957b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 25964f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 25974f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 25984f1b2e48SStefano Zampini } 2599c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2600c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2601a3df083aSStefano Zampini } else { 2602a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2603a3df083aSStefano Zampini } 2604c263805aSStefano Zampini } 2605c263805aSStefano Zampini PetscFunctionReturn(0); 2606c263805aSStefano Zampini } 2607c263805aSStefano Zampini 2608c263805aSStefano Zampini #undef __FUNCT__ 2609b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 261008122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2611b1b3d7a2SStefano Zampini { 2612b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 261308122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 261408122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 261508122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 261608122e43SStefano Zampini PetscScalar *work,lwork; 261708122e43SStefano Zampini PetscScalar *St,*S,*eigv; 261808122e43SStefano Zampini PetscScalar *Sarray,*Starray; 261908122e43SStefano Zampini PetscReal *eigs,thresh; 26201b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2621f6f667cfSStefano Zampini PetscBool allocated_S_St; 262208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 262308122e43SStefano Zampini PetscReal *rwork; 262408122e43SStefano Zampini #endif 2625b1b3d7a2SStefano Zampini PetscErrorCode ierr; 2626b1b3d7a2SStefano Zampini 2627b1b3d7a2SStefano Zampini PetscFunctionBegin; 2628b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 2629af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 2630af25d912SStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adaptive selection not yet implemented for general matrix pencils (herm %d, posdef %d)\n",sub_schurs->is_hermitian,sub_schurs->is_posdef); 263106a4e24aSStefano Zampini 2632fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2633fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2634fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2635fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 26361575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2637fd14bc51SStefano Zampini } 2638fd14bc51SStefano Zampini 2639e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 2640e496cd5dSStefano 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); 2641e496cd5dSStefano Zampini } 2642e496cd5dSStefano Zampini 264308122e43SStefano Zampini /* max size of subsets */ 264408122e43SStefano Zampini mss = 0; 264508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 264608122e43SStefano Zampini PetscInt subset_size; 2647862806e4SStefano Zampini 264808122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 264908122e43SStefano Zampini mss = PetscMax(mss,subset_size); 265008122e43SStefano Zampini } 265108122e43SStefano Zampini 265208122e43SStefano Zampini /* min/max and threshold */ 265308122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 2654f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 265508122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 2656f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 2657f6f667cfSStefano Zampini if (nmin) { 2658f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 2659f6f667cfSStefano Zampini } 266008122e43SStefano Zampini 266108122e43SStefano Zampini /* allocate lapack workspace */ 266208122e43SStefano Zampini cum = cum2 = 0; 266308122e43SStefano Zampini maxneigs = 0; 266408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 266508122e43SStefano Zampini PetscInt n,subset_size; 2666f6f667cfSStefano Zampini 266708122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 266808122e43SStefano Zampini n = PetscMin(subset_size,nmax); 26699162d606SStefano Zampini cum += subset_size; 26709162d606SStefano Zampini cum2 += subset_size*n; 267108122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 267208122e43SStefano Zampini } 267308122e43SStefano Zampini if (mss) { 26749ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 267508122e43SStefano Zampini PetscBLASInt B_itype = 1; 267608122e43SStefano Zampini PetscBLASInt B_N = mss; 26774c6709b3SStefano Zampini PetscReal zero = 0.0; 26784c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 267908122e43SStefano Zampini 268008122e43SStefano Zampini B_lwork = -1; 268108122e43SStefano Zampini S = NULL; 268208122e43SStefano Zampini St = NULL; 2683a58a30b4SStefano Zampini eigs = NULL; 2684a58a30b4SStefano Zampini eigv = NULL; 2685a58a30b4SStefano Zampini B_iwork = NULL; 2686a58a30b4SStefano Zampini B_ifail = NULL; 2687d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2688d1710679SStefano Zampini rwork = NULL; 2689d1710679SStefano Zampini #endif 26908bec7fa6SStefano Zampini thresh = 1.0; 269108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 269208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 269308122e43SStefano 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)); 269408122e43SStefano Zampini #else 269508122e43SStefano 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)); 269608122e43SStefano Zampini #endif 269708122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 269808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 269908122e43SStefano Zampini } else { 270008122e43SStefano Zampini /* TODO */ 270108122e43SStefano Zampini } 270208122e43SStefano Zampini } else { 270308122e43SStefano Zampini lwork = 0; 270408122e43SStefano Zampini } 270508122e43SStefano Zampini 270608122e43SStefano Zampini nv = 0; 2707d62866d3SStefano 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) */ 2708d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 270908122e43SStefano Zampini } 27104c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 2711f6f667cfSStefano Zampini if (allocated_S_St) { 2712f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 2713f6f667cfSStefano Zampini } 2714f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 271508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 271608122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 271708122e43SStefano Zampini #endif 27189162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 27199162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 27209162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 272108122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 27229162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 272308122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 272408122e43SStefano Zampini 272508122e43SStefano Zampini maxneigs = 0; 272672b8c272SStefano Zampini cum = cumarray = 0; 27279162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 27289162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 2729d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 273008122e43SStefano Zampini const PetscInt *idxs; 273108122e43SStefano Zampini 2732d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 273308122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 273408122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 273508122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 273608122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 27379162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 27389162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 273908122e43SStefano Zampini } 2740d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 274108122e43SStefano Zampini } 274208122e43SStefano Zampini 274308122e43SStefano Zampini if (mss) { /* multilevel */ 274408122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 274508122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 274608122e43SStefano Zampini } 274708122e43SStefano Zampini 2748ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 274908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 275008122e43SStefano Zampini const PetscInt *idxs; 27519d54b7f4SStefano Zampini PetscReal upper,lower; 2752862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 275308122e43SStefano Zampini PetscBLASInt B_N; 2754aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 275508122e43SStefano Zampini 27569d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 27579d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 27589d54b7f4SStefano Zampini lower = thresh; 27599d54b7f4SStefano Zampini } else { 27609d54b7f4SStefano Zampini upper = 1./thresh; 27619d54b7f4SStefano Zampini lower = 0.; 27629d54b7f4SStefano Zampini } 2763862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 2764ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 2765f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 2766f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 27679ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 2768aff50787SStefano Zampini PetscInt j,k; 2769aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 2770aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 2771aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 277208122e43SStefano Zampini } 277308122e43SStefano Zampini for (j=0;j<subset_size;j++) { 2774aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 2775aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 2776aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 2777aff50787SStefano Zampini } 277808122e43SStefano Zampini } 277908122e43SStefano Zampini } else { 278008122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 278108122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 278208122e43SStefano Zampini } 27838bec7fa6SStefano Zampini } else { 2784f6f667cfSStefano Zampini S = Sarray + cumarray; 2785f6f667cfSStefano Zampini St = Starray + cumarray; 27868bec7fa6SStefano Zampini } 2787aff50787SStefano Zampini /* see if we can save some work */ 2788b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 2789aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 2790aff50787SStefano Zampini } 2791aff50787SStefano Zampini 2792b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 2793aff50787SStefano Zampini B_neigs = 0; 2794aff50787SStefano Zampini } else { 27959ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 279608122e43SStefano Zampini PetscBLASInt B_itype = 1; 2797f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 27984c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 27999552c7c7SStefano Zampini PetscInt nmin_s; 2800b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 280108122e43SStefano Zampini 2802fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 28038bec7fa6SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %d/%d %d %d.\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]); 2804fd14bc51SStefano Zampini } 2805d16cbb6bSStefano Zampini 2806b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 2807b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 2808b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 2809b7ab4a40SStefano Zampini } 2810b7ab4a40SStefano Zampini 281108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2812b7ab4a40SStefano Zampini if (compute_range) { 2813d16cbb6bSStefano Zampini 2814d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 281508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 28169d54b7f4SStefano 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)); 281708122e43SStefano Zampini #else 28189d54b7f4SStefano 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)); 281908122e43SStefano Zampini #endif 2820b7ab4a40SStefano Zampini } else if (!same_data) { 2821d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 2822d16cbb6bSStefano Zampini B_IL = 1; 2823d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 28249d54b7f4SStefano 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)); 2825d16cbb6bSStefano Zampini #else 28269d54b7f4SStefano 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)); 2827d16cbb6bSStefano Zampini #endif 2828b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 2829b7ab4a40SStefano Zampini PetscInt k; 2830b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 2831b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 2832b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 2833b7ab4a40SStefano Zampini nmin = nmax; 2834b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 2835b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 2836b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 2837b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 2838b7ab4a40SStefano Zampini } 2839d16cbb6bSStefano Zampini } 284008122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 284108122e43SStefano Zampini if (B_ierr) { 28426c4ed002SBarry 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); 28436c4ed002SBarry 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); 28446c4ed002SBarry 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); 284508122e43SStefano Zampini } 284608122e43SStefano Zampini 284708122e43SStefano Zampini if (B_neigs > nmax) { 2848fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2849fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 2850fd14bc51SStefano Zampini } 28519d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 285208122e43SStefano Zampini B_neigs = nmax; 285308122e43SStefano Zampini } 285408122e43SStefano Zampini 28559552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 28569552c7c7SStefano Zampini if (B_neigs < nmin_s) { 285708122e43SStefano Zampini PetscBLASInt B_neigs2; 285808122e43SStefano Zampini 28599d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2860f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 28619d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 28629d54b7f4SStefano Zampini } else { 28639d54b7f4SStefano Zampini B_IL = B_neigs + 1; 28649d54b7f4SStefano Zampini B_IU = nmin_s; 28659d54b7f4SStefano Zampini } 2866fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2867fd14bc51SStefano 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); 2868fd14bc51SStefano Zampini } 28699ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 28701ae86dd6SStefano Zampini PetscInt j,k; 287108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 28721ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 28731ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 28741ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 287508122e43SStefano Zampini } 287608122e43SStefano Zampini } 287708122e43SStefano Zampini } else { 287808122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 287908122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 288008122e43SStefano Zampini } 288108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 288208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 28839d54b7f4SStefano 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)); 288408122e43SStefano Zampini #else 28859d54b7f4SStefano 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)); 288608122e43SStefano Zampini #endif 288708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 288808122e43SStefano Zampini B_neigs += B_neigs2; 288908122e43SStefano Zampini } 289008122e43SStefano Zampini if (B_ierr) { 28916c4ed002SBarry 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); 28926c4ed002SBarry 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); 28936c4ed002SBarry 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); 289408122e43SStefano Zampini } 2895fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2896ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 289708122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 289808122e43SStefano Zampini if (eigs[j] == 0.0) { 2899ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 290008122e43SStefano Zampini } else { 29019d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2902ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 29039d54b7f4SStefano Zampini } else { 29049d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 29059d54b7f4SStefano Zampini } 2906fd14bc51SStefano Zampini } 290708122e43SStefano Zampini } 290808122e43SStefano Zampini } 290908122e43SStefano Zampini } else { 291008122e43SStefano Zampini /* TODO */ 291108122e43SStefano Zampini } 2912aff50787SStefano Zampini } 29136c3e6151SStefano Zampini /* change the basis back to the original one */ 29146c3e6151SStefano Zampini if (sub_schurs->change) { 291572b8c272SStefano Zampini Mat change,phi,phit; 29166c3e6151SStefano Zampini 29176c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 29186c3e6151SStefano Zampini PetscInt ii; 29196c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 29206c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 29216c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 2922684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2923684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 2924684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 2925684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2926684229deSStefano Zampini #else 29276c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 2928684229deSStefano Zampini #endif 29296c3e6151SStefano Zampini } 29306c3e6151SStefano Zampini } 29316c3e6151SStefano Zampini } 293272b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 29336c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 293472b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 29356c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 29366c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 29376c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 29386c3e6151SStefano Zampini } 29398bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 29408bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 29419162d606SStefano Zampini if (B_neigs) { 29429162d606SStefano 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); 2943fd14bc51SStefano Zampini 2944fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 29459552c7c7SStefano Zampini PetscInt ii; 29469552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 2947ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 29489552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 2949ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2950ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2951ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2952ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2953ac47001eSStefano Zampini #else 2954ac47001eSStefano 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); 2955ac47001eSStefano Zampini #endif 29569552c7c7SStefano Zampini } 29579552c7c7SStefano Zampini } 2958fd14bc51SStefano Zampini } 29599162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 29609162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 29619162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 29629162d606SStefano Zampini cum++; 296308122e43SStefano Zampini } 296408122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 296508122e43SStefano Zampini /* shift for next computation */ 296608122e43SStefano Zampini cumarray += subset_size*subset_size; 296708122e43SStefano Zampini } 2968fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2969fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2970fd14bc51SStefano Zampini } 297108122e43SStefano Zampini 297208122e43SStefano Zampini if (mss) { 297308122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 297408122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 2975f6f667cfSStefano Zampini /* destroy matrices (junk) */ 2976f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 2977f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 297808122e43SStefano Zampini } 2979f6f667cfSStefano Zampini if (allocated_S_St) { 2980f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 2981f6f667cfSStefano Zampini } 2982f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 298308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 298408122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 298508122e43SStefano Zampini #endif 298608122e43SStefano Zampini if (pcbddc->dbg_flag) { 29871b968477SStefano Zampini PetscInt maxneigs_r; 2988b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 29899b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 299008122e43SStefano Zampini } 299108122e43SStefano Zampini PetscFunctionReturn(0); 299208122e43SStefano Zampini } 2993b1b3d7a2SStefano Zampini 2994674ae819SStefano Zampini #undef __FUNCT__ 2995c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 2996c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 2997c8587f34SStefano Zampini { 29988629588bSStefano Zampini PetscScalar *coarse_submat_vals; 2999c8587f34SStefano Zampini PetscErrorCode ierr; 3000c8587f34SStefano Zampini 3001c8587f34SStefano Zampini PetscFunctionBegin; 3002f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 30035e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3004c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3005c8587f34SStefano Zampini 3006684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 30070fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3008684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3009c8587f34SStefano Zampini 30108629588bSStefano Zampini /* 30118629588bSStefano Zampini Setup local correction and local part of coarse basis. 30128629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 30138629588bSStefano Zampini */ 301447f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 30158629588bSStefano Zampini 30168629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 30178629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 30188629588bSStefano Zampini 30198629588bSStefano Zampini /* free */ 30208629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3021c8587f34SStefano Zampini PetscFunctionReturn(0); 3022c8587f34SStefano Zampini } 3023c8587f34SStefano Zampini 3024c8587f34SStefano Zampini #undef __FUNCT__ 3025674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 3026674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3027674ae819SStefano Zampini { 3028674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3029674ae819SStefano Zampini PetscErrorCode ierr; 3030674ae819SStefano Zampini 3031674ae819SStefano Zampini PetscFunctionBegin; 3032674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 303330368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3034674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3035785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3036674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3037f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3038f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3039785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 304063602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 304163602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3042674ae819SStefano Zampini PetscFunctionReturn(0); 3043674ae819SStefano Zampini } 3044674ae819SStefano Zampini 3045674ae819SStefano Zampini #undef __FUNCT__ 3046674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 3047674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3048674ae819SStefano Zampini { 3049674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 30504f1b2e48SStefano Zampini PetscInt i; 3051674ae819SStefano Zampini PetscErrorCode ierr; 3052674ae819SStefano Zampini 3053674ae819SStefano Zampini PetscFunctionBegin; 3054*1e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 3055*1e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3056a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3057b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3058674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 305916909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 30601dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3061674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3062669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3063fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 3064a13144ffSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 3065674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 30664f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 30674f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 30684f1b2e48SStefano Zampini } 30694f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3070b334f244SStefano Zampini if (pcbddc->sub_schurs) { 3071b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 3072b334f244SStefano Zampini } 3073c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 30748af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 3075674ae819SStefano Zampini PetscFunctionReturn(0); 3076674ae819SStefano Zampini } 3077674ae819SStefano Zampini 3078674ae819SStefano Zampini #undef __FUNCT__ 3079674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 3080674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3081674ae819SStefano Zampini { 3082674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3083674ae819SStefano Zampini PetscErrorCode ierr; 3084674ae819SStefano Zampini 3085674ae819SStefano Zampini PetscFunctionBegin; 3086674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 308758da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3088ca92afb2SStefano Zampini PetscScalar *array; 308906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 309006656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 309158da7f69SStefano Zampini } 3092674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3093674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 309415aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 309515aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3096674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3097674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3098674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 309906656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3100674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3101674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 31028ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3103674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3104674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3105674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 3106f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 3107f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 3108f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 3109f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3110727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 31110e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3112f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 311370cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 311481d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 31150369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 31161dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 31174f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 31188b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3119ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3120ca92afb2SStefano Zampini PetscInt i; 3121ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3122ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3123ca92afb2SStefano Zampini } 3124ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3125ca92afb2SStefano Zampini } 31264f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3127674ae819SStefano Zampini PetscFunctionReturn(0); 3128674ae819SStefano Zampini } 3129674ae819SStefano Zampini 3130674ae819SStefano Zampini #undef __FUNCT__ 3131f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 3132f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 31336bfb1811SStefano Zampini { 31346bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 31356bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 31366bfb1811SStefano Zampini VecType impVecType; 31374f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 31386bfb1811SStefano Zampini PetscErrorCode ierr; 31396bfb1811SStefano Zampini 31406bfb1811SStefano Zampini PetscFunctionBegin; 31416c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 3142e7b262bdSStefano Zampini /* get sizes */ 31434f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3144b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 31456bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3146e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3147e7b262bdSStefano Zampini /* R nodes */ 3148e7b262bdSStefano Zampini old_size = -1; 3149e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3150e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3151e7b262bdSStefano Zampini } 3152e7b262bdSStefano Zampini if (n_R != old_size) { 3153e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3154e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 31556bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 31566bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 31576bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 31586bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3159e7b262bdSStefano Zampini } 3160e7b262bdSStefano Zampini /* local primal dofs */ 3161e7b262bdSStefano Zampini old_size = -1; 3162e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3163e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3164e7b262bdSStefano Zampini } 3165e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3166e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 316783b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3168e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 31696bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3170e7b262bdSStefano Zampini } 3171e7b262bdSStefano Zampini /* local explicit constraints */ 3172e7b262bdSStefano Zampini old_size = -1; 3173e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3174e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3175e7b262bdSStefano Zampini } 3176e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3177e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 317883b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 317983b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 318083b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 318183b7ccabSStefano Zampini } 31826bfb1811SStefano Zampini PetscFunctionReturn(0); 31836bfb1811SStefano Zampini } 31846bfb1811SStefano Zampini 31856bfb1811SStefano Zampini #undef __FUNCT__ 318647f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 318747f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 318888ebb749SStefano Zampini { 318925084f0cSStefano Zampini PetscErrorCode ierr; 319025084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 319188ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 319288ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3193d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 319425084f0cSStefano Zampini /* submatrices of local problem */ 319580677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 319606656605SStefano Zampini /* submatrices of local coarse problem */ 319706656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 319825084f0cSStefano Zampini /* working matrices */ 319906656605SStefano Zampini Mat C_CR; 320025084f0cSStefano Zampini /* additional working stuff */ 320106656605SStefano Zampini PC pc_R; 32024f1b2e48SStefano Zampini Mat F; 32035cbda25cSStefano Zampini Vec dummy_vec; 3204a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 320525084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 320606656605SStefano Zampini PetscScalar *work; 320706656605SStefano Zampini PetscInt *idx_V_B; 3208ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 320906656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 3210ffd830a3SStefano Zampini 321125084f0cSStefano Zampini /* some shortcuts to scalars */ 321206656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 321388ebb749SStefano Zampini 321488ebb749SStefano Zampini PetscFunctionBegin; 32159a962809SStefano 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"); 3216ffd830a3SStefano Zampini 3217ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3218b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 32194f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3220b371cd4fSStefano Zampini n_B = pcis->n_B; 3221b371cd4fSStefano Zampini n_D = pcis->n - n_B; 322288ebb749SStefano Zampini n_R = pcis->n - n_vertices; 322388ebb749SStefano Zampini 322488ebb749SStefano Zampini /* vertices in boundary numbering */ 3225785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 32260e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 32276c4ed002SBarry 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); 322888ebb749SStefano Zampini 322906656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3230019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 323106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 323206656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 323306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 323406656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 323506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 323606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 323706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 323806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 323906656605SStefano Zampini 324006656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 324106656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 324206656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 324306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 324406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3245ffd830a3SStefano Zampini lda_rhs = n_R; 3246a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 324706656605SStefano Zampini if (isLU || isILU || isCHOL) { 324806656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3249b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3250df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3251d62866d3SStefano Zampini MatFactorType type; 3252d62866d3SStefano Zampini 3253df4d28bfSStefano Zampini F = reuse_solver->F; 32546816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3255d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 3256ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 325722db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 325806656605SStefano Zampini } else { 325906656605SStefano Zampini F = NULL; 326006656605SStefano Zampini } 326106656605SStefano Zampini 3262ffd830a3SStefano Zampini /* allocate workspace */ 3263ffd830a3SStefano Zampini n = 0; 3264ffd830a3SStefano Zampini if (n_constraints) { 3265ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3266ffd830a3SStefano Zampini } 3267ffd830a3SStefano Zampini if (n_vertices) { 3268ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3269ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3270ffd830a3SStefano Zampini } 3271ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3272ffd830a3SStefano Zampini 32735cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 32745cbda25cSStefano Zampini dummy_vec = NULL; 32755cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 32765cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 32775cbda25cSStefano Zampini } 32785cbda25cSStefano Zampini 327988ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 328088ebb749SStefano Zampini if (n_constraints) { 328172b8c272SStefano Zampini Mat M1,M2,M3,C_B; 328206656605SStefano Zampini IS is_aux; 328380677318SStefano Zampini PetscScalar *array,*array2; 328406656605SStefano Zampini 3285f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 328680677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 328788ebb749SStefano Zampini 328825084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 328925084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 32908ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 329172b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 329288ebb749SStefano Zampini 329380677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 329480677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 3295ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 329688ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 329706656605SStefano Zampini const PetscScalar *row_cmat_values; 329806656605SStefano Zampini const PetscInt *row_cmat_indices; 329906656605SStefano Zampini PetscInt size_of_constraint,j; 330088ebb749SStefano Zampini 330106656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 330206656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 3303ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 330406656605SStefano Zampini } 330506656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 330606656605SStefano Zampini } 3307ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 330806656605SStefano Zampini if (F) { 330906656605SStefano Zampini Mat B; 331006656605SStefano Zampini 3311ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 3312a3df083aSStefano Zampini if (need_benign_correction) { 3313df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3314a3df083aSStefano Zampini 331572b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 331672b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 3317a3df083aSStefano Zampini } 331880677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 3319a3df083aSStefano Zampini if (need_benign_correction) { 3320a3df083aSStefano Zampini PetscScalar *marr; 3321df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3322a3df083aSStefano Zampini 3323a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 33245cbda25cSStefano Zampini if (lda_rhs != n_R) { 33255cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 33265cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 33275cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 33285cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 33295cbda25cSStefano Zampini } 33305cbda25cSStefano Zampini } else { 3331a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 3332a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 33335cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3334a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3335a3df083aSStefano Zampini } 33365cbda25cSStefano Zampini } 3337a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 3338a3df083aSStefano Zampini } 333906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 334006656605SStefano Zampini } else { 334180677318SStefano Zampini PetscScalar *marr; 334280677318SStefano Zampini 334380677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 334406656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3345ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3346ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 334706656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 334806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 334906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 335006656605SStefano Zampini } 335180677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 335206656605SStefano Zampini } 335380677318SStefano Zampini if (!pcbddc->switch_static) { 335480677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 335580677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 335680677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 335780677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3358ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 335980677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 336080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 336180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 336280677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 336380677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 336480677318SStefano Zampini } 336580677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 336680677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 336772b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 336880677318SStefano Zampini } else { 3369ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3370ffd830a3SStefano Zampini IS dummy; 3371ffd830a3SStefano Zampini 3372ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 337372b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3374ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3375ffd830a3SStefano Zampini } else { 337680677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 337780677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3378ffd830a3SStefano Zampini } 337925084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 338080677318SStefano Zampini } 338180677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 338280677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 338380677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 338406656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 338506656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 338680677318SStefano Zampini if (isCHOL) { 338780677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 338880677318SStefano Zampini } else { 338925084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 339080677318SStefano Zampini } 339180677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 339206656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 339325084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 339425084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 339525084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 339680677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 339772b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 339872b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 339906656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 340006656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 3401f4ddd8eeSStefano Zampini } 3402fc227af8SStefano Zampini 3403fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 340488ebb749SStefano Zampini if (n_vertices) { 340506656605SStefano Zampini IS is_aux; 34063a50541eSStefano Zampini 3407b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 34086816873aSStefano Zampini IS tis; 34096816873aSStefano Zampini 34106816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 34116816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 34126816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 34136816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 34146816873aSStefano Zampini } else { 34153a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 34166816873aSStefano Zampini } 34179577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 34189577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 341904708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 342025084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 342188ebb749SStefano Zampini } 342288ebb749SStefano Zampini 342388ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 3424f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 342506656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 342606656605SStefano Zampini if (pcbddc->coarse_phi_D) { 342706656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 342806656605SStefano Zampini } 3429f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 343006656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 343106656605SStefano Zampini PetscScalar *marray; 343206656605SStefano Zampini 343306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 343406656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 3435f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3436f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3437f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3438f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3439f4ddd8eeSStefano Zampini } 3440f4ddd8eeSStefano Zampini } 344106656605SStefano Zampini 3442f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 344306656605SStefano Zampini PetscScalar *marray; 344488ebb749SStefano Zampini 344506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 34468eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 344706656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 344888ebb749SStefano Zampini } 34493301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 345006656605SStefano Zampini n *= 2; 345188ebb749SStefano Zampini } 345206656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 345306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 345406656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 34558eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 345606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 345706656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 345888ebb749SStefano Zampini } 34593301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 346006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 34618eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 346206656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 346306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 346488ebb749SStefano Zampini } 346588ebb749SStefano Zampini } else { 3466c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 3467c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 34681b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3469c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 3470c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 3471c0553b1fSStefano Zampini } 347288ebb749SStefano Zampini } 347306656605SStefano Zampini } 3474019a44ceSStefano Zampini 347506656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 34764f1b2e48SStefano Zampini p0_lidx_I = NULL; 34774f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 3478d12edf2fSStefano Zampini const PetscInt *idxs; 3479d12edf2fSStefano Zampini 3480d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 34814f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 34824f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 34834f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 34844f1b2e48SStefano Zampini } 3485d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 3486d12edf2fSStefano Zampini } 3487d16cbb6bSStefano Zampini 348806656605SStefano Zampini /* vertices */ 348906656605SStefano Zampini if (n_vertices) { 349016f15bc4SStefano Zampini 3491af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 349204708bb6SStefano Zampini 349316f15bc4SStefano Zampini if (n_R) { 349414393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 349506656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 349616f15bc4SStefano Zampini PetscScalar *x,*y; 349704708bb6SStefano Zampini PetscBool isseqaij; 349806656605SStefano Zampini 349921eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 350014393ed6SStefano Zampini if (need_benign_correction) { 350114393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 350214393ed6SStefano Zampini IS is_p0; 350314393ed6SStefano Zampini PetscInt *idxs_p0,n; 350414393ed6SStefano Zampini 350514393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 350614393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 350714393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 3508af25d912SStefano 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); 350914393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 351014393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 351114393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 351214393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 351314393ed6SStefano Zampini } 351414393ed6SStefano Zampini 3515ffd830a3SStefano Zampini if (lda_rhs == n_R) { 3516af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3517ffd830a3SStefano Zampini } else { 3518ca92afb2SStefano Zampini PetscScalar *av,*array; 3519ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 3520ca92afb2SStefano Zampini PetscInt n; 3521ca92afb2SStefano Zampini PetscBool flg_row; 3522ffd830a3SStefano Zampini 3523ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 3524ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 35259d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3526ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3527ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 3528ca92afb2SStefano Zampini for (i=0;i<n;i++) { 3529ca92afb2SStefano Zampini PetscInt j; 3530ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 3531ffd830a3SStefano Zampini } 3532ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3533ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3534ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 3535ffd830a3SStefano Zampini } 3536ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3537a3df083aSStefano Zampini if (need_benign_correction) { 3538df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3539a3df083aSStefano Zampini PetscScalar *marr; 3540a3df083aSStefano Zampini 3541a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 354214393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 354314393ed6SStefano Zampini 354414393ed6SStefano Zampini | 0 0 0 | (V) 354514393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 354614393ed6SStefano Zampini | 0 0 -1 | (p0) 354714393ed6SStefano Zampini 354814393ed6SStefano Zampini */ 3549df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 355014393ed6SStefano Zampini const PetscScalar *vals; 355114393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 355214393ed6SStefano Zampini PetscInt n,j,nz; 355314393ed6SStefano Zampini 3554df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3555df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 355614393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 355714393ed6SStefano Zampini for (j=0;j<n;j++) { 355814393ed6SStefano Zampini PetscScalar val = vals[j]; 355914393ed6SStefano Zampini PetscInt k,col = idxs[j]; 356014393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 356114393ed6SStefano Zampini } 356214393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3563df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 356414393ed6SStefano Zampini } 356572b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 356672b8c272SStefano Zampini } 356772b8c272SStefano Zampini if (F) { 356814393ed6SStefano Zampini /* need to correct the rhs */ 356972b8c272SStefano Zampini if (need_benign_correction) { 357072b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 357172b8c272SStefano Zampini PetscScalar *marr; 357272b8c272SStefano Zampini 357372b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 35745cbda25cSStefano Zampini if (lda_rhs != n_R) { 35755cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 35765cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 35775cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 35785cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 35795cbda25cSStefano Zampini } 35805cbda25cSStefano Zampini } else { 3581a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3582a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 35835cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3584a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3585a3df083aSStefano Zampini } 35865cbda25cSStefano Zampini } 3587a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 3588a3df083aSStefano Zampini } 358906656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 359014393ed6SStefano Zampini /* need to correct the solution */ 3591a3df083aSStefano Zampini if (need_benign_correction) { 3592df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3593a3df083aSStefano Zampini PetscScalar *marr; 3594a3df083aSStefano Zampini 3595a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 35965cbda25cSStefano Zampini if (lda_rhs != n_R) { 35975cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 35985cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 35995cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 36005cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 36015cbda25cSStefano Zampini } 36025cbda25cSStefano Zampini } else { 3603a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3604a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 36055cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3606a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3607a3df083aSStefano Zampini } 36085cbda25cSStefano Zampini } 3609a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 3610a3df083aSStefano Zampini } 361106656605SStefano Zampini } else { 361206656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 361306656605SStefano Zampini for (i=0;i<n_vertices;i++) { 3614ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 3615ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 361606656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 361706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 361806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 361906656605SStefano Zampini } 362006656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 362106656605SStefano Zampini } 362280677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3623ffd830a3SStefano Zampini /* S_VV and S_CV */ 362406656605SStefano Zampini if (n_constraints) { 362506656605SStefano Zampini Mat B; 362680677318SStefano Zampini 3627ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 362880677318SStefano Zampini for (i=0;i<n_vertices;i++) { 3629ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3630ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 363180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 363280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 363380677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 363480677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 363580677318SStefano Zampini } 3636ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 363780677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 363880677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 3639ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 364080677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 364106656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 3642ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 3643ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 364406656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 364506656605SStefano Zampini } 364604708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 364704708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 3648511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 364904708bb6SStefano Zampini } 3650ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3651ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 3652ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3653ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 3654ffd830a3SStefano Zampini } 365506656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 365614393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 365714393ed6SStefano Zampini if (need_benign_correction) { 3658df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 365914393ed6SStefano Zampini PetscScalar *marr,*sums; 366014393ed6SStefano Zampini 366114393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 3662f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 3663df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 366414393ed6SStefano Zampini const PetscScalar *vals; 366514393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 366614393ed6SStefano Zampini PetscInt n,j,nz; 366714393ed6SStefano Zampini 3668df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3669df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 367014393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 367114393ed6SStefano Zampini PetscInt k; 367214393ed6SStefano Zampini sums[j] = 0.; 367314393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 367414393ed6SStefano Zampini } 367514393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 367614393ed6SStefano Zampini for (j=0;j<n;j++) { 367714393ed6SStefano Zampini PetscScalar val = vals[j]; 367814393ed6SStefano Zampini PetscInt k; 367914393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 368014393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 368114393ed6SStefano Zampini } 368214393ed6SStefano Zampini } 368314393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3684df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 368514393ed6SStefano Zampini } 368614393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 3687f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 368814393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 368914393ed6SStefano Zampini } 369080677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 369106656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 369206656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 369306656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 369406656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 369506656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 369606656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 369706656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3698d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 3699019a44ceSStefano Zampini } else { 3700d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3701d16cbb6bSStefano Zampini } 370221eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 3703d16cbb6bSStefano Zampini 370406656605SStefano Zampini /* coarse basis functions */ 370506656605SStefano Zampini for (i=0;i<n_vertices;i++) { 370616f15bc4SStefano Zampini PetscScalar *y; 370716f15bc4SStefano Zampini 3708ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 370906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 371006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 371106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 371206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 371306656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 371406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 371506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 371606656605SStefano Zampini 371706656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 37184f1b2e48SStefano Zampini PetscInt j; 37194f1b2e48SStefano Zampini 372006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 372106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 372206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 372306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 372406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 37254f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 372606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 372706656605SStefano Zampini } 372806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 372906656605SStefano Zampini } 373004708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 373104708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 373206656605SStefano Zampini } 37335cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 373406656605SStefano Zampini 373506656605SStefano Zampini if (n_constraints) { 373606656605SStefano Zampini Mat B; 373706656605SStefano Zampini 3738ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 373906656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 374080677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 374106656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 374206656605SStefano Zampini if (n_vertices) { 374380677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 374480677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 374580677318SStefano Zampini } else { 374680677318SStefano Zampini Mat S_VCt; 374780677318SStefano Zampini 3748ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3749ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 375072b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 3751ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 3752ffd830a3SStefano Zampini } 375380677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 375480677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 375580677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 375680677318SStefano Zampini } 375706656605SStefano Zampini } 375806656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 375906656605SStefano Zampini /* coarse basis functions */ 376006656605SStefano Zampini for (i=0;i<n_constraints;i++) { 376106656605SStefano Zampini PetscScalar *y; 376206656605SStefano Zampini 3763ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 376406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 376506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 376606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 376706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 376806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 376906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 377006656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 37714f1b2e48SStefano Zampini PetscInt j; 37724f1b2e48SStefano Zampini 377306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 377406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 377506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 377606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 377706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 37784f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 377906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 378006656605SStefano Zampini } 378106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 378206656605SStefano Zampini } 378306656605SStefano Zampini } 378480677318SStefano Zampini if (n_constraints) { 378580677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 378680677318SStefano Zampini } 37874f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 378872b8c272SStefano Zampini 378972b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 379072b8c272SStefano Zampini if (pcbddc->benign_n) { 379172b8c272SStefano Zampini Mat B0_B,B0_BPHI; 379272b8c272SStefano Zampini IS is_dummy; 379372b8c272SStefano Zampini PetscScalar *data; 379472b8c272SStefano Zampini PetscInt j; 379572b8c272SStefano Zampini 379672b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 379772b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 379872b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 379972b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 380086c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 380172b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 380272b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 380372b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 380472b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 380572b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 380672b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 380772b8c272SStefano Zampini } 380872b8c272SStefano Zampini } 380972b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 381072b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 381172b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 381272b8c272SStefano Zampini } 3813019a44ceSStefano Zampini 381406656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 38153301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3816ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 3817ffd830a3SStefano Zampini PetscScalar *marray; 381806656605SStefano Zampini 381906656605SStefano Zampini if (n_constraints) { 3820ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 382106656605SStefano Zampini 3822af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 382306656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 3824ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 382516f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 382606656605SStefano Zampini if (n_vertices) { 3827ffd830a3SStefano Zampini Mat S_VCT; 382806656605SStefano Zampini 382906656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 3830ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 383116f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 383206656605SStefano Zampini } 3833ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 38345b782168SStefano Zampini } else { 38355b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 383606656605SStefano Zampini } 383716f15bc4SStefano Zampini if (n_vertices && n_R) { 3838ffd830a3SStefano Zampini PetscScalar *av,*marray; 3839ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 3840ffd830a3SStefano Zampini PetscInt n; 3841ffd830a3SStefano Zampini PetscBool flg_row; 384206656605SStefano Zampini 3843ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 3844af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3845ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3846ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 3847ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3848ffd830a3SStefano Zampini for (i=0;i<n;i++) { 3849ffd830a3SStefano Zampini PetscInt j; 3850ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 3851ffd830a3SStefano Zampini } 3852ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 3853ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3854ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 385506656605SStefano Zampini } 385606656605SStefano Zampini 3857ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 3858ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3859ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 3860ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 3861ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 386206656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 386306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 386406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 386506656605SStefano Zampini } 3866ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 38675b782168SStefano Zampini if (B_C) { 3868ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 3869ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 3870ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 3871ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 3872ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 3873ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3874ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 387506656605SStefano Zampini } 3876ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 38775b782168SStefano Zampini } 387806656605SStefano Zampini /* coarse basis functions */ 387906656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 388006656605SStefano Zampini PetscScalar *y; 388106656605SStefano Zampini 3882ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 388306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 388406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 388506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 388606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 388706656605SStefano Zampini if (i<n_vertices) { 388806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 388906656605SStefano Zampini } 389006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 389106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 389206656605SStefano Zampini 389306656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 389406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 389506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 389606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 389706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 389806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 389906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 390006656605SStefano Zampini } 390106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 390206656605SStefano Zampini } 3903ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 3904ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 390506656605SStefano Zampini } 3906d62866d3SStefano Zampini /* free memory */ 390788ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 390806656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 390906656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 391006656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 391106656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 3912d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3913d62866d3SStefano Zampini if (n_vertices) { 3914d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 3915d62866d3SStefano Zampini } 3916d62866d3SStefano Zampini if (n_constraints) { 3917d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 3918d62866d3SStefano Zampini } 391988ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 392088ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 392188ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 3922d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 392388ebb749SStefano Zampini Mat coarse_sub_mat; 392425084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 392588ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 392688ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 392788ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 39288bec7fa6SStefano Zampini Mat C_B,CPHI; 39298bec7fa6SStefano Zampini IS is_dummy; 39308bec7fa6SStefano Zampini Vec mones; 393188ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 393288ebb749SStefano Zampini PetscReal real_value; 393388ebb749SStefano Zampini 3934a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 3935a3df083aSStefano Zampini Mat A; 3936a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 3937a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 3938a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 3939a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 3940a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3941a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 3942a3df083aSStefano Zampini } else { 394388ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 394488ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 394588ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 394688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3947a3df083aSStefano Zampini } 394888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 394988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 3950ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 395188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 395288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 395388ebb749SStefano Zampini } 395488ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 395588ebb749SStefano Zampini 395625084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 39573301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 395825084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3959ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 396088ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 396188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 396288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 396388ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 396488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 396588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 396688ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 396788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 396888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 396988ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 397088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 397188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 397288ebb749SStefano Zampini } else { 397388ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 397488ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 397588ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 397688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 397788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 397888ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 397988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 398088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 398188ebb749SStefano Zampini } 398288ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 398388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 398488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 3985511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 39864f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3987fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 3988d12edf2fSStefano Zampini PetscScalar *data,*data2; 39894f1b2e48SStefano Zampini PetscInt j; 3990d12edf2fSStefano Zampini 39914f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 3992fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 3993d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 399486c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 3995d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 3996d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 39974f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 39984f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 3999d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 40004f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 40014f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 40024f1b2e48SStefano Zampini } 4003d12edf2fSStefano Zampini } 4004d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 4005d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 4006d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4007d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4008d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4009d12edf2fSStefano Zampini } 4010d12edf2fSStefano Zampini #if 0 4011d12edf2fSStefano Zampini { 4012d12edf2fSStefano Zampini PetscViewer viewer; 4013d12edf2fSStefano Zampini char filename[256]; 4014ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4015d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4016d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4017ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4018ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4019ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4020d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 402172b8c272SStefano Zampini if (save_change) { 402272b8c272SStefano Zampini Mat phi_B; 402372b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 402472b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 402572b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 402672b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 402772b8c272SStefano Zampini } else { 4028ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4029ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 403072b8c272SStefano Zampini } 4031ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4032ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4033ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4034ffd830a3SStefano Zampini } 4035ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4036ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4037ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4038ffd830a3SStefano Zampini } 403972b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4040ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4041ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4042ffd830a3SStefano Zampini } 4043d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4044d12edf2fSStefano Zampini } 4045d12edf2fSStefano Zampini #endif 404681d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 40478bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 40481575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 404906656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 40508bec7fa6SStefano Zampini 40518bec7fa6SStefano Zampini /* check constraints */ 4052a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 4053a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 40544f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 40558bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4056a00504b5SStefano Zampini } else { 4057a00504b5SStefano Zampini PetscScalar *data; 4058a00504b5SStefano Zampini Mat tmat; 4059a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4060a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4061a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4062a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4063a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4064a00504b5SStefano Zampini } 40658bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 40668bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 40678bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 40688bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4069bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4070ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4071bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4072bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4073bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4074bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4075bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 407688ebb749SStefano Zampini } 40778bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 40788bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 40798bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 40808bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 408125084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 408288ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 408388ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 408488ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 408588ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 408688ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 408788ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 408888ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 408988ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 409088ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 409188ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4092ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 409388ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 409488ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 409588ebb749SStefano Zampini } 409688ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 409788ebb749SStefano Zampini } 40988629588bSStefano Zampini /* get back data */ 40998629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 410088ebb749SStefano Zampini PetscFunctionReturn(0); 410188ebb749SStefano Zampini } 410288ebb749SStefano Zampini 410388ebb749SStefano Zampini #undef __FUNCT__ 4104d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 4105d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4106aa0d41d4SStefano Zampini { 4107d65f70fdSStefano Zampini Mat *work_mat; 4108d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4109d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4110c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4111aa0d41d4SStefano Zampini PetscErrorCode ierr; 4112aa0d41d4SStefano Zampini 4113aa0d41d4SStefano Zampini PetscFunctionBegin; 4114d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4115d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4116d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4117d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4118aa0d41d4SStefano Zampini 4119d65f70fdSStefano Zampini if (!rsorted) { 4120906d46d4SStefano Zampini const PetscInt *idxs; 4121906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4122aa0d41d4SStefano Zampini 4123d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4124d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4125d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4126d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4127aa0d41d4SStefano Zampini } 4128d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4129d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4130d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4131d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4132aa0d41d4SStefano Zampini } 4133d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4134d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4135d65f70fdSStefano Zampini } else { 4136d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4137d65f70fdSStefano Zampini isrow_s = isrow; 4138aa0d41d4SStefano Zampini } 4139906d46d4SStefano Zampini 4140d65f70fdSStefano Zampini if (!csorted) { 4141d65f70fdSStefano Zampini if (isrow == iscol) { 4142d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4143d65f70fdSStefano Zampini iscol_s = isrow_s; 4144d65f70fdSStefano Zampini } else { 4145d65f70fdSStefano Zampini const PetscInt *idxs; 4146d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4147906d46d4SStefano Zampini 4148d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4149d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4150d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4151d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4152d65f70fdSStefano Zampini } 4153d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4154d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4155d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4156d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4157d65f70fdSStefano Zampini } 4158d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4159d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4160d65f70fdSStefano Zampini } 4161d65f70fdSStefano Zampini } else { 4162d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4163d65f70fdSStefano Zampini iscol_s = iscol; 4164d65f70fdSStefano Zampini } 4165d65f70fdSStefano Zampini 4166d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4167d65f70fdSStefano Zampini 4168d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4169906d46d4SStefano Zampini Mat new_mat; 4170d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4171906d46d4SStefano Zampini 4172d65f70fdSStefano Zampini if (!rsorted) { 4173d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4174d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4175d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4176d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4177906d46d4SStefano Zampini } 4178d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4179d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 4180d65f70fdSStefano Zampini } else { 4181d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 4182906d46d4SStefano Zampini } 4183d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 4184d65f70fdSStefano Zampini 4185d65f70fdSStefano Zampini if (!csorted) { 4186d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 4187d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 4188d65f70fdSStefano Zampini is_perm_c = is_perm_r; 4189d65f70fdSStefano Zampini } else { 4190d65f70fdSStefano Zampini PetscInt *idxs_c,i; 4191f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 4192d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 4193d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4194d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 4195d65f70fdSStefano Zampini } 4196d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 4197d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 4198d65f70fdSStefano Zampini } 4199d65f70fdSStefano Zampini } else { 4200d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 4201d65f70fdSStefano Zampini } 4202d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 4203d65f70fdSStefano Zampini 4204d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 4205d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 4206d65f70fdSStefano Zampini work_mat[0] = new_mat; 4207d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 4208d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 4209d65f70fdSStefano Zampini } 4210d65f70fdSStefano Zampini 4211d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 4212d65f70fdSStefano Zampini *B = work_mat[0]; 4213d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 4214d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 4215d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 4216d65f70fdSStefano Zampini PetscFunctionReturn(0); 4217d65f70fdSStefano Zampini } 4218d65f70fdSStefano Zampini 4219d65f70fdSStefano Zampini #undef __FUNCT__ 42205e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 42215e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 4222aa0d41d4SStefano Zampini { 4223aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 42245e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4225d65f70fdSStefano Zampini Mat new_mat; 42265e8657edSStefano Zampini IS is_local,is_global; 4227d65f70fdSStefano Zampini PetscInt local_size; 4228d65f70fdSStefano Zampini PetscBool isseqaij; 4229aa0d41d4SStefano Zampini PetscErrorCode ierr; 4230aa0d41d4SStefano Zampini 4231aa0d41d4SStefano Zampini PetscFunctionBegin; 4232aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 42335e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 42345e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 4235b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 4236aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 4237d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 4238aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 4239906d46d4SStefano Zampini 4240906d46d4SStefano Zampini /* check */ 4241906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4242906d46d4SStefano Zampini Vec x,x_change; 4243906d46d4SStefano Zampini PetscReal error; 4244906d46d4SStefano Zampini 42455e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 4246906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 42475e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 4248e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4249e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4250d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 425188428137SStefano Zampini if (!pcbddc->change_interior) { 425288428137SStefano Zampini const PetscScalar *x,*y,*v; 425388428137SStefano Zampini PetscReal lerror = 0.; 425488428137SStefano Zampini PetscInt i; 425588428137SStefano Zampini 425688428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 425788428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 425888428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 425988428137SStefano Zampini for (i=0;i<local_size;i++) 426088428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 426188428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 426288428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 426388428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 426488428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 426588428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 426688428137SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on I: %1.6e\n",error);CHKERRQ(ierr); 426788428137SStefano Zampini } 4268e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4269e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4270906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4271906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4272906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4273906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 4274906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4275906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4276906d46d4SStefano Zampini } 4277906d46d4SStefano Zampini 427822d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 42799b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 428022d5777bSStefano Zampini if (isseqaij) { 4281a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4282a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 4283aa0d41d4SStefano Zampini } else { 4284a00504b5SStefano Zampini Mat work_mat; 42851cf9b237SStefano Zampini 4286a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4287aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4288a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 42891d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 4290aa0d41d4SStefano Zampini } 42913301b35fSStefano Zampini if (matis->A->symmetric_set) { 42923301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 4293e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 42943301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 4295e496cd5dSStefano Zampini #endif 42963301b35fSStefano Zampini } 4297d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 4298aa0d41d4SStefano Zampini PetscFunctionReturn(0); 4299aa0d41d4SStefano Zampini } 4300aa0d41d4SStefano Zampini 4301aa0d41d4SStefano Zampini #undef __FUNCT__ 4302a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 43038ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 4304a64d13efSStefano Zampini { 4305a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4306a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4307d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 430853892102SStefano Zampini PetscInt *idx_R_local=NULL; 43093a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 43103a50541eSStefano Zampini PetscInt vbs,bs; 43116816873aSStefano Zampini PetscBT bitmask=NULL; 4312a64d13efSStefano Zampini PetscErrorCode ierr; 4313a64d13efSStefano Zampini 4314a64d13efSStefano Zampini PetscFunctionBegin; 4315b23d619eSStefano Zampini /* 4316b23d619eSStefano Zampini No need to setup local scatters if 4317b23d619eSStefano Zampini - primal space is unchanged 4318b23d619eSStefano Zampini AND 4319b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 4320b23d619eSStefano Zampini AND 4321b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 4322b23d619eSStefano Zampini */ 4323b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 4324f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 4325f4ddd8eeSStefano Zampini } 4326f4ddd8eeSStefano Zampini /* destroy old objects */ 4327f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 4328f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 4329f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 4330a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 4331b371cd4fSStefano Zampini n_B = pcis->n_B; 4332b371cd4fSStefano Zampini n_D = pcis->n - n_B; 4333b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 43343a50541eSStefano Zampini 4335a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 43366816873aSStefano Zampini 433753892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 4338b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4339854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 4340a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 4341a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 43420e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 4343a64d13efSStefano Zampini } 4344a64d13efSStefano Zampini 4345a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 43464641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 43476816873aSStefano Zampini idx_R_local[n_R++] = i; 4348a64d13efSStefano Zampini } 4349a64d13efSStefano Zampini } 4350df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 4351df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 43526816873aSStefano Zampini 4353df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4354df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 43556816873aSStefano Zampini } 43563a50541eSStefano Zampini 43573a50541eSStefano Zampini /* Block code */ 43583a50541eSStefano Zampini vbs = 1; 43593a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 43603a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 43613a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 43623a50541eSStefano Zampini PetscInt *vary; 4363b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4364785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 43653a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 4366d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 4367d3df7717SStefano 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 */ 43680e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 4369d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 43703a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 43713a50541eSStefano Zampini is_blocked = PETSC_FALSE; 43723a50541eSStefano Zampini break; 43733a50541eSStefano Zampini } 43743a50541eSStefano Zampini } 4375d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 4376d3df7717SStefano Zampini } else { 4377d3df7717SStefano Zampini /* Verify directly the R set */ 4378d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 4379d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 4380d3df7717SStefano Zampini for (j=1; j<bs; j++) { 4381d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 4382d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 4383d3df7717SStefano Zampini break; 4384d3df7717SStefano Zampini } 4385d3df7717SStefano Zampini } 4386d3df7717SStefano Zampini } 4387d3df7717SStefano Zampini } 43883a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 43893a50541eSStefano Zampini vbs = bs; 43903a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 43913a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 43923a50541eSStefano Zampini } 43933a50541eSStefano Zampini } 43943a50541eSStefano Zampini } 43953a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 4396b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4397df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 439853892102SStefano Zampini 4399df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4400df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 440153892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 4402df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 440353892102SStefano Zampini } else { 44043a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 440553892102SStefano Zampini } 4406a64d13efSStefano Zampini 4407a64d13efSStefano Zampini /* print some info if requested */ 4408a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 4409a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4410a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 44111575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4412a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 4413a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 44144f1b2e48SStefano 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); 4415a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4416a64d13efSStefano Zampini } 4417a64d13efSStefano Zampini 4418a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 4419b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 44206816873aSStefano Zampini IS is_aux1,is_aux2; 44216816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 44226816873aSStefano Zampini 44233a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4424854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 4425854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 4426a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 44274641a718SStefano Zampini for (i=0; i<n_D; i++) { 44284641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 44294641a718SStefano Zampini } 4430a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4431a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 44324641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 44334641a718SStefano Zampini aux_array1[j++] = i; 4434a64d13efSStefano Zampini } 4435a64d13efSStefano Zampini } 4436a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4437a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4438a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 44394641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 44404641a718SStefano Zampini aux_array2[j++] = i; 4441a64d13efSStefano Zampini } 4442a64d13efSStefano Zampini } 4443a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4444a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 4445a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 4446a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4447a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 4448a64d13efSStefano Zampini 44498eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4450785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 4451a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 44524641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 44534641a718SStefano Zampini aux_array1[j++] = i; 4454a64d13efSStefano Zampini } 4455a64d13efSStefano Zampini } 4456a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4457a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 4458a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4459a64d13efSStefano Zampini } 44604641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 44613a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4462d62866d3SStefano Zampini } else { 4463df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 44646816873aSStefano Zampini IS tis; 44656816873aSStefano Zampini PetscInt schur_size; 44666816873aSStefano Zampini 4467df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 44686816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 4469df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 44706816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 44716816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 44726816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 44736816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 44746816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 4475d62866d3SStefano Zampini } 4476d62866d3SStefano Zampini } 4477a64d13efSStefano Zampini PetscFunctionReturn(0); 4478a64d13efSStefano Zampini } 4479a64d13efSStefano Zampini 4480304d26faSStefano Zampini 4481304d26faSStefano Zampini #undef __FUNCT__ 4482304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 4483684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 4484304d26faSStefano Zampini { 4485304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4486304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4487304d26faSStefano Zampini PC pc_temp; 4488304d26faSStefano Zampini Mat A_RR; 4489f4ddd8eeSStefano Zampini MatReuse reuse; 4490304d26faSStefano Zampini PetscScalar m_one = -1.0; 4491304d26faSStefano Zampini PetscReal value; 449204708bb6SStefano Zampini PetscInt n_D,n_R; 4493c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 4494304d26faSStefano Zampini PetscErrorCode ierr; 4495e604994aSStefano Zampini /* prefixes stuff */ 4496312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 4497e604994aSStefano Zampini size_t len; 4498304d26faSStefano Zampini 4499304d26faSStefano Zampini PetscFunctionBegin; 4500304d26faSStefano Zampini 4501e604994aSStefano Zampini /* compute prefixes */ 4502e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 4503e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 4504e604994aSStefano Zampini if (!pcbddc->current_level) { 4505e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4506e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4507e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4508e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4509e604994aSStefano Zampini } else { 4510e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4511312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4512e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4513e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 4514312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4515312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 451634d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 451734d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4518e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4519e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4520e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 4521e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 4522e604994aSStefano Zampini } 4523e604994aSStefano Zampini 4524304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 4525684f6988SStefano Zampini if (dirichlet) { 4526d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4527450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 45289a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 4529450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 4530a3df083aSStefano Zampini Mat A_IIn; 4531a3df083aSStefano Zampini 4532a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 4533a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 4534a3df083aSStefano Zampini pcis->A_II = A_IIn; 4535a3df083aSStefano Zampini } 4536450f8f5eSStefano Zampini } 45373301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 45383301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 4539964fefecSStefano Zampini } 4540ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 4541964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 4542304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 4543304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 4544304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 4545304d26faSStefano Zampini /* default */ 4546304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 4547e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 45489577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 4549304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 45509577ea80SStefano Zampini if (issbaij) { 45519577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 45529577ea80SStefano Zampini } else { 4553304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 45549577ea80SStefano Zampini } 4555304d26faSStefano Zampini /* Allow user's customization */ 4556304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 4557304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4558304d26faSStefano Zampini } 4559d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 4560b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4561df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4562d62866d3SStefano Zampini 4563df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 4564d5574798SStefano Zampini } 4565304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4566304d26faSStefano Zampini if (!n_D) { 4567304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 4568304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4569304d26faSStefano Zampini } 4570304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 4571304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 4572304d26faSStefano Zampini /* set ksp_D into pcis data */ 4573304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 4574304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 4575304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 4576684f6988SStefano Zampini } 4577304d26faSStefano Zampini 4578304d26faSStefano Zampini /* NEUMANN PROBLEM */ 4579684f6988SStefano Zampini A_RR = 0; 4580684f6988SStefano Zampini if (neumann) { 4581d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 458204708bb6SStefano Zampini PetscInt ibs,mbs; 458304708bb6SStefano Zampini PetscBool issbaij; 458404708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4585f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 45868ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 4587f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 4588f4ddd8eeSStefano Zampini PetscInt nn_R; 458981d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 4590f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4591f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 4592f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 4593f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 4594f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4595f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4596f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 4597727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 4598f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4599f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4600f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 4601f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 4602f4ddd8eeSStefano Zampini } 4603f4ddd8eeSStefano Zampini } 4604f4ddd8eeSStefano Zampini /* last check */ 4605d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 4606f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4607f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4608f4ddd8eeSStefano Zampini } 4609f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 4610f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4611f4ddd8eeSStefano Zampini } 4612a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 4613af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 4614af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 461504708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 461604708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 461704708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 461804708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 461904708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 4620af732b37SStefano Zampini } else { 4621511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 46226816873aSStefano Zampini } 462304708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 462404708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 462504708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 462604708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 462704708bb6SStefano Zampini } else { 4628511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 462904708bb6SStefano Zampini } 463004708bb6SStefano Zampini } 4631a00504b5SStefano Zampini /* extract A_RR */ 4632b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4633a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4634a00504b5SStefano Zampini 4635a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 463616e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4637a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 463816e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 463916e386b8SStefano Zampini } else { 4640a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 4641a00504b5SStefano Zampini } 4642a00504b5SStefano Zampini } else { 4643a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4644a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 4645a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4646a00504b5SStefano Zampini } 4647a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 4648f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 464916e386b8SStefano Zampini } 46503301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 46513301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 46526816873aSStefano Zampini } 4653f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 4654304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 4655304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 4656304d26faSStefano Zampini /* default */ 4657304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 4658e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 4659304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 46609577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 46619577ea80SStefano Zampini if (issbaij) { 46629577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 46639577ea80SStefano Zampini } else { 4664304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 46659577ea80SStefano Zampini } 4666304d26faSStefano Zampini /* Allow user's customization */ 4667304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 4668304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4669304d26faSStefano Zampini } 4670304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4671304d26faSStefano Zampini if (!n_R) { 4672304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 4673304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4674304d26faSStefano Zampini } 46755cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 4676df4d28bfSStefano Zampini /* Reuse solver if it is present */ 4677b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4678df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4679d62866d3SStefano Zampini 4680df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 4681d62866d3SStefano Zampini } 4682304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 4683304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 4684684f6988SStefano Zampini } 4685304d26faSStefano Zampini 4686684f6988SStefano Zampini if (pcbddc->dbg_flag) { 4687684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 46881575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4689684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4690684f6988SStefano Zampini } 4691c7017625SStefano Zampini 4692c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 4693c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 4694c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 4695c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 4696c7017625SStefano Zampini } 4697c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 4698c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 4699c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 4700c7017625SStefano Zampini } 4701c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 4702c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 4703c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 4704c7017625SStefano Zampini } 4705c7017625SStefano Zampini 4706c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 4707c7017625SStefano Zampini if (pcbddc->dbg_flag) { 4708684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 47090fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 47100fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 47110fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 47120fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 47130fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 4714e604994aSStefano 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); 4715c7017625SStefano Zampini if (check_corr[0]) { 4716c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 4717c7017625SStefano Zampini } 4718304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4719304d26faSStefano Zampini } 4720684f6988SStefano Zampini if (neumann) { /* Neumann */ 47210fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 47220fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 47230fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 47240fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 47250fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 4726e604994aSStefano 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); 4727c7017625SStefano Zampini if (check_corr[1]) { 4728c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 4729c7017625SStefano Zampini } 4730304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4731304d26faSStefano Zampini } 4732684f6988SStefano Zampini } 47335cbda25cSStefano Zampini /* free Neumann problem's matrix */ 47345cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4735304d26faSStefano Zampini PetscFunctionReturn(0); 4736304d26faSStefano Zampini } 4737304d26faSStefano Zampini 4738304d26faSStefano Zampini #undef __FUNCT__ 4739ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 474080677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 4741674ae819SStefano Zampini { 4742674ae819SStefano Zampini PetscErrorCode ierr; 4743674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4744be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4745b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 4746674ae819SStefano Zampini 4747674ae819SStefano Zampini PetscFunctionBegin; 4748b334f244SStefano Zampini if (!reuse_solver) { 474980677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 475020c7b377SStefano Zampini } 475180677318SStefano Zampini if (!pcbddc->switch_static) { 475280677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 475380677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 475480677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 475520c7b377SStefano Zampini } 4756b334f244SStefano Zampini if (!reuse_solver) { 475780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 475880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 475920c7b377SStefano Zampini } else { 4760df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4761be83ff47SStefano Zampini 4762df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4763df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 476420c7b377SStefano Zampini } 4765be83ff47SStefano Zampini } else { 476680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 476780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 476880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 476980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 477080677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 477180677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 477280677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 477380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 477480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4775674ae819SStefano Zampini } 4776674ae819SStefano Zampini } 4777b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 477880677318SStefano Zampini if (applytranspose) { 477980677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 478080677318SStefano Zampini } else { 478180677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 478280677318SStefano Zampini } 4783be83ff47SStefano Zampini } else { 4784df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4785be83ff47SStefano Zampini 4786be83ff47SStefano Zampini if (applytranspose) { 4787df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4788be83ff47SStefano Zampini } else { 4789df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4790be83ff47SStefano Zampini } 4791be83ff47SStefano Zampini } 479280677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 479380677318SStefano Zampini if (!pcbddc->switch_static) { 4794b334f244SStefano Zampini if (!reuse_solver) { 479580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 479680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4797be83ff47SStefano Zampini } else { 4798df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4799be83ff47SStefano Zampini 4800df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4801df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4802be83ff47SStefano Zampini } 480380677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 480480677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 480580677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 480680677318SStefano Zampini } 480780677318SStefano Zampini } else { 480880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 480980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 481080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 481180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 481280677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 481380677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 481480677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 481580677318SStefano Zampini } 481680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 481780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 481880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 481980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4820674ae819SStefano Zampini } 4821674ae819SStefano Zampini PetscFunctionReturn(0); 4822674ae819SStefano Zampini } 4823674ae819SStefano Zampini 4824dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 4825674ae819SStefano Zampini #undef __FUNCT__ 4826674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 4827dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 4828674ae819SStefano Zampini { 4829674ae819SStefano Zampini PetscErrorCode ierr; 4830674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4831674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 4832674ae819SStefano Zampini const PetscScalar zero = 0.0; 4833674ae819SStefano Zampini 4834674ae819SStefano Zampini PetscFunctionBegin; 4835dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 48364fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4837dc359a40SStefano Zampini if (applytranspose) { 4838674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 48398eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 4840dc359a40SStefano Zampini } else { 4841674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 4842674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 484315aaf578SStefano Zampini } 48444fee134fSStefano Zampini } else { 48454fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 48464fee134fSStefano Zampini } 4847efc2fbd9SStefano Zampini 4848efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 48494f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4850efc2fbd9SStefano Zampini PetscScalar *array; 48514f1b2e48SStefano Zampini PetscInt j; 4852efc2fbd9SStefano Zampini 4853efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 48544f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 4855efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4856efc2fbd9SStefano Zampini } 4857efc2fbd9SStefano Zampini 485812edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 485912edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 486012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 486112edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 486212edc857SStefano Zampini 48639f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 486412edc857SStefano Zampini if (pcbddc->coarse_ksp) { 486551694757SStefano Zampini Mat coarse_mat; 4866964fefecSStefano Zampini Vec rhs,sol; 486751694757SStefano Zampini MatNullSpace nullsp; 486827b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 4869964fefecSStefano Zampini 487027b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 487127b6a85dSStefano Zampini PC coarse_pc; 487227b6a85dSStefano Zampini 487327b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 487427b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 487527b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 487627b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 487727b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 487827b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 48793bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 488027b6a85dSStefano Zampini } 488127b6a85dSStefano Zampini } 4882964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 4883964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 488451694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 488551694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 488651694757SStefano Zampini if (nullsp) { 488751694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 488851694757SStefano Zampini } 488912edc857SStefano Zampini if (applytranspose) { 48909a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 4891964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 48922701bc32SStefano Zampini } else { 48931f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 48942701bc32SStefano Zampini PC coarse_pc; 48952701bc32SStefano Zampini 48962701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 48972701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 48983e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 48992701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 490012edc857SStefano Zampini } else { 4901964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 490212edc857SStefano Zampini } 49032701bc32SStefano Zampini } 49041d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 490527b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 490627b6a85dSStefano Zampini PC coarse_pc; 490727b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 490827b6a85dSStefano Zampini 490927b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 491027b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 491127b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 49123bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 491327b6a85dSStefano Zampini } 491451694757SStefano Zampini if (nullsp) { 491551694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 491651694757SStefano Zampini } 491712edc857SStefano Zampini } 4918674ae819SStefano Zampini 4919674ae819SStefano Zampini /* Local solution on R nodes */ 49204fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 492180677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 49229f00e9b4SStefano Zampini } 49239f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 49249f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 492512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4926674ae819SStefano Zampini 49274fee134fSStefano Zampini /* Sum contributions from the two levels */ 49284fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4929dc359a40SStefano Zampini if (applytranspose) { 4930dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 4931dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4932dc359a40SStefano Zampini } else { 4933674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 49348eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4935dc359a40SStefano Zampini } 4936efc2fbd9SStefano Zampini /* store p0 */ 49374f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4938efc2fbd9SStefano Zampini PetscScalar *array; 49394f1b2e48SStefano Zampini PetscInt j; 4940efc2fbd9SStefano Zampini 4941efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 49424f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 4943efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4944efc2fbd9SStefano Zampini } 49454fee134fSStefano Zampini } else { /* expand the coarse solution */ 49464fee134fSStefano Zampini if (applytranspose) { 49474fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 49484fee134fSStefano Zampini } else { 49494fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 49504fee134fSStefano Zampini } 49514fee134fSStefano Zampini } 4952674ae819SStefano Zampini PetscFunctionReturn(0); 4953674ae819SStefano Zampini } 4954674ae819SStefano Zampini 4955674ae819SStefano Zampini #undef __FUNCT__ 4956674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 495712edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 4958674ae819SStefano Zampini { 4959674ae819SStefano Zampini PetscErrorCode ierr; 4960674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 496158da7f69SStefano Zampini PetscScalar *array; 496212edc857SStefano Zampini Vec from,to; 4963674ae819SStefano Zampini 4964674ae819SStefano Zampini PetscFunctionBegin; 496512edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 496612edc857SStefano Zampini from = pcbddc->coarse_vec; 496712edc857SStefano Zampini to = pcbddc->vec1_P; 496812edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 496912edc857SStefano Zampini Vec tvec; 497058da7f69SStefano Zampini 497158da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 497258da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 497312edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 497458da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 497558da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 497658da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 497712edc857SStefano Zampini } 497812edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 497912edc857SStefano Zampini from = pcbddc->vec1_P; 498012edc857SStefano Zampini to = pcbddc->coarse_vec; 498112edc857SStefano Zampini } 498212edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 4983674ae819SStefano Zampini PetscFunctionReturn(0); 4984674ae819SStefano Zampini } 4985674ae819SStefano Zampini 4986674ae819SStefano Zampini #undef __FUNCT__ 4987674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 498812edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 4989674ae819SStefano Zampini { 4990674ae819SStefano Zampini PetscErrorCode ierr; 4991674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 499258da7f69SStefano Zampini PetscScalar *array; 499312edc857SStefano Zampini Vec from,to; 4994674ae819SStefano Zampini 4995674ae819SStefano Zampini PetscFunctionBegin; 499612edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 499712edc857SStefano Zampini from = pcbddc->coarse_vec; 499812edc857SStefano Zampini to = pcbddc->vec1_P; 499912edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 500012edc857SStefano Zampini from = pcbddc->vec1_P; 500112edc857SStefano Zampini to = pcbddc->coarse_vec; 500212edc857SStefano Zampini } 500312edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 500412edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 500512edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 500612edc857SStefano Zampini Vec tvec; 500758da7f69SStefano Zampini 500812edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 500958da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 501058da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 501158da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 501258da7f69SStefano Zampini } 501358da7f69SStefano Zampini } else { 501458da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 501558da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 501612edc857SStefano Zampini } 501712edc857SStefano Zampini } 5018674ae819SStefano Zampini PetscFunctionReturn(0); 5019674ae819SStefano Zampini } 5020674ae819SStefano Zampini 5021984c4197SStefano Zampini /* uncomment for testing purposes */ 5022984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 5023674ae819SStefano Zampini #undef __FUNCT__ 5024674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 5025674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 5026674ae819SStefano Zampini { 5027674ae819SStefano Zampini PetscErrorCode ierr; 5028674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5029674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5030674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5031984c4197SStefano Zampini /* one and zero */ 5032984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 5033984c4197SStefano Zampini /* space to store constraints and their local indices */ 50349162d606SStefano Zampini PetscScalar *constraints_data; 50359162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 50369162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 50379162d606SStefano Zampini PetscInt *constraints_n; 5038984c4197SStefano Zampini /* iterators */ 5039b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 5040984c4197SStefano Zampini /* BLAS integers */ 5041e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 5042e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 5043c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 5044727cdba6SStefano Zampini /* reuse */ 50450e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 50460e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 5047984c4197SStefano Zampini /* change of basis */ 5048b3d85658SStefano Zampini PetscBool qr_needed; 50499162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 5050984c4197SStefano Zampini /* auxiliary stuff */ 505164efe560SStefano Zampini PetscInt *nnz,*is_indices; 50528a0068c3SStefano Zampini PetscInt ncc; 5053984c4197SStefano Zampini /* some quantities */ 505445a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 5055a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 5056984c4197SStefano Zampini 5057674ae819SStefano Zampini PetscFunctionBegin; 50588e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 50598e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 50608e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 506116909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 5062088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 5063088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 50640e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 50650e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 50660e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 50670e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 50680e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 5069088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5070cf5a6209SStefano Zampini 5071cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 50729162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 5073cf5a6209SStefano Zampini MatNullSpace nearnullsp; 5074cf5a6209SStefano Zampini const Vec *nearnullvecs; 5075cf5a6209SStefano Zampini Vec *localnearnullsp; 5076cf5a6209SStefano Zampini PetscScalar *array; 5077cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 5078cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 5079674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 5080b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 5081674ae819SStefano Zampini PetscScalar *work; 5082674ae819SStefano Zampini PetscReal *singular_vals; 5083674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5084674ae819SStefano Zampini PetscReal *rwork; 5085674ae819SStefano Zampini #endif 5086674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5087674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 5088674ae819SStefano Zampini #else 5089964fefecSStefano Zampini PetscBLASInt dummy_int=1; 5090964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 5091674ae819SStefano Zampini #endif 5092674ae819SStefano Zampini 5093674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 5094d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 5095e4d548c7SStefano Zampini /* print some info */ 50965c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 5097e4d548c7SStefano Zampini PetscInt nv; 5098e4d548c7SStefano Zampini 5099c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5100e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 5101e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5102e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5103e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 5104e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 5105e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 5106e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5107e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5108e4d548c7SStefano Zampini } 5109e4d548c7SStefano Zampini 5110d06fc5fdSStefano Zampini /* free unneeded index sets */ 5111d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 5112d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 5113674ae819SStefano Zampini } 5114d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 5115d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5116d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5117d06fc5fdSStefano Zampini } 5118d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5119d06fc5fdSStefano Zampini n_ISForEdges = 0; 5120d06fc5fdSStefano Zampini } 5121d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 5122d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5123d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5124d06fc5fdSStefano Zampini } 5125d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5126d06fc5fdSStefano Zampini n_ISForFaces = 0; 5127d06fc5fdSStefano Zampini } 512870022509SStefano Zampini 5129674ae819SStefano Zampini /* check if near null space is attached to global mat */ 5130674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 5131674ae819SStefano Zampini if (nearnullsp) { 5132674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 5133f4ddd8eeSStefano Zampini /* remove any stored info */ 5134f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 5135f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5136f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 5137f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 5138f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 5139473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5140f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 5141f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 5142f4ddd8eeSStefano Zampini } 5143984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 5144984c4197SStefano Zampini nnsp_size = 0; 5145674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 5146674ae819SStefano Zampini } 5147984c4197SStefano Zampini /* get max number of constraints on a single cc */ 5148984c4197SStefano Zampini max_constraints = nnsp_size; 5149984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 5150984c4197SStefano Zampini 5151674ae819SStefano Zampini /* 5152674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 51539162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 51549162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 51559162d606SStefano Zampini There can be multiple constraints per connected component 5156674ae819SStefano Zampini */ 5157674ae819SStefano Zampini n_vertices = 0; 5158674ae819SStefano Zampini if (ISForVertices) { 5159674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 5160674ae819SStefano Zampini } 51619162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 51629162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 51639162d606SStefano Zampini 51649162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 51659162d606SStefano Zampini total_counts *= max_constraints; 5166674ae819SStefano Zampini total_counts += n_vertices; 51674641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 51689162d606SStefano Zampini 5169674ae819SStefano Zampini total_counts = 0; 5170674ae819SStefano Zampini max_size_of_constraint = 0; 5171674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 51729162d606SStefano Zampini IS used_is; 5173674ae819SStefano Zampini if (i<n_ISForEdges) { 51749162d606SStefano Zampini used_is = ISForEdges[i]; 5175674ae819SStefano Zampini } else { 51769162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 5177674ae819SStefano Zampini } 51789162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 5179674ae819SStefano Zampini total_counts += j; 5180674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 5181674ae819SStefano Zampini } 51829162d606SStefano 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); 51839162d606SStefano Zampini 5184984c4197SStefano Zampini /* get local part of global near null space vectors */ 5185785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 5186984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5187984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 5188e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5189e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5190984c4197SStefano Zampini } 5191674ae819SStefano Zampini 5192242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 5193242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 5194a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 5195242a89d7SStefano Zampini 5196984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 5197a773dcb8SStefano Zampini if (!skip_lapack) { 5198674ae819SStefano Zampini PetscScalar temp_work; 5199911cabfeSStefano Zampini 5200674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5201984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 5202785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 5203785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 5204785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 5205674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5206785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 5207674ae819SStefano Zampini #endif 5208674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5209c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 5210c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 5211674ae819SStefano Zampini lwork = -1; 5212674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5213674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5214c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 5215674ae819SStefano Zampini #else 5216c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 5217674ae819SStefano Zampini #endif 5218674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5219984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 5220674ae819SStefano Zampini #else /* on missing GESVD */ 5221674ae819SStefano Zampini /* SVD */ 5222674ae819SStefano Zampini PetscInt max_n,min_n; 5223674ae819SStefano Zampini max_n = max_size_of_constraint; 5224984c4197SStefano Zampini min_n = max_constraints; 5225984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 5226674ae819SStefano Zampini min_n = max_size_of_constraint; 5227984c4197SStefano Zampini max_n = max_constraints; 5228674ae819SStefano Zampini } 5229785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 5230674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5231785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 5232674ae819SStefano Zampini #endif 5233674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5234674ae819SStefano Zampini lwork = -1; 5235e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 5236e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 5237b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 5238674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5239674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 52409162d606SStefano 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)); 5241674ae819SStefano Zampini #else 52429162d606SStefano 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)); 5243674ae819SStefano Zampini #endif 5244674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5245984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 5246984c4197SStefano Zampini #endif /* on missing GESVD */ 5247674ae819SStefano Zampini /* Allocate optimal workspace */ 5248674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 5249854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 5250674ae819SStefano Zampini } 5251674ae819SStefano Zampini /* Now we can loop on constraining sets */ 5252674ae819SStefano Zampini total_counts = 0; 52539162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 52549162d606SStefano Zampini constraints_data_ptr[0] = 0; 5255674ae819SStefano Zampini /* vertices */ 52569162d606SStefano Zampini if (n_vertices) { 5257674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 52589162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 5259674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 52609162d606SStefano Zampini constraints_n[total_counts] = 1; 52619162d606SStefano Zampini constraints_data[total_counts] = 1.0; 52629162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 52639162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 5264674ae819SStefano Zampini total_counts++; 5265674ae819SStefano Zampini } 5266674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5267674ae819SStefano Zampini n_vertices = total_counts; 5268674ae819SStefano Zampini } 5269984c4197SStefano Zampini 5270674ae819SStefano Zampini /* edges and faces */ 52719162d606SStefano Zampini total_counts_cc = total_counts; 5272911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 52739162d606SStefano Zampini IS used_is; 52749162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 52759162d606SStefano Zampini 5276911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 52779162d606SStefano Zampini used_is = ISForEdges[ncc]; 5278984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 5279674ae819SStefano Zampini } else { 52809162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 5281984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 5282674ae819SStefano Zampini } 5283674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 52849162d606SStefano Zampini 52859162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 52869162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5287984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 5288984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 5289674ae819SStefano Zampini if (nnsp_has_cnst) { 52905b08dc53SStefano Zampini PetscScalar quad_value; 52919162d606SStefano Zampini 52929162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 52939162d606SStefano Zampini idxs_copied = PETSC_TRUE; 52949162d606SStefano Zampini 5295a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 5296674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 5297a773dcb8SStefano Zampini } else { 5298a773dcb8SStefano Zampini quad_value = 1.0; 5299a773dcb8SStefano Zampini } 5300674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 53019162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 5302674ae819SStefano Zampini } 53039162d606SStefano Zampini temp_constraints++; 5304674ae819SStefano Zampini total_counts++; 5305674ae819SStefano Zampini } 5306674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 5307984c4197SStefano Zampini PetscReal real_value; 53089162d606SStefano Zampini PetscScalar *ptr_to_data; 53099162d606SStefano Zampini 5310984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 53119162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 5312674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 53139162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 5314674ae819SStefano Zampini } 5315984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 5316984c4197SStefano Zampini /* check if array is null on the connected component */ 5317e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 53189162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 53195b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 5320674ae819SStefano Zampini temp_constraints++; 5321674ae819SStefano Zampini total_counts++; 53229162d606SStefano Zampini if (!idxs_copied) { 53239162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 53249162d606SStefano Zampini idxs_copied = PETSC_TRUE; 5325674ae819SStefano Zampini } 5326674ae819SStefano Zampini } 53279162d606SStefano Zampini } 53289162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 532945a1bb75SStefano Zampini valid_constraints = temp_constraints; 5330eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 5331a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 53329162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 53339162d606SStefano Zampini 53349162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5335a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 53369162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 5337a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 53389162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 5339a773dcb8SStefano Zampini } else { /* perform SVD */ 5340984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 53419162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5342674ae819SStefano Zampini 5343674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5344984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 5345984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 5346984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 5347984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 5348984c4197SStefano Zampini from that computed using LAPACKgesvd 5349984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 5350984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 5351984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 5352674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 5353e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5354984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5355674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 5356674ae819SStefano Zampini for (k=0;k<j+1;k++) { 53579162d606SStefano 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)); 5358674ae819SStefano Zampini } 5359674ae819SStefano Zampini } 5360e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 5361e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5362e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 5363674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5364c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 5365674ae819SStefano Zampini #else 5366c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 5367674ae819SStefano Zampini #endif 5368674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5369984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 5370984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 5371674ae819SStefano Zampini j = 0; 5372984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 5373674ae819SStefano Zampini total_counts = total_counts-j; 537445a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 5375e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 5376c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5377c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5378c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 5379c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5380c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 5381c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5382674ae819SStefano Zampini if (j<temp_constraints) { 5383984c4197SStefano Zampini PetscInt ii; 5384984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 5385674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 53869162d606SStefano 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)); 5387674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5388984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 5389674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 53909162d606SStefano 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]; 5391674ae819SStefano Zampini } 5392674ae819SStefano Zampini } 5393674ae819SStefano Zampini } 5394674ae819SStefano Zampini #else /* on missing GESVD */ 5395e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5396e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5397b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5398674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5399674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 54009162d606SStefano 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)); 5401674ae819SStefano Zampini #else 54029162d606SStefano 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)); 5403674ae819SStefano Zampini #endif 5404984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 5405674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5406984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 5407e310c8b4SStefano Zampini k = temp_constraints; 5408e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 5409674ae819SStefano Zampini j = 0; 5410e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 541145a1bb75SStefano Zampini valid_constraints = k-j; 5412911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 5413984c4197SStefano Zampini #endif /* on missing GESVD */ 5414674ae819SStefano Zampini } 5415a773dcb8SStefano Zampini } 54169162d606SStefano Zampini /* update pointers information */ 54179162d606SStefano Zampini if (valid_constraints) { 54189162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 54199162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 54209162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 54219162d606SStefano Zampini /* set change_of_basis flag */ 542245a1bb75SStefano Zampini if (boolforchange) { 5423b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 54249162d606SStefano Zampini } 5425b3d85658SStefano Zampini total_counts_cc++; 542645a1bb75SStefano Zampini } 542745a1bb75SStefano Zampini } 5428984c4197SStefano Zampini /* free workspace */ 54298f1c130eSStefano Zampini if (!skip_lapack) { 5430984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 5431984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5432984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 5433984c4197SStefano Zampini #endif 5434984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 5435984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5436984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 5437984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 5438984c4197SStefano Zampini #endif 5439984c4197SStefano Zampini } 5440984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5441984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 5442984c4197SStefano Zampini } 5443984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 5444cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 5445cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5446cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5447cf5a6209SStefano Zampini } 5448cf5a6209SStefano Zampini if (n_ISForFaces) { 5449cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5450cf5a6209SStefano Zampini } 5451cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5452cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5453cf5a6209SStefano Zampini } 5454cf5a6209SStefano Zampini if (n_ISForEdges) { 5455cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5456cf5a6209SStefano Zampini } 5457cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 545808122e43SStefano Zampini } else { 545908122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5460984c4197SStefano Zampini 546108122e43SStefano Zampini total_counts = 0; 546208122e43SStefano Zampini n_vertices = 0; 5463d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 5464d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 546508122e43SStefano Zampini } 546608122e43SStefano Zampini max_constraints = 0; 54679162d606SStefano Zampini total_counts_cc = 0; 546808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 546908122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 54709162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 547108122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 547208122e43SStefano Zampini } 54739162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 54749162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 54759162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 54769162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 547774d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 54789162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 54799162d606SStefano Zampini total_counts_cc = 0; 54809162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 54819162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 54829162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 548308122e43SStefano Zampini } 548408122e43SStefano Zampini } 54859162d606SStefano Zampini #if 0 54869162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 54879162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 54889162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 54899162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 54909162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 54919162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 54929162d606SStefano Zampini } 54939162d606SStefano Zampini printf("\n"); 54949162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 54959162d606SStefano Zampini } 54961b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 54978bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 54981b968477SStefano Zampini } 54991b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 55008bec7fa6SStefano 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]); 55011b968477SStefano Zampini } 550208122e43SStefano Zampini #endif 550308122e43SStefano Zampini 55048bec7fa6SStefano Zampini max_size_of_constraint = 0; 55059162d606SStefano 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]); 55069162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 550708122e43SStefano Zampini /* Change of basis */ 5508b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 550908122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 551008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 551108122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 5512b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 551308122e43SStefano Zampini } 551408122e43SStefano Zampini } 551508122e43SStefano Zampini } 551608122e43SStefano Zampini } 5517984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 55184f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 551908122e43SStefano Zampini 55209162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 55219162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 55226c4ed002SBarry Smith if (i != constraints_idxs_ptr[total_counts_cc]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %D != %D\n",constraints_idxs_ptr[total_counts_cc],i); 5523674ae819SStefano Zampini 5524674ae819SStefano Zampini /* Create constraint matrix */ 5525674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 552616f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 5527984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 5528984c4197SStefano Zampini 5529984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 5530a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 5531a717540cSStefano Zampini qr_needed = PETSC_FALSE; 553274d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 5533984c4197SStefano Zampini total_primal_vertices=0; 5534b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 55359162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 55369162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 553772b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 55389162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 5539b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 554064efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 55419162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 55429162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 5543a717540cSStefano Zampini } 5544b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 554591af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 5546a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 5547a717540cSStefano Zampini qr_needed = PETSC_TRUE; 5548a717540cSStefano Zampini } 5549fa434743SStefano Zampini } else { 5550b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 5551fa434743SStefano Zampini } 5552a717540cSStefano Zampini } 5553b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 5554b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 5555674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 555670022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 55574f1b2e48SStefano 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); 55580e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 55590e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 5560984c4197SStefano Zampini 5561984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 556274d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 5563785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 5564984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 556574d5cdf7SStefano Zampini 5566984c4197SStefano Zampini j = total_primal_vertices; 556774d5cdf7SStefano Zampini total_counts = total_primal_vertices; 5568b3d85658SStefano Zampini cum = total_primal_vertices; 55699162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 55704641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 5571b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 5572b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 5573b3d85658SStefano Zampini cum++; 55749162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 557574d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 557674d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 557774d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 557874d5cdf7SStefano Zampini } 55799162d606SStefano Zampini j += constraints_n[i]; 5580674ae819SStefano Zampini } 5581674ae819SStefano Zampini } 5582674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 5583674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 5584088faed8SStefano Zampini 5585674ae819SStefano Zampini /* set values in constraint matrix */ 5586984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 55870e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5588674ae819SStefano Zampini } 5589984c4197SStefano Zampini total_counts = total_primal_vertices; 55909162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 55914641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 55929162d606SStefano Zampini PetscInt *cols; 55939162d606SStefano Zampini 55949162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 55959162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 55969162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 55979162d606SStefano Zampini PetscInt row = total_counts+k; 55989162d606SStefano Zampini PetscScalar *vals; 55999162d606SStefano Zampini 56009162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 56019162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 56029162d606SStefano Zampini } 56039162d606SStefano Zampini total_counts += constraints_n[i]; 5604674ae819SStefano Zampini } 5605674ae819SStefano Zampini } 5606674ae819SStefano Zampini /* assembling */ 5607674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5608674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5609088faed8SStefano Zampini 5610984c4197SStefano Zampini /* 56116a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5612984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 5613f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 5614984c4197SStefano Zampini */ 5615674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 5616674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 5617026de310SStefano Zampini /* dual and primal dofs on a single cc */ 5618984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 5619984c4197SStefano Zampini /* working stuff for GEQRF */ 562081d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 5621984c4197SStefano Zampini PetscBLASInt lqr_work; 5622984c4197SStefano Zampini /* working stuff for UNGQR */ 5623984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 5624984c4197SStefano Zampini PetscBLASInt lgqr_work; 5625984c4197SStefano Zampini /* working stuff for TRTRS */ 5626984c4197SStefano Zampini PetscScalar *trs_rhs; 56273f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 5628984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 5629984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 5630984c4197SStefano Zampini PetscScalar *start_vals; 5631984c4197SStefano Zampini /* working stuff for values insertion */ 56324641a718SStefano Zampini PetscBT is_primal; 563364efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 5634906d46d4SStefano Zampini /* matrix sizes */ 5635906d46d4SStefano Zampini PetscInt global_size,local_size; 5636906d46d4SStefano Zampini /* temporary change of basis */ 5637906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 5638cf5a6209SStefano Zampini /* extra space for debugging */ 5639cf5a6209SStefano Zampini PetscScalar *dbg_work; 5640984c4197SStefano Zampini 5641906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 5642906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 564316f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 5644bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 5645906d46d4SStefano Zampini /* nonzeros for local mat */ 5646bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 56471dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5648bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 56491dd7afcfSStefano Zampini } else { 56501dd7afcfSStefano Zampini const PetscInt *ii; 56511dd7afcfSStefano Zampini PetscInt n; 56521dd7afcfSStefano Zampini PetscBool flg_row; 56531dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 56541dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 56551dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 56561dd7afcfSStefano Zampini } 56579162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 5658a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 56599162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 5660a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 56619162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 5662a717540cSStefano Zampini } else { 56639162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 56649162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 5665a717540cSStefano Zampini } 5666a717540cSStefano Zampini } 5667a717540cSStefano Zampini } 5668906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 5669bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 56701dd7afcfSStefano Zampini /* Set interior change in the matrix */ 56711dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5672bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 5673906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 5674a717540cSStefano Zampini } 56751dd7afcfSStefano Zampini } else { 56761dd7afcfSStefano Zampini const PetscInt *ii,*jj; 56771dd7afcfSStefano Zampini PetscScalar *aa; 56781dd7afcfSStefano Zampini PetscInt n; 56791dd7afcfSStefano Zampini PetscBool flg_row; 56801dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 56811dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 56821dd7afcfSStefano Zampini for (i=0;i<n;i++) { 56831dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 56841dd7afcfSStefano Zampini } 56851dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 56861dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 56871dd7afcfSStefano Zampini } 5688a717540cSStefano Zampini 5689a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5690a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5691a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5692a717540cSStefano Zampini } 5693a717540cSStefano Zampini 5694a717540cSStefano Zampini 5695a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 5696a717540cSStefano Zampini /* 5697a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 5698a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 5699a717540cSStefano Zampini 5700a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 5701a717540cSStefano Zampini 5702a6b551f4SStefano 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) 5703a6b551f4SStefano Zampini 5704a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 5705a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 5706a717540cSStefano Zampini | ... | 5707a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 5708a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 5709a717540cSStefano Zampini 5710a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 5711a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 5712a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 5713a6b551f4SStefano Zampini 5714a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 5715a717540cSStefano Zampini */ 5716a717540cSStefano Zampini if (qr_needed) { 5717984c4197SStefano Zampini /* space to store Q */ 5718854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 57194e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 57204e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 5721984c4197SStefano Zampini /* first we issue queries for optimal work */ 57223f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 57233f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 57243f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5725984c4197SStefano Zampini lqr_work = -1; 57263f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 5727984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 5728984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 5729785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 5730984c4197SStefano Zampini lgqr_work = -1; 57313f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 57323f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 57333f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 57343f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 57353f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 57363f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 5737984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 5738984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 5739785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 5740984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 5741785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 5742a717540cSStefano Zampini /* allocating workspace for check */ 5743a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5744cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 5745a717540cSStefano Zampini } 5746a717540cSStefano Zampini } 5747984c4197SStefano Zampini /* array to store whether a node is primal or not */ 57484641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 5749473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 57500e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 57516c4ed002SBarry Smith if (i != total_primal_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %D != %D\n",total_primal_vertices,i); 575239e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 575339e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 575439e2fb2aSStefano Zampini } 575539e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 5756984c4197SStefano Zampini 5757a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 57589162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 57599162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 57604641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 5761984c4197SStefano Zampini /* get constraint info */ 57629162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 5763984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 5764984c4197SStefano Zampini 5765984c4197SStefano Zampini if (pcbddc->dbg_flag) { 57669162d606SStefano 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); 5767674ae819SStefano Zampini } 5768984c4197SStefano Zampini 5769fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 5770a717540cSStefano Zampini 5771a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 5772a717540cSStefano Zampini if (pcbddc->dbg_flag) { 57739162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5774a717540cSStefano Zampini } 5775984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 57769162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5777984c4197SStefano Zampini 5778984c4197SStefano Zampini /* compute QR decomposition of constraints */ 57793f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 57803f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 57813f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5782674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 57833f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 5784984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 5785674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5786984c4197SStefano Zampini 5787984c4197SStefano Zampini /* explictly compute R^-T */ 5788984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 5789984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 57903f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 57913f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 57923f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 57933f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 5794984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 57953f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 5796984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 5797984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5798984c4197SStefano Zampini 5799a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 58003f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 58013f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 58023f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 58033f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5804984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 58053f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 5806984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 5807984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5808984c4197SStefano Zampini 5809984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 5810984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 5811984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 58123f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 58133f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 58143f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 58153f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 58163f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 58173f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5818984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 58199162d606SStefano 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)); 5820984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 58219162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5822984c4197SStefano Zampini 5823984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 58249162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 5825984c4197SStefano Zampini /* insert cols for primal dofs */ 5826984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 5827984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 58289162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5829906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5830984c4197SStefano Zampini } 5831984c4197SStefano Zampini /* insert cols for dual dofs */ 5832984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 58339162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 5834984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 58359162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5836906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5837984c4197SStefano Zampini j++; 5838674ae819SStefano Zampini } 5839674ae819SStefano Zampini } 5840984c4197SStefano Zampini 5841984c4197SStefano Zampini /* check change of basis */ 5842984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5843984c4197SStefano Zampini PetscInt ii,jj; 5844984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 5845c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 5846c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5847c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 5848c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5849c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 5850c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 5851984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5852cf5a6209SStefano 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)); 5853984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5854984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5855984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5856cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 5857cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) valid_qr = PETSC_FALSE; 5858674ae819SStefano Zampini } 5859674ae819SStefano Zampini } 5860984c4197SStefano Zampini if (!valid_qr) { 586122d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 5862984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5863984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5864cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 5865cf5a6209SStefano 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])); 5866674ae819SStefano Zampini } 5867cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 5868cf5a6209SStefano 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])); 5869984c4197SStefano Zampini } 5870984c4197SStefano Zampini } 5871984c4197SStefano Zampini } 5872674ae819SStefano Zampini } else { 587322d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 5874674ae819SStefano Zampini } 5875674ae819SStefano Zampini } 5876a717540cSStefano Zampini } else { /* simple transformation block */ 5877a717540cSStefano Zampini PetscInt row,col; 5878a6b551f4SStefano Zampini PetscScalar val,norm; 5879a6b551f4SStefano Zampini 5880a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 58819162d606SStefano 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)); 5882a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 58839162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 58849162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5885bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 58869162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 5887906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 58889162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 5889a717540cSStefano Zampini } else { 5890a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 58919162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5892a717540cSStefano Zampini if (row != col) { 58939162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 5894a717540cSStefano Zampini } else { 58959162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 5896a717540cSStefano Zampini } 5897906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 5898a717540cSStefano Zampini } 5899a717540cSStefano Zampini } 5900a717540cSStefano Zampini } 590198a51de6SStefano Zampini if (pcbddc->dbg_flag) { 590222d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 5903a717540cSStefano Zampini } 5904674ae819SStefano Zampini } 5905984c4197SStefano Zampini } else { 5906984c4197SStefano Zampini if (pcbddc->dbg_flag) { 59079162d606SStefano 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); 5908674ae819SStefano Zampini } 5909674ae819SStefano Zampini } 5910674ae819SStefano Zampini } 5911a717540cSStefano Zampini 5912a717540cSStefano Zampini /* free workspace */ 5913a717540cSStefano Zampini if (qr_needed) { 5914984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5915cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 5916984c4197SStefano Zampini } 5917984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 5918984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 5919984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 5920984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 5921984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 5922674ae819SStefano Zampini } 5923a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 5924906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5925906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5926906d46d4SStefano Zampini 5927906d46d4SStefano Zampini /* assembling of global change of variable */ 592888c03ad3SStefano Zampini if (!pcbddc->fake_change) { 5929bbb9e6c6SStefano Zampini Mat tmat; 593016f15bc4SStefano Zampini PetscInt bs; 593116f15bc4SStefano Zampini 5932906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 5933906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 5934bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 5935bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 5936bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5937bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 593816f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 593916f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 5940906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 5941bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 5942bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5943bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 5944bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5945bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5946e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5947e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5948bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 5949bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 595088c03ad3SStefano Zampini 5951906d46d4SStefano Zampini /* check */ 5952906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 5953906d46d4SStefano Zampini PetscReal error; 5954906d46d4SStefano Zampini Vec x,x_change; 5955906d46d4SStefano Zampini 5956906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 5957906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 5958906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 5959906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 5960e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5961e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5962bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 5963e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5964e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5965906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 5966906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 5967906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 5968906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5969bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 5970906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 5971906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 5972906d46d4SStefano Zampini } 5973b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 5974b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 5975b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5976bf3a8328SStefano Zampini 59779a962809SStefano Zampini 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");CHKERRQ(ierr); 5978b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 5979ac632422SStefano Zampini Mat S_new,tmat; 5980bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 5981bbb9e6c6SStefano Zampini 5982bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 59836816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 5984bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5985bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 5986bf3a8328SStefano Zampini IS is_V; 5987b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 5988b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 5989b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 5990b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 5991b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 5992bf3a8328SStefano Zampini } 5993bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 5994ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 5995b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 5996ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 5997bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5998bf3a8328SStefano Zampini const PetscScalar *array; 5999bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6000bf3a8328SStefano Zampini PetscInt i,n_V; 6001bf3a8328SStefano Zampini 6002b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6003b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6004b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6005b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6006b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6007b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6008b087196eSStefano Zampini PetscScalar val; 6009b087196eSStefano Zampini PetscInt idx; 6010b087196eSStefano Zampini 6011b087196eSStefano Zampini idx = idxs_V[i]; 6012b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6013b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6014b087196eSStefano Zampini } 6015b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6016b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6017bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 6018bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6019bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6020bf3a8328SStefano Zampini } 6021ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 6022ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6023ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 6024ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6025b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 6026ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6027bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6028b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6029bf3a8328SStefano Zampini } 6030ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 6031ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6032ac632422SStefano Zampini } 6033b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 603488c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6035b96c3477SStefano Zampini } 6036c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 6037b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 6038c9db6a07SStefano Zampini PetscInt i; 6039c9db6a07SStefano Zampini 6040c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6041c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 6042c9db6a07SStefano Zampini } 6043c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 6044c9db6a07SStefano Zampini } 6045b96c3477SStefano Zampini } 604616909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 604716909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 604816909a7fSStefano Zampini } else { 6049906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 605016909a7fSStefano Zampini } 60511dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 605227b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 605372b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 605472b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 605572b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 605672b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 605772b8c272SStefano Zampini } 60581dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 605927b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 6060b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 6061b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 6062906d46d4SStefano Zampini } else { 60631dd7afcfSStefano Zampini Mat benign_global = NULL; 606427b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 60651dd7afcfSStefano Zampini Mat tmat; 60661dd7afcfSStefano Zampini 60671dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 60681dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 60691dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 60701dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 60711dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 60721dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 60731dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 60741dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 60751dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 60761dd7afcfSStefano Zampini if (pcbddc->benign_change) { 60771dd7afcfSStefano Zampini Mat M; 60781dd7afcfSStefano Zampini 60791dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 60801dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 60811dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 60821dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 6083906d46d4SStefano Zampini } else { 60841dd7afcfSStefano Zampini Mat eye; 60851dd7afcfSStefano Zampini PetscScalar *array; 60861dd7afcfSStefano Zampini 60871dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 60881dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 60891dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 60901dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 6091906d46d4SStefano Zampini } 60921dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 60931dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 60941dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 60951dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 60961dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 60971dd7afcfSStefano Zampini } 60981dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 60991dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 61001dd7afcfSStefano Zampini } 61011dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 61021dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 61031dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 610427b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 61051dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 61061dd7afcfSStefano Zampini } 61071dd7afcfSStefano Zampini } 610816909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 610916909a7fSStefano Zampini IS is_global; 611016909a7fSStefano Zampini const PetscInt *gidxs; 611116909a7fSStefano Zampini 611216909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 611316909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 611416909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 611516909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 611616909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 611716909a7fSStefano Zampini } 61181dd7afcfSStefano Zampini } 61191dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 61201dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 6121b9b85e73SStefano Zampini } 6122a717540cSStefano Zampini 612372b8c272SStefano Zampini if (!pcbddc->fake_change) { 61244f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 61254f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 61264f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 61274f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 6128019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 6129019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 6130019a44ceSStefano Zampini pcbddc->local_primal_size++; 6131019a44ceSStefano Zampini } 6132019a44ceSStefano Zampini 6133019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 6134727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 6135727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 61369f47a83aSStefano 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); 6137c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 61380e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 61399f47a83aSStefano 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); 6140727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 6141727cdba6SStefano Zampini } 61420e6343abSStefano Zampini } 6143727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 6144b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 614572b8c272SStefano Zampini } 614672b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 6147727cdba6SStefano Zampini 6148a717540cSStefano Zampini /* flush dbg viewer */ 6149b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 6150b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6151b8ffe317SStefano Zampini } 6152a717540cSStefano Zampini 6153e310c8b4SStefano Zampini /* free workspace */ 6154a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 61554641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 615608122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 61579162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 61589162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 615908122e43SStefano Zampini } else { 61609162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 61619162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 61629162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 616308122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 616408122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 61659162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 61669162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 616708122e43SStefano Zampini } 6168674ae819SStefano Zampini PetscFunctionReturn(0); 6169674ae819SStefano Zampini } 6170674ae819SStefano Zampini 6171674ae819SStefano Zampini #undef __FUNCT__ 6172674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 6173674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 6174674ae819SStefano Zampini { 617571582508SStefano Zampini ISLocalToGlobalMapping map; 6176674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6177674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 617814f95afaSStefano Zampini PetscInt ierr,i,N; 6179674ae819SStefano Zampini 6180674ae819SStefano Zampini PetscFunctionBegin; 61818af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 6182b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 61838e61c736SStefano Zampini /* Reset previously computed graph */ 61848e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 6185674ae819SStefano Zampini /* Init local Graph struct */ 61867fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 618771582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 6188be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 6189674ae819SStefano Zampini 6190575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 61919a962809SStefano 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); 61929577ea80SStefano Zampini 6193674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 6194d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 61954d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 61964d379d7bSStefano Zampini PetscInt nvtxs; 6197e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 6198674ae819SStefano Zampini 61992fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 62002fffb893SStefano Zampini if (flg_row) { 62014d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 6202b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 62032fffb893SStefano Zampini } 62042fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 6205674ae819SStefano Zampini } 62069b28b941SStefano Zampini if (pcbddc->dbg_flag) { 62079b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6208674ae819SStefano Zampini } 6209674ae819SStefano Zampini 6210674ae819SStefano Zampini /* Setup of Graph */ 62114b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 621214f95afaSStefano 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); 6213674ae819SStefano Zampini 62144f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 62154f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 62164f1b2e48SStefano Zampini PetscInt *local_subs; 62174f1b2e48SStefano Zampini 62184f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 62194f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 62204f1b2e48SStefano Zampini const PetscInt *idxs; 62214f1b2e48SStefano Zampini PetscInt nl,j; 62224f1b2e48SStefano Zampini 62234f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 62244f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 622571582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 62264f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 62274f1b2e48SStefano Zampini } 62284f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 62294f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 62304f1b2e48SStefano Zampini } 62318af8fcf9SStefano Zampini } 62324f1b2e48SStefano Zampini 6233cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 6234674ae819SStefano Zampini /* Graph's connected components analysis */ 6235674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 623671582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 62378af8fcf9SStefano Zampini } 6238674ae819SStefano Zampini PetscFunctionReturn(0); 6239674ae819SStefano Zampini } 6240674ae819SStefano Zampini 62419a7d3425SStefano Zampini #undef __FUNCT__ 62429a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 62439a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 62449a7d3425SStefano Zampini { 62459a7d3425SStefano Zampini PetscInt i,j; 62469a7d3425SStefano Zampini PetscScalar *alphas; 62479a7d3425SStefano Zampini PetscErrorCode ierr; 62489a7d3425SStefano Zampini 62499a7d3425SStefano Zampini PetscFunctionBegin; 6250785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 62519a7d3425SStefano Zampini for (i=0;i<n;i++) { 62529a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 6253669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 6254669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 6255669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 62569a7d3425SStefano Zampini } 62579a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 62589a7d3425SStefano Zampini PetscFunctionReturn(0); 62599a7d3425SStefano Zampini } 62609a7d3425SStefano Zampini 6261e7931f94SStefano Zampini #undef __FUNCT__ 626270cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 626357de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 6264e7931f94SStefano Zampini { 626557de7509SStefano Zampini Mat A; 6266e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 6267e7931f94SStefano Zampini PetscMPIInt size,rank,color; 626852e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 626952e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 627027b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 627157de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 627227b6a85dSStefano Zampini PetscInt xadj_count, *count; 627327b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 627427b6a85dSStefano Zampini PetscSubcomm psubcomm; 627527b6a85dSStefano Zampini MPI_Comm subcomm; 627652e5ac9dSStefano Zampini PetscErrorCode ierr; 6277a57a6d2fSStefano Zampini 6278e7931f94SStefano Zampini PetscFunctionBegin; 627957de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 628057de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 628157de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 628257de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 628357de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 628457de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 628557de7509SStefano Zampini 628657de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 628757de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 628857de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 628957de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 629057de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 629157de7509SStefano Zampini im_active = !!(n); 629257de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 629357de7509SStefano Zampini void_procs = size - active_procs; 629457de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 629557de7509SStefano Zampini if (void_procs) { 629657de7509SStefano Zampini PetscInt ncand; 629757de7509SStefano Zampini 629857de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 629957de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 630057de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 630157de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 630257de7509SStefano Zampini if (!procs_candidates[i]) { 630357de7509SStefano Zampini procs_candidates[ncand++] = i; 630457de7509SStefano Zampini } 630557de7509SStefano Zampini } 630657de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 630757de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 630857de7509SStefano Zampini } 630957de7509SStefano Zampini 631014f0bfb9SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix 631114f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 631214f0bfb9SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1) { 631314f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 631414f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 631514f0bfb9SStefano Zampini else dest = rank; 631657de7509SStefano Zampini if (im_active) { 631757de7509SStefano Zampini issize = 1; 631857de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 631914f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 632057de7509SStefano Zampini } else { 632114f0bfb9SStefano Zampini isidx = dest; 632257de7509SStefano Zampini } 632357de7509SStefano Zampini } else { 632457de7509SStefano Zampini issize = 0; 632557de7509SStefano Zampini isidx = -1; 632657de7509SStefano Zampini } 632757de7509SStefano Zampini *n_subdomains = active_procs; 632857de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 6329daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 633057de7509SStefano Zampini PetscFunctionReturn(0); 633157de7509SStefano Zampini } 6332c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 6333c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 633427b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 6335e7931f94SStefano Zampini 6336e7931f94SStefano Zampini /* Get info on mapping */ 63373bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 63383bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6339e7931f94SStefano Zampini 6340e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 6341785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 6342e7931f94SStefano Zampini xadj[0] = 0; 6343e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 6344785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 6345785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 634627b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 634727b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 634827b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 634927b6a85dSStefano Zampini count[shared[i][j]] += 1; 6350e7931f94SStefano Zampini 635127b6a85dSStefano Zampini xadj_count = 0; 63522b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 635327b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 635427b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 6355d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 6356d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 6357d023bfaeSStefano Zampini xadj_count++; 635827b6a85dSStefano Zampini break; 635927b6a85dSStefano Zampini } 6360e7931f94SStefano Zampini } 6361e7931f94SStefano Zampini } 6362d023bfaeSStefano Zampini xadj[1] = xadj_count; 636327b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 63643bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6365e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 6366e7931f94SStefano Zampini 63673837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 6368e7931f94SStefano Zampini 636927b6a85dSStefano Zampini /* Restrict work on active processes only */ 637027b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 637127b6a85dSStefano Zampini if (void_procs) { 637227b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 637327b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 637427b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 637527b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 637627b6a85dSStefano Zampini } else { 637727b6a85dSStefano Zampini psubcomm = NULL; 637827b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 637927b6a85dSStefano Zampini } 638027b6a85dSStefano Zampini 638127b6a85dSStefano Zampini v_wgt = NULL; 638227b6a85dSStefano Zampini if (!color) { 6383e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 6384e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 6385e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6386c8587f34SStefano Zampini } else { 638752e5ac9dSStefano Zampini Mat subdomain_adj; 638852e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 638952e5ac9dSStefano Zampini MatPartitioning partitioner; 639027b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 639152e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 639257de7509SStefano Zampini PetscMPIInt size; 6393b0c7d250SStefano Zampini PetscBool aggregate; 6394b0c7d250SStefano Zampini 639527b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 639627b6a85dSStefano Zampini if (void_procs) { 639727b6a85dSStefano Zampini PetscInt prank = rank; 6398785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 639927b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 6400e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 6401e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 6402c8587f34SStefano Zampini } 6403e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 640427b6a85dSStefano Zampini } else { 640527b6a85dSStefano Zampini oldranks = NULL; 640627b6a85dSStefano Zampini } 6407b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 640827b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 6409b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 6410b0c7d250SStefano Zampini PetscMPIInt nrank; 6411b0c7d250SStefano Zampini PetscScalar *vals; 6412b0c7d250SStefano Zampini 641327b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 6414b0c7d250SStefano Zampini lrows = 0; 6415b0c7d250SStefano Zampini if (nrank<redprocs) { 6416b0c7d250SStefano Zampini lrows = size/redprocs; 6417b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 6418b0c7d250SStefano Zampini } 641927b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 6420b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 6421b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6422b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6423b0c7d250SStefano Zampini row = nrank; 6424b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 6425b0c7d250SStefano Zampini cols = adjncy; 6426b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 6427b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 6428b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 6429b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6430b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 643152e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 643252e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 643352e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6434b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 643527b6a85dSStefano Zampini if (use_vwgt) { 643627b6a85dSStefano Zampini Vec v; 643727b6a85dSStefano Zampini const PetscScalar *array; 643827b6a85dSStefano Zampini PetscInt nl; 643927b6a85dSStefano Zampini 644027b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 644127b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 644227b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 644327b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 644427b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 644527b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 644627b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 644722db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 644827b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 644927b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 645027b6a85dSStefano Zampini } 6451b0c7d250SStefano Zampini } else { 645227b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 645327b6a85dSStefano Zampini if (use_vwgt) { 645427b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 645527b6a85dSStefano Zampini v_wgt[0] = local_size; 645627b6a85dSStefano Zampini } 6457b0c7d250SStefano Zampini } 645822b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 6459e7931f94SStefano Zampini 6460e7931f94SStefano Zampini /* Partition */ 646127b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 6462e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 646327b6a85dSStefano Zampini if (v_wgt) { 6464e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 6465c8587f34SStefano Zampini } 646657de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 646757de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 6468e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 6469e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 647022b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 6471e7931f94SStefano Zampini 647252e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 64736583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 647452e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 647552e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 647657de7509SStefano Zampini if (!aggregate) { 647757de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 647827b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 647927b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 648027b6a85dSStefano Zampini #endif 648157de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 648227b6a85dSStefano Zampini } else if (oldranks) { 6483b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 648427b6a85dSStefano Zampini } else { 648527b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 648657de7509SStefano Zampini } 648728143c3dSStefano Zampini } else { 6488b0c7d250SStefano Zampini PetscInt idxs[1]; 6489b0c7d250SStefano Zampini PetscMPIInt tag; 6490b0c7d250SStefano Zampini MPI_Request *reqs; 6491b0c7d250SStefano Zampini 6492b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 6493b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 6494b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 649527b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 649628143c3dSStefano Zampini } 649727b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 6498b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6499b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 650057de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 650127b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 650227b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 650327b6a85dSStefano Zampini #endif 650457de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 650527b6a85dSStefano Zampini } else if (oldranks) { 6506b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 650727b6a85dSStefano Zampini } else { 650827b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 6509e7931f94SStefano Zampini } 651057de7509SStefano Zampini } 651152e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6512e7931f94SStefano Zampini /* clean up */ 6513e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 651452e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 6515e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 6516e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 6517e7931f94SStefano Zampini } 651827b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 651957de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 6520e7931f94SStefano Zampini 6521e7931f94SStefano Zampini /* assemble parallel IS for sends */ 6522e7931f94SStefano Zampini i = 1; 652327b6a85dSStefano Zampini if (!color) i=0; 652457de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 6525e7931f94SStefano Zampini PetscFunctionReturn(0); 6526e7931f94SStefano Zampini } 6527e7931f94SStefano Zampini 6528e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 6529e7931f94SStefano Zampini 6530e7931f94SStefano Zampini #undef __FUNCT__ 6531*1e0482f5SStefano Zampini #define __FUNCT__ "PCBDDCMatISSubassemble" 6532*1e0482f5SStefano 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[]) 6533e7931f94SStefano Zampini { 653470cf5478SStefano Zampini Mat local_mat; 6535e7931f94SStefano Zampini IS is_sends_internal; 65369d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 65371ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 65389d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 6539e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 6540e7931f94SStefano Zampini PetscInt* l2gmap_indices; 6541e7931f94SStefano Zampini const PetscInt* is_indices; 6542e7931f94SStefano Zampini MatType new_local_type; 6543e7931f94SStefano Zampini /* buffers */ 6544e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 654528143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 65469d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 6547e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 65481ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 6549e7931f94SStefano Zampini /* MPI */ 655028143c3dSStefano Zampini MPI_Comm comm,comm_n; 655128143c3dSStefano Zampini PetscSubcomm subcomm; 6552e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 655328143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 655428143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 65551ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 65561ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 65571ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 6558e7931f94SStefano Zampini PetscErrorCode ierr; 6559e7931f94SStefano Zampini 6560e7931f94SStefano Zampini PetscFunctionBegin; 656157de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6562e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 656328143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 656457de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 656557de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 656657de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 656757de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 656857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 65691ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 65701ae86dd6SStefano Zampini if (nvecs) { 65711ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 65721ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 65731ae86dd6SStefano Zampini } 657457de7509SStefano Zampini /* further checks */ 6575e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6576e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 6577e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 6578e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 6579e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 658057de7509SStefano Zampini if (reuse && *mat_n) { 658170cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 658257de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 658370cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 658428143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 658570cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 658670cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 658770cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 658870cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 658970cf5478SStefano Zampini } 6590e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 6591e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 659257de7509SStefano Zampini 6593e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 6594e7931f94SStefano Zampini if (!is_sends) { 659528143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 659657de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 6597c8587f34SStefano Zampini } else { 6598e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 6599e7931f94SStefano Zampini is_sends_internal = is_sends; 6600c8587f34SStefano Zampini } 6601e7931f94SStefano Zampini 6602e7931f94SStefano Zampini /* get comm */ 6603a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 6604e7931f94SStefano Zampini 6605e7931f94SStefano Zampini /* compute number of sends */ 6606e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 6607e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 6608e7931f94SStefano Zampini 6609e7931f94SStefano Zampini /* compute number of receives */ 6610e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 6611785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 6612e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 6613e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6614e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 6615e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 6616e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 6617e7931f94SStefano Zampini 661828143c3dSStefano Zampini /* restrict comm if requested */ 661928143c3dSStefano Zampini subcomm = 0; 662028143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 662128143c3dSStefano Zampini if (restrict_comm) { 6622779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 6623779c1cceSStefano Zampini 662428143c3dSStefano Zampini color = 0; 662553a05cb3SStefano Zampini if (restrict_full) { 662653a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 662753a05cb3SStefano Zampini } else { 662853a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 662953a05cb3SStefano Zampini } 6630b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 663128143c3dSStefano Zampini subcommsize = commsize - subcommsize; 663228143c3dSStefano Zampini /* check if reuse has been requested */ 663357de7509SStefano Zampini if (reuse) { 663428143c3dSStefano Zampini if (*mat_n) { 663528143c3dSStefano Zampini PetscMPIInt subcommsize2; 663628143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 663728143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 663828143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 663928143c3dSStefano Zampini } else { 664028143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 664128143c3dSStefano Zampini } 664228143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 6643779c1cceSStefano Zampini PetscMPIInt rank; 6644779c1cceSStefano Zampini 6645779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 664628143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 664728143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 664828143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 6649306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 665028143c3dSStefano Zampini } 665128143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 665228143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 665328143c3dSStefano Zampini } else { 665428143c3dSStefano Zampini comm_n = comm; 665528143c3dSStefano Zampini } 665628143c3dSStefano Zampini 6657e7931f94SStefano Zampini /* prepare send/receive buffers */ 6658785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 6659e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 6660785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 6661e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 666228143c3dSStefano Zampini if (nis) { 6663854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 666428143c3dSStefano Zampini } 6665e7931f94SStefano Zampini 666628143c3dSStefano Zampini /* Get data from local matrices */ 66676c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 6668e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 6669e7931f94SStefano Zampini /* 6670e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 6671e7931f94SStefano Zampini send_buffer_idxs should contain: 6672e7931f94SStefano Zampini - MatType_PRIVATE type 6673e7931f94SStefano Zampini - PetscInt size_of_l2gmap 6674e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 6675e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 6676e7931f94SStefano Zampini */ 66776c4ed002SBarry Smith else { 6678e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 66793bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 6680854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 6681e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 6682e7931f94SStefano Zampini send_buffer_idxs[1] = i; 66833bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6684e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 66853bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6686e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 6687e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6688e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 6689e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 6690c8587f34SStefano Zampini } 6691c8587f34SStefano Zampini } 6692e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 669328143c3dSStefano Zampini /* additional is (if any) */ 669428143c3dSStefano Zampini if (nis) { 669528143c3dSStefano Zampini PetscMPIInt psum; 669628143c3dSStefano Zampini PetscInt j; 669728143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 669828143c3dSStefano Zampini PetscInt plen; 669928143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 670028143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 670128143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 670228143c3dSStefano Zampini } 6703854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 670428143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 670528143c3dSStefano Zampini PetscInt plen; 670628143c3dSStefano Zampini const PetscInt *is_array_idxs; 670728143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 670828143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 670928143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 671028143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 671128143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 671228143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 671328143c3dSStefano Zampini } 671428143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 671528143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 671628143c3dSStefano Zampini } 671728143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 671828143c3dSStefano Zampini } 671928143c3dSStefano Zampini 6720e7931f94SStefano Zampini buf_size_idxs = 0; 6721e7931f94SStefano Zampini buf_size_vals = 0; 672228143c3dSStefano Zampini buf_size_idxs_is = 0; 67231ae86dd6SStefano Zampini buf_size_vecs = 0; 6724e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6725e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 6726e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 672728143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 67281ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 6729e7931f94SStefano Zampini } 6730785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 6731785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 673295ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 67331ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 6734e7931f94SStefano Zampini 6735e7931f94SStefano Zampini /* get new tags for clean communications */ 6736e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 6737e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 673828143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 67391ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 6740e7931f94SStefano Zampini 6741e7931f94SStefano Zampini /* allocate for requests */ 6742785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 6743785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 674495ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 67451ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 6746785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 6747785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 674895ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 67491ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 6750e7931f94SStefano Zampini 6751e7931f94SStefano Zampini /* communications */ 6752e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6753e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 675428143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 67551ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 6756e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6757e7931f94SStefano Zampini source_dest = onodes[i]; 6758e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 6759e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 6760e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6761e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 676228143c3dSStefano Zampini if (nis) { 676357de7509SStefano Zampini source_dest = onodes_is[i]; 676428143c3dSStefano 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); 676528143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 676628143c3dSStefano Zampini } 67671ae86dd6SStefano Zampini if (nvecs) { 67681ae86dd6SStefano Zampini source_dest = onodes[i]; 67691ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 67701ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 67711ae86dd6SStefano Zampini } 6772e7931f94SStefano Zampini } 6773e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6774e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 6775e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 6776e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 677728143c3dSStefano Zampini if (nis) { 677828143c3dSStefano 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); 677928143c3dSStefano Zampini } 67801ae86dd6SStefano Zampini if (nvecs) { 67811ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 67821ae86dd6SStefano 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); 67831ae86dd6SStefano Zampini } 6784e7931f94SStefano Zampini } 6785e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6786e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 6787e7931f94SStefano Zampini 6788e7931f94SStefano Zampini /* assemble new l2g map */ 6789e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6790e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 67919d30be91SStefano Zampini new_local_rows = 0; 6792e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 67939d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6794e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6795e7931f94SStefano Zampini } 67969d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 6797e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 67989d30be91SStefano Zampini new_local_rows = 0; 6799e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 68009d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 68019d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6802e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6803e7931f94SStefano Zampini } 68049d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 68059d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 6806e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 6807e7931f94SStefano Zampini 6808e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 6809e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 6810e7931f94SStefano 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) */ 6811e7931f94SStefano Zampini if (n_recvs) { 681228143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 6813e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6814e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6815e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 6816e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 6817e7931f94SStefano Zampini break; 6818e7931f94SStefano Zampini } 6819e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6820e7931f94SStefano Zampini } 6821e7931f94SStefano Zampini switch (new_local_type_private) { 682228143c3dSStefano Zampini case MATDENSE_PRIVATE: 682328143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 6824e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6825e7931f94SStefano Zampini bs = 1; 682628143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 682728143c3dSStefano Zampini new_local_type = MATSEQDENSE; 682828143c3dSStefano Zampini bs = 1; 682928143c3dSStefano Zampini } 6830e7931f94SStefano Zampini break; 6831e7931f94SStefano Zampini case MATAIJ_PRIVATE: 6832e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6833e7931f94SStefano Zampini bs = 1; 6834e7931f94SStefano Zampini break; 6835e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 6836e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 6837e7931f94SStefano Zampini break; 6838e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 6839e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 6840e7931f94SStefano Zampini break; 6841e7931f94SStefano Zampini default: 68429d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 6843e7931f94SStefano Zampini break; 6844e7931f94SStefano Zampini } 684528143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 684628143c3dSStefano Zampini new_local_type = MATSEQDENSE; 684728143c3dSStefano Zampini bs = 1; 6848e7931f94SStefano Zampini } 6849e7931f94SStefano Zampini 685070cf5478SStefano Zampini /* create MATIS object if needed */ 685157de7509SStefano Zampini if (!reuse) { 6852e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 6853e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 685470cf5478SStefano Zampini } else { 685570cf5478SStefano Zampini /* it also destroys the local matrices */ 685657de7509SStefano Zampini if (*mat_n) { 685770cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 685857de7509SStefano Zampini } else { /* this is a fake object */ 685957de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 686057de7509SStefano Zampini } 686170cf5478SStefano Zampini } 686270cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 6863e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 68649d30be91SStefano Zampini 68659d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 68669d30be91SStefano Zampini 68679d30be91SStefano Zampini /* Global to local map of received indices */ 68689d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 68699d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 68709d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 68719d30be91SStefano Zampini 68729d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 68739d30be91SStefano Zampini buf_size_idxs = 0; 68749d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 68759d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 68769d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 68779d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 68789d30be91SStefano Zampini } 68799d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 68809d30be91SStefano Zampini 68819d30be91SStefano Zampini /* set preallocation */ 68829d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 68839d30be91SStefano Zampini if (!newisdense) { 68849d30be91SStefano Zampini PetscInt *new_local_nnz=0; 68859d30be91SStefano Zampini 68869d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 68879d30be91SStefano Zampini if (n_recvs) { 68889d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 68899d30be91SStefano Zampini } 68909d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 68919d30be91SStefano Zampini PetscInt j; 68929d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 68939d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 68949d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 68959d30be91SStefano Zampini } 68969d30be91SStefano Zampini } else { 68979d30be91SStefano Zampini /* TODO */ 68989d30be91SStefano Zampini } 68999d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 69009d30be91SStefano Zampini } 69019d30be91SStefano Zampini if (new_local_nnz) { 69029d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 69039d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 69049d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 69059d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 69069d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 69079d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 69089d30be91SStefano Zampini } else { 69099d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 69109d30be91SStefano Zampini } 69119d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 69129d30be91SStefano Zampini } else { 69139d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 69149d30be91SStefano Zampini } 6915e7931f94SStefano Zampini 6916e7931f94SStefano Zampini /* set values */ 6917e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 69189d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 6919e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6920e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 6921e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 69229d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 6923e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6924e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6925e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 692628143c3dSStefano Zampini } else { 692728143c3dSStefano Zampini /* TODO */ 6928e7931f94SStefano Zampini } 6929e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6930e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 6931e7931f94SStefano Zampini } 6932e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6933e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 693470cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 693570cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 69369d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 6937e7931f94SStefano Zampini 6938dfd14d43SStefano Zampini #if 0 693928143c3dSStefano Zampini if (!restrict_comm) { /* check */ 6940e7931f94SStefano Zampini Vec lvec,rvec; 6941e7931f94SStefano Zampini PetscReal infty_error; 6942e7931f94SStefano Zampini 69432a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 6944e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 6945e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 6946e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 694770cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 6948e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 6949e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 6950e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 6951e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 6952e7931f94SStefano Zampini } 695328143c3dSStefano Zampini #endif 6954e7931f94SStefano Zampini 695528143c3dSStefano Zampini /* assemble new additional is (if any) */ 695628143c3dSStefano Zampini if (nis) { 695728143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 695828143c3dSStefano Zampini 695928143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6960854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 696128143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 696228143c3dSStefano Zampini psum = 0; 696328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 696428143c3dSStefano Zampini for (j=0;j<nis;j++) { 696528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 696628143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 696728143c3dSStefano Zampini psum += plen; 696828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 696928143c3dSStefano Zampini } 697028143c3dSStefano Zampini } 6971854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 6972854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 697328143c3dSStefano Zampini for (i=1;i<nis;i++) { 697428143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 697528143c3dSStefano Zampini } 697628143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 697728143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 697828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 697928143c3dSStefano Zampini for (j=0;j<nis;j++) { 698028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 698128143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 698228143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 698328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 698428143c3dSStefano Zampini } 698528143c3dSStefano Zampini } 698628143c3dSStefano Zampini for (i=0;i<nis;i++) { 698728143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 698828143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 698928143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 699028143c3dSStefano Zampini } 699128143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 699228143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 699328143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 699428143c3dSStefano Zampini } 6995e7931f94SStefano Zampini /* free workspace */ 699628143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 6997e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6998e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 6999e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7000e7931f94SStefano Zampini if (isdense) { 7001e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7002e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 7003e7931f94SStefano Zampini } else { 7004e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 7005e7931f94SStefano Zampini } 700628143c3dSStefano Zampini if (nis) { 700728143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 700828143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 700928143c3dSStefano Zampini } 70101ae86dd6SStefano Zampini 70111ae86dd6SStefano Zampini if (nvecs) { 70121ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 70131ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 70141ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 70151ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 70161ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 70171ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 70181ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 70191ae86dd6SStefano Zampini /* set values */ 70201ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 70211ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 70221ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 70231ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 70241ae86dd6SStefano Zampini PetscInt j; 70251ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 70261ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 70271ae86dd6SStefano Zampini } 70281ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 70291ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 70301ae86dd6SStefano Zampini } 70311ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 70321ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 70331ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 70341ae86dd6SStefano Zampini } 70351ae86dd6SStefano Zampini 70361ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 70371ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 7038e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 7039e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 70401ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 704128143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 7042e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 7043e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 70441ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 704528143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 7046e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 7047e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 7048e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 7049e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 7050e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 705128143c3dSStefano Zampini if (nis) { 705228143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 705328143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 705428143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 705528143c3dSStefano Zampini } 705628143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 705728143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 705828143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 705928143c3dSStefano Zampini for (i=0;i<nis;i++) { 706028143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 706128143c3dSStefano Zampini } 70621ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 70631ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 70641ae86dd6SStefano Zampini } 706553a05cb3SStefano Zampini *mat_n = NULL; 706628143c3dSStefano Zampini } 7067e7931f94SStefano Zampini PetscFunctionReturn(0); 7068e7931f94SStefano Zampini } 7069a57a6d2fSStefano Zampini 707012edc857SStefano Zampini /* temporary hack into ksp private data structure */ 7071af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 707212edc857SStefano Zampini 7073c8587f34SStefano Zampini #undef __FUNCT__ 7074c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 7075c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 7076c8587f34SStefano Zampini { 7077c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7078c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 707920a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 70801ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 7081*1e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 70829881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 708320a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 70846e683305SStefano Zampini IS coarse_is,*isarray; 70856e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 708630368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 7087f9eb5b7dSStefano Zampini PC pc_temp; 7088c8587f34SStefano Zampini PCType coarse_pc_type; 7089c8587f34SStefano Zampini KSPType coarse_ksp_type; 7090f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 70914f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 7092*1e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 709368457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 709422bc73bbSStefano Zampini PetscScalar *array; 709557de7509SStefano Zampini MatReuse coarse_mat_reuse; 709657de7509SStefano Zampini PetscBool restr, full_restr, have_void; 70979881197aSStefano Zampini PetscErrorCode ierr; 7098fdc09c96SStefano Zampini 7099c8587f34SStefano Zampini PetscFunctionBegin; 7100c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 710168457ee5SStefano 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 */ 7102fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 71035a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 7104fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 7105f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 7106f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 7107f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 7108fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 710951bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 711051bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 7111dc4bcba2SStefano Zampini PC pc; 7112dc4bcba2SStefano Zampini PetscBool isbddc; 7113dc4bcba2SStefano Zampini 7114dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 7115dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 7116dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 7117dc4bcba2SStefano Zampini if (isbddc) { 711863c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 711963c961adSStefano Zampini } else { 7120727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 712163c961adSStefano Zampini } 7122fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7123fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 7124fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7125f4ddd8eeSStefano Zampini } 7126fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 7127fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7128f4ddd8eeSStefano Zampini } 712970cf5478SStefano Zampini /* reset any subassembling information */ 713057de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 713170cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 713257de7509SStefano Zampini } 71336e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 7134fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7135f4ddd8eeSStefano Zampini } 713657de7509SStefano Zampini /* assemble coarse matrix */ 713757de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 713857de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 713957de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 714057de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 714118a45a71SStefano Zampini } else { 714257de7509SStefano Zampini coarse_mat = NULL; 714357de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 71446e683305SStefano Zampini } 7145e7931f94SStefano Zampini 7146abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 7147abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 7148abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 7149abbbba34SStefano Zampini 7150abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 715122bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 715222bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 715322bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 715422bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 7155e176bc59SStefano 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); 71566e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 71576e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 71586e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7159abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 7160abbbba34SStefano Zampini 716157de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 716257de7509SStefano Zampini im_active = !!(pcis->n); 716357de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 716457de7509SStefano Zampini 716514f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 716657de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 716757de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 716857de7509SStefano Zampini coarse_mat_is = NULL; 716957de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 717057de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 71711ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 717257de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 717357de7509SStefano Zampini if (multilevel_requested) { 717457de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 717557de7509SStefano Zampini restr = PETSC_FALSE; 717657de7509SStefano Zampini full_restr = PETSC_FALSE; 717757de7509SStefano Zampini } else { 717857de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 717957de7509SStefano Zampini restr = PETSC_TRUE; 718057de7509SStefano Zampini full_restr = PETSC_TRUE; 718157de7509SStefano Zampini } 71824b2aedd3SStefano Zampini if (!pcbddc->coarse_size) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 718357de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 718457de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 7185a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 718637eada30SStefano Zampini ierr = MatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7187a198735bSStefano Zampini } else { 7188a198735bSStefano Zampini PetscMPIInt size,rank; 7189a198735bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 7190a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 7191a198735bSStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 7192a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7193a198735bSStefano Zampini } 719457de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 719557de7509SStefano Zampini PetscInt psum; 719657de7509SStefano Zampini PetscMPIInt size; 719757de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 719857de7509SStefano Zampini else psum = 0; 719957de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 720057de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 720157de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 720257de7509SStefano Zampini } 720357de7509SStefano Zampini /* determine if we can go multilevel */ 720457de7509SStefano Zampini if (multilevel_requested) { 720557de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 720657de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 720757de7509SStefano Zampini } 720857de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 720957de7509SStefano Zampini 7210e4d548c7SStefano Zampini /* dump subassembling pattern */ 7211e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 7212e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 7213e4d548c7SStefano Zampini } 7214e4d548c7SStefano Zampini 72156e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 7216*1e0482f5SStefano Zampini nedcfield = -1; 7217*1e0482f5SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal)) { /* protects from unneded computations */ 72186e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 72196e683305SStefano Zampini const PetscInt *idxs; 72206e683305SStefano Zampini ISLocalToGlobalMapping tmap; 72216e683305SStefano Zampini 72226e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 72230be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 72246e683305SStefano Zampini /* allocate space for temporary storage */ 7225854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 7226854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 72276e683305SStefano Zampini /* allocate for IS array */ 72286e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 7229*1e0482f5SStefano Zampini if (pcbddc->nedclocal) { 7230*1e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 7231*1e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 7232*1e0482f5SStefano Zampini } else { 7233*1e0482f5SStefano Zampini nedcfield = 0; 7234*1e0482f5SStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%d)",nisdofs); 7235*1e0482f5SStefano Zampini nisdofs = 1; 7236*1e0482f5SStefano Zampini } 7237*1e0482f5SStefano Zampini } 72386e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 723927b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 724030368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 7241854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 72426e683305SStefano Zampini /* dofs splitting */ 72436e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 72446e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 7245*1e0482f5SStefano Zampini if (nedcfield != i) { 72466e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 72476e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 72486e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 72496e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 7250*1e0482f5SStefano Zampini } else { 7251*1e0482f5SStefano Zampini ierr = ISView(pcbddc->nedclocal,NULL);CHKERRQ(ierr); 7252*1e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 7253*1e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 7254*1e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 7255*1e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 7256*1e0482f5SStefano Zampini } 72576e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 725830368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 72596e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 72606e683305SStefano Zampini } 72616e683305SStefano Zampini /* neumann boundaries */ 72626e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 72636e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 72646e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 72656e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 72666e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 72676e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 72686e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 726930368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 72706e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 72716e683305SStefano Zampini } 72726e683305SStefano Zampini /* free memory */ 72736e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 72746e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 72756e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 72766e683305SStefano Zampini } else { 72776e683305SStefano Zampini nis = 0; 72786e683305SStefano Zampini nisdofs = 0; 72796e683305SStefano Zampini nisneu = 0; 728030368db7SStefano Zampini nisvert = 0; 72816e683305SStefano Zampini isarray = NULL; 72826e683305SStefano Zampini } 72836e683305SStefano Zampini /* destroy no longer needed map */ 72846e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 72856e683305SStefano Zampini 728657de7509SStefano Zampini /* subassemble */ 728757de7509SStefano Zampini if (multilevel_allowed) { 72881ae86dd6SStefano Zampini Vec vp[1]; 72891ae86dd6SStefano Zampini PetscInt nvecs = 0; 729057de7509SStefano Zampini PetscBool reuse,reuser; 72911ae86dd6SStefano Zampini 729257de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 729357de7509SStefano Zampini else reuse = PETSC_FALSE; 729457de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 72951ae86dd6SStefano Zampini vp[0] = NULL; 72961ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 72971ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 72981ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 72991ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 73001ae86dd6SStefano Zampini nvecs = 1; 73011ae86dd6SStefano Zampini 73021ae86dd6SStefano Zampini if (pcbddc->divudotp) { 7303a198735bSStefano Zampini Mat B,loc_divudotp; 73041ae86dd6SStefano Zampini Vec v,p; 73051ae86dd6SStefano Zampini IS dummy; 73061ae86dd6SStefano Zampini PetscInt np; 73071ae86dd6SStefano Zampini 7308a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 7309a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 73101ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 7311a198735bSStefano Zampini ierr = MatGetSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 73121ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 73131ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 73141ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 73151ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 73161ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 73171ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 73181ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 73191ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 73201ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 73211ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 73221ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 73231ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 732474e2c79eSStefano Zampini } 73251ae86dd6SStefano Zampini } 73261ae86dd6SStefano Zampini if (reuser) { 7327*1e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 732874e2c79eSStefano Zampini } else { 7329*1e0482f5SStefano 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); 73301ae86dd6SStefano Zampini } 73311ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 73321ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 73331ae86dd6SStefano Zampini PetscInt nl; 73341ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 73351ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 73361ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 73371ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 73381ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 73391ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 73401ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 73411ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 7342a198735bSStefano Zampini } else { 7343a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 73441ae86dd6SStefano Zampini } 73451ae86dd6SStefano Zampini } else { 7346*1e0482f5SStefano 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); 73476e683305SStefano Zampini } 734857de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 734957de7509SStefano Zampini PetscMPIInt size; 7350f913dca9SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size);CHKERRQ(ierr); 735157de7509SStefano Zampini if (!multilevel_allowed) { 735257de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 73536e683305SStefano Zampini } else { 735457de7509SStefano Zampini Mat A; 7355779c1cceSStefano Zampini 735657de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 735757de7509SStefano Zampini if (coarse_mat_is) { 735857de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 735957de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 736057de7509SStefano Zampini coarse_mat = coarse_mat_is; 736157de7509SStefano Zampini } 736257de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 736357de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 736457de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 7365779c1cceSStefano Zampini } 7366779c1cceSStefano Zampini } 736757de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 736857de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 73696e683305SStefano Zampini 73706e683305SStefano Zampini /* create local to global scatters for coarse problem */ 737168457ee5SStefano Zampini if (compute_vecs) { 73726e683305SStefano Zampini PetscInt lrows; 73736e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 737457de7509SStefano Zampini if (coarse_mat) { 737557de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 73766e683305SStefano Zampini } else { 73776e683305SStefano Zampini lrows = 0; 73786e683305SStefano Zampini } 73796e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 73806e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 73816e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 73826e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 73836e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 73846e683305SStefano Zampini } 73856e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 7386c8587f34SStefano Zampini 7387f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 7388f9eb5b7dSStefano Zampini if (multilevel_allowed) { 7389f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 7390f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 7391f9eb5b7dSStefano Zampini } else { 7392f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 7393f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 7394c8587f34SStefano Zampini } 7395c8587f34SStefano Zampini 73966e683305SStefano Zampini /* print some info if requested */ 73976e683305SStefano Zampini if (pcbddc->dbg_flag) { 73986e683305SStefano Zampini if (!multilevel_allowed) { 73996e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 74006e683305SStefano Zampini if (multilevel_requested) { 74016e683305SStefano 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); 74026e683305SStefano Zampini } else if (pcbddc->max_levels) { 74036e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 74046e683305SStefano Zampini } 74056e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 74066e683305SStefano Zampini } 74076e683305SStefano Zampini } 74086e683305SStefano Zampini 7409*1e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 7410*1e0482f5SStefano Zampini coarseG = NULL; 7411*1e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 7412*1e0482f5SStefano Zampini MPI_Comm ccomm; 7413*1e0482f5SStefano Zampini if (coarse_mat) { 7414*1e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 7415*1e0482f5SStefano Zampini } else { 7416*1e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 7417*1e0482f5SStefano Zampini } 7418*1e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 7419*1e0482f5SStefano Zampini } 7420*1e0482f5SStefano Zampini 7421f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 742257de7509SStefano Zampini if (coarse_mat) { 74236a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 74246e683305SStefano Zampini if (pcbddc->dbg_flag) { 742557de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 74266e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 74276e683305SStefano Zampini } 7428f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 7429312be037SStefano Zampini char prefix[256],str_level[16]; 7430e604994aSStefano Zampini size_t len; 7431*1e0482f5SStefano Zampini 743257de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 7433422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 7434c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 7435f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 743657de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7437c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 74386e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 7439c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 7440*1e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 7441c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7442e604994aSStefano Zampini /* prefix */ 7443e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 7444e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 7445e604994aSStefano Zampini if (!pcbddc->current_level) { 7446e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 7447e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 7448c8587f34SStefano Zampini } else { 7449e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 7450312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 7451312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 745234d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 7453312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 7454e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 7455e604994aSStefano Zampini } 7456e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 74573e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 74583e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 74593e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 74603e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 7461f9eb5b7dSStefano Zampini /* allow user customization */ 7462f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 74633e3c6dadSStefano Zampini } 74643e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 746551bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 74663e3c6dadSStefano Zampini if (nisdofs) { 74673e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 74683e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 74693e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 74703e3c6dadSStefano Zampini } 74713e3c6dadSStefano Zampini } 74723e3c6dadSStefano Zampini if (nisneu) { 74733e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 74743e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 7475312be037SStefano Zampini } 747630368db7SStefano Zampini if (nisvert) { 747730368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 747830368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 747930368db7SStefano Zampini } 7480*1e0482f5SStefano Zampini if (coarseG) { 7481*1e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 7482*1e0482f5SStefano Zampini } 7483f9eb5b7dSStefano Zampini 7484f9eb5b7dSStefano Zampini /* get some info after set from options */ 7485f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 7486f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 74874f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 74886e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 7489f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7490f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 7491f9eb5b7dSStefano Zampini } 749239f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 74934f3a063dSStefano Zampini if (isredundant) { 74944f3a063dSStefano Zampini KSP inner_ksp; 74954f3a063dSStefano Zampini PC inner_pc; 74964f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 74974f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 74984f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 74994f3a063dSStefano Zampini } 7500f9eb5b7dSStefano Zampini 750157de7509SStefano Zampini /* parameters which miss an API */ 750257de7509SStefano Zampini if (isbddc) { 7503720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 7504720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 750557de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 750627b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 750727b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 7508a198735bSStefano Zampini Mat coarsedivudotp_is; 7509a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 7510a198735bSStefano Zampini IS row,col; 7511a198735bSStefano Zampini const PetscInt *gidxs; 7512a198735bSStefano Zampini PetscInt n,st,M,N; 7513a198735bSStefano Zampini 7514a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 7515a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 7516a198735bSStefano Zampini st = st-n; 7517a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 7518a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 7519a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 7520a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7521a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 7522a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7523a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 7524a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 7525a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 7526a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 7527a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 7528a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 7529a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 7530a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 7531a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 7532a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 7533a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7534a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7535a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 7536a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 75378ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 7538a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 7539720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 754059e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 7541720d30f9SStefano Zampini } 7542d4d8cf7bSStefano Zampini } 75439881197aSStefano Zampini 75443301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 75455a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 75463301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 75473301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 75483301b35fSStefano Zampini } 75493301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 75503301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 75513301b35fSStefano Zampini } 75523301b35fSStefano Zampini if (pc->pmat->spd_set) { 75533301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 75543301b35fSStefano Zampini } 755527b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 755627b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 755727b6a85dSStefano Zampini } 75586e683305SStefano Zampini /* set operators */ 75595f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 75606e683305SStefano Zampini if (pcbddc->dbg_flag) { 75616e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 75626e683305SStefano Zampini } 75636e683305SStefano Zampini } 7564*1e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 75656e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 7566b1ecc7b1SStefano Zampini #if 0 7567b9b85e73SStefano Zampini { 7568b9b85e73SStefano Zampini PetscViewer viewer; 7569b9b85e73SStefano Zampini char filename[256]; 7570b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 7571b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 75726a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 7573b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 7574f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 7575b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 7576b9b85e73SStefano Zampini } 7577b9b85e73SStefano Zampini #endif 7578f9eb5b7dSStefano Zampini 757998a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 758098a51de6SStefano Zampini Vec crhs,csol; 758104708bb6SStefano Zampini 7582f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 7583f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 7584f347579bSStefano Zampini if (!csol) { 75852a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 7586f9eb5b7dSStefano Zampini } 7587f347579bSStefano Zampini if (!crhs) { 75882a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 7589f347579bSStefano Zampini } 7590b0f5fe93SStefano Zampini } 75911ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 7592b0f5fe93SStefano Zampini 7593b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 7594b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 7595b0f5fe93SStefano Zampini 7596b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 75974f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 75984f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 75994f1b2e48SStefano Zampini } 7600b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 7601b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 7602b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7603b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7604b0f5fe93SStefano Zampini if (coarse_mat) { 7605b0f5fe93SStefano Zampini Vec nullv; 7606b0f5fe93SStefano Zampini PetscScalar *array,*array2; 7607b0f5fe93SStefano Zampini PetscInt nl; 7608b0f5fe93SStefano Zampini 7609b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 7610b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 7611b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7612b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 7613b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 7614b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 7615b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7616b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 7617b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 7618b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 7619b0f5fe93SStefano Zampini } 7620b0f5fe93SStefano Zampini } 7621b0f5fe93SStefano Zampini 7622b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 7623b0f5fe93SStefano Zampini PetscBool ispreonly; 7624b0f5fe93SStefano Zampini 7625b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7626b0f5fe93SStefano Zampini PetscBool isnull; 7627b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 7628bef83e63SStefano Zampini if (isnull) { 7629b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 7630b0f5fe93SStefano Zampini } 7631bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 7632b0f5fe93SStefano Zampini } 7633b0f5fe93SStefano Zampini /* setup coarse ksp */ 7634b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 7635cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 7636cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 76376e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 7638c8587f34SStefano Zampini KSP check_ksp; 76392b510759SStefano Zampini KSPType check_ksp_type; 7640c8587f34SStefano Zampini PC check_pc; 76416e683305SStefano Zampini Vec check_vec,coarse_vec; 76426a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 76432b510759SStefano Zampini PetscInt its; 76446e683305SStefano Zampini PetscBool compute_eigs; 76456e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 76466e683305SStefano Zampini PetscInt neigs; 76478e185a42SStefano Zampini const char *prefix; 7648c8587f34SStefano Zampini 76492b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 76506e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 7651422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 765223ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7653f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 7654e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 7655e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 7656e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 76572b510759SStefano Zampini if (ispreonly) { 76582b510759SStefano Zampini check_ksp_type = KSPPREONLY; 76596e683305SStefano Zampini compute_eigs = PETSC_FALSE; 76602b510759SStefano Zampini } else { 7661cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 76626e683305SStefano Zampini compute_eigs = PETSC_TRUE; 7663c8587f34SStefano Zampini } 7664c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 76656e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 76666e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 76676e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 7668a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 7669a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 7670a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 7671a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 7672c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 7673c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 7674c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 7675c8587f34SStefano Zampini /* create random vec */ 76762701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 7677c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 76786e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 7679c8587f34SStefano Zampini /* solve coarse problem */ 76806e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 7681cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 76826e683305SStefano Zampini if (compute_eigs) { 7683854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 7684854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 76856e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 76861ae86dd6SStefano Zampini if (neigs) { 76876e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 76886e683305SStefano Zampini lambda_min = eigs_r[0]; 76896e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 76902701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 76912701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 7692cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 7693cbcc2c2aSStefano Zampini } 7694c8587f34SStefano Zampini } 7695c8587f34SStefano Zampini } 76961ae86dd6SStefano Zampini } 7697cbcc2c2aSStefano Zampini 7698c8587f34SStefano Zampini /* check coarse problem residual error */ 76996e683305SStefano Zampini if (pcbddc->dbg_flag) { 77006e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 77016e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 77026e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 7703c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 77046e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 77056e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 7706779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 77076e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 77086e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 77096e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 77106e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 7711b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7712b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 7713b0f5fe93SStefano Zampini } 77146e683305SStefano Zampini if (compute_eigs) { 77156e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 7716b03ebc13SStefano Zampini KSPConvergedReason reason; 7717deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 7718c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 7719b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 77206e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 7721b03ebc13SStefano 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); 77226e683305SStefano Zampini for (i=0;i<neigs;i++) { 77236e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 7724c8587f34SStefano Zampini } 77256e683305SStefano Zampini } 77266e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 77276e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 77286e683305SStefano Zampini } 7729e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 77302701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 7731c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 77326e683305SStefano Zampini if (compute_eigs) { 77336e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 77346e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 7735c8587f34SStefano Zampini } 77366e683305SStefano Zampini } 77376e683305SStefano Zampini } 7738bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 7739cbcc2c2aSStefano Zampini /* print additional info */ 7740cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 77416e683305SStefano Zampini /* waits until all processes reaches this point */ 77426e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 7743cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 7744cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7745cbcc2c2aSStefano Zampini } 7746cbcc2c2aSStefano Zampini 77472b510759SStefano Zampini /* free memory */ 7748fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 7749c8587f34SStefano Zampini PetscFunctionReturn(0); 7750c8587f34SStefano Zampini } 7751674ae819SStefano Zampini 7752f34684f1SStefano Zampini #undef __FUNCT__ 7753f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 7754f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 7755f34684f1SStefano Zampini { 7756f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7757f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 7758f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 7759dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 7760dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 776173be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 7762dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 7763f34684f1SStefano Zampini PetscErrorCode ierr; 7764f34684f1SStefano Zampini 7765f34684f1SStefano Zampini PetscFunctionBegin; 7766f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 77676c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 7768dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 77693bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 7770dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7771dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 77726583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 7773dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 7774dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 7775dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 77766c4ed002SBarry 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); 7777dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 7778dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7779dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 7780dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7781dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7782f34684f1SStefano Zampini 7783f34684f1SStefano Zampini /* check numbering */ 7784f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 7785019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 7786dc456d91SStefano Zampini PetscInt i; 7787b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 7788f34684f1SStefano Zampini 7789f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7790f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 7791f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 77921575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7793019a44ceSStefano Zampini /* counter */ 7794019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7795019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 7796019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7797019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7798019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7799019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7800f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 7801f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 7802727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 7803f34684f1SStefano Zampini } 7804f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7805f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7806f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7807e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7808e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7809e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7810e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7811f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7812019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7813f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7814019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 78152c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 781675c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 7817b9b85e73SStefano Zampini set_error = PETSC_TRUE; 78182c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 78192c66d082SStefano 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); 7820f34684f1SStefano Zampini } 7821f34684f1SStefano Zampini } 7822019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7823b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 7824f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7825f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7826f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 7827f34684f1SStefano Zampini } 7828f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7829f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7830e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7831e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7832f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 7833f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 7834b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 7835ca8b9ea9SStefano Zampini PetscInt *gidxs; 7836ca8b9ea9SStefano Zampini 7837ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 78383bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 7839f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 7840f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7841f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 7842f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 78434bc2dc4bSStefano 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); 7844f34684f1SStefano Zampini } 7845f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7846ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 7847f34684f1SStefano Zampini } 7848f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 78491575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7850302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 7851f34684f1SStefano Zampini } 78528bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 7853f34684f1SStefano Zampini /* get back data */ 7854f34684f1SStefano Zampini *coarse_size_n = coarse_size; 7855f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 7856674ae819SStefano Zampini PetscFunctionReturn(0); 7857674ae819SStefano Zampini } 7858674ae819SStefano Zampini 7859e456f2a8SStefano Zampini #undef __FUNCT__ 7860e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 7861a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 7862e456f2a8SStefano Zampini { 7863e456f2a8SStefano Zampini IS localis_t; 7864a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 7865e456f2a8SStefano Zampini PetscScalar *vals; 7866e456f2a8SStefano Zampini PetscErrorCode ierr; 7867e456f2a8SStefano Zampini 7868e456f2a8SStefano Zampini PetscFunctionBegin; 7869a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 7870e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 7871854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 7872e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 7873e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7874a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 7875a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 78761035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 7877a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 78781035eff8SStefano Zampini } 7879a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 7880e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7881e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 7882a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 7883a7dc3881SStefano Zampini /* now compute set in local ordering */ 7884a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7885a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7886a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7887a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 7888a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7889ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7890e456f2a8SStefano Zampini lsize++; 7891e456f2a8SStefano Zampini } 7892e456f2a8SStefano Zampini } 7893854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 7894a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7895ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7896e456f2a8SStefano Zampini idxs[lsize++] = i; 7897e456f2a8SStefano Zampini } 7898e456f2a8SStefano Zampini } 7899a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7900a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 7901e456f2a8SStefano Zampini *localis = localis_t; 7902e456f2a8SStefano Zampini PetscFunctionReturn(0); 7903e456f2a8SStefano Zampini } 7904906d46d4SStefano Zampini 7905b96c3477SStefano Zampini #undef __FUNCT__ 7906b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 790708122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 7908b96c3477SStefano Zampini { 7909a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7910b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7911b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 7912a64f4aa4SStefano Zampini Mat S_j; 7913b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 7914b96c3477SStefano Zampini PetscBool free_used_adj; 7915b96c3477SStefano Zampini PetscErrorCode ierr; 7916b96c3477SStefano Zampini 7917b96c3477SStefano Zampini PetscFunctionBegin; 7918b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 7919b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 792008122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 7921b96c3477SStefano Zampini used_xadj = NULL; 7922b96c3477SStefano Zampini used_adjncy = NULL; 7923b96c3477SStefano Zampini } else { 792408122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 792508122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 792608122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 792708122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 7928b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 7929b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 7930b96c3477SStefano Zampini } else { 79312fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 7932b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 7933b96c3477SStefano Zampini PetscInt nvtxs; 7934b96c3477SStefano Zampini 79352fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 79362fffb893SStefano Zampini if (flg_row) { 7937b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 7938b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 7939b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 7940b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 79412fffb893SStefano Zampini } else { 79422fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 79432fffb893SStefano Zampini used_xadj = NULL; 79442fffb893SStefano Zampini used_adjncy = NULL; 79452fffb893SStefano Zampini } 79462fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 7947b96c3477SStefano Zampini } 7948b96c3477SStefano Zampini } 7949d5574798SStefano Zampini 7950d5574798SStefano Zampini /* setup sub_schurs data */ 7951a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 7952df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 7953df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 7954a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 795591af6908SStefano 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); 7956a64f4aa4SStefano Zampini } else { 79576816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 79584d7f8f00SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE; 7959a3df083aSStefano Zampini PetscInt benign_n; 796072b8c272SStefano Zampini Mat change = NULL; 79619d54b7f4SStefano Zampini Vec scaling = NULL; 796272b8c272SStefano Zampini IS change_primal = NULL; 7963a3df083aSStefano Zampini 79645feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 79655feab87aSStefano Zampini PetscInt n_vertices; 79665feab87aSStefano Zampini 79675feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 79682034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 79695feab87aSStefano Zampini } 797004708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 797104708bb6SStefano Zampini if (!isseqaij) { 797204708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 797304708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 797404708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 797504708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 797604708bb6SStefano Zampini } else { 7977511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 797804708bb6SStefano Zampini } 797904708bb6SStefano Zampini } 7980a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 7981a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 7982ca92afb2SStefano Zampini } else { 7983a3df083aSStefano Zampini benign_n = 0; 7984ca92afb2SStefano Zampini } 7985b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 7986b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 7987b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 798872b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 798922db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 7990b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 799122db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 7992b7ab4a40SStefano Zampini } 7993b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 7994b7ab4a40SStefano 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 */ 7995b7ab4a40SStefano Zampini if (need_change) { 799688c03ad3SStefano Zampini PC_IS *pcisf; 799788c03ad3SStefano Zampini PC_BDDC *pcbddcf; 799888c03ad3SStefano Zampini PC pcf; 799988c03ad3SStefano Zampini 8000e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 800188c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 800288c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 800388c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 800488c03ad3SStefano Zampini /* hacks */ 800588c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 800672b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 800772b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 800872b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 800972b8c272SStefano Zampini pcisf->n = pcis->n; 801072b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 801188c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 801288c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 801388c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 801488c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 801588c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 801688c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 801772b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 801888c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 801988c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 802072b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 802172b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 802272b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 802372b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 802472b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 802588c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 802672b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 802788c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 802888c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 802988c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 803088c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 803188c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 803288c03ad3SStefano Zampini pcf->ops->destroy = NULL; 803388c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 803488c03ad3SStefano Zampini } 80359d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 803691af6908SStefano 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); 803772b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 803872b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 8039ca92afb2SStefano Zampini } 8040d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8041b96c3477SStefano Zampini 8042b96c3477SStefano Zampini /* free adjacency */ 8043b96c3477SStefano Zampini if (free_used_adj) { 8044b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 8045b96c3477SStefano Zampini } 8046b96c3477SStefano Zampini PetscFunctionReturn(0); 8047b96c3477SStefano Zampini } 8048b96c3477SStefano Zampini 8049b96c3477SStefano Zampini #undef __FUNCT__ 8050b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 805108122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 8052b96c3477SStefano Zampini { 8053b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8054b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8055b96c3477SStefano Zampini PCBDDCGraph graph; 8056b96c3477SStefano Zampini PetscErrorCode ierr; 8057b96c3477SStefano Zampini 8058b96c3477SStefano Zampini PetscFunctionBegin; 8059b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 806008122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 80613301b35fSStefano Zampini IS verticesIS,verticescomm; 80623301b35fSStefano Zampini PetscInt vsize,*idxs; 8063b96c3477SStefano Zampini 8064b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 80653301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 80663301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 80673301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 80683301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 8069c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 8070b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 8071be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 8072441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 80733301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 8074b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 8075b96c3477SStefano Zampini } else { 8076b96c3477SStefano Zampini graph = pcbddc->mat_graph; 8077b96c3477SStefano Zampini } 8078e4d548c7SStefano Zampini /* print some info */ 80795c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 8080e4d548c7SStefano Zampini IS vertices; 8081e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 8082c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 8083e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8084e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 8085e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8086e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 8087e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 8088e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 8089e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 8090e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8091e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8092c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8093e4d548c7SStefano Zampini } 8094b96c3477SStefano Zampini 8095b96c3477SStefano Zampini /* sub_schurs init */ 8096b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 8097b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 8098b334f244SStefano Zampini } 80998b6046baSStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 8100a64f4aa4SStefano Zampini 8101b96c3477SStefano Zampini /* free graph struct */ 810208122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 8103b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 8104b96c3477SStefano Zampini } 8105b96c3477SStefano Zampini PetscFunctionReturn(0); 8106b96c3477SStefano Zampini } 8107fa34dd3eSStefano Zampini 8108fa34dd3eSStefano Zampini #undef __FUNCT__ 8109fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 8110fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 8111fa34dd3eSStefano Zampini { 8112fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8113fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8114fa34dd3eSStefano Zampini PetscErrorCode ierr; 8115fa34dd3eSStefano Zampini 8116fa34dd3eSStefano Zampini PetscFunctionBegin; 8117fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 8118fa34dd3eSStefano Zampini IS zerodiag = NULL; 81194f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 8120fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 81214f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 812275c01103SStefano Zampini PetscReal norm; 8123fa34dd3eSStefano Zampini PetscInt i; 8124fa34dd3eSStefano Zampini 8125fa34dd3eSStefano Zampini /* B0 and B0_B */ 8126fa34dd3eSStefano Zampini if (zerodiag) { 8127fa34dd3eSStefano Zampini IS dummy; 8128fa34dd3eSStefano Zampini 81294f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 81304f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 8131fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 8132fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 8133fa34dd3eSStefano Zampini } 8134fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 8135fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 8136fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 8137fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8138fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8139fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8140fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8141fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 8142fa34dd3eSStefano Zampini /* S_j */ 8143fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8144fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 8145fa34dd3eSStefano Zampini 8146fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 8147fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 8148fa34dd3eSStefano Zampini /* continuous in primal space */ 8149fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 8150fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8151fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8152fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 81534f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 81544f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 8155fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8156fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8157fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8158fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8159fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8160fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8161fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 8162fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 8163fa34dd3eSStefano Zampini 8164fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 8165fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 8166fa34dd3eSStefano Zampini /* local with Schur */ 8167fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 8168fa34dd3eSStefano Zampini if (zerodiag) { 8169fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 81704f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 8171fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8172fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 8173fa34dd3eSStefano Zampini } 8174fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 8175fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8176fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8177fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8178fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8179fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 8180fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8181fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8182fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 8183fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8184fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8185fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8186fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8187fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8188fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 8189fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 8190fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8191fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8192fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8193fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8194fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8195fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8196fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 8197fa34dd3eSStefano Zampini if (zerodiag) { 8198fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 8199fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 82004f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 8201fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8202fa34dd3eSStefano Zampini } 8203fa34dd3eSStefano Zampini /* BDDC */ 8204fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 8205fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 8206fa34dd3eSStefano Zampini 8207fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 8208fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 8209fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 8210fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 82114f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 82124f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 8213fa34dd3eSStefano Zampini } 82144f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 8215fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 8216fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 8217fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 8218fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8219fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 8220fa34dd3eSStefano Zampini } 8221fa34dd3eSStefano Zampini PetscFunctionReturn(0); 8222fa34dd3eSStefano Zampini } 8223*1e0482f5SStefano Zampini 8224*1e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 8225*1e0482f5SStefano Zampini #undef __FUNCT__ 8226*1e0482f5SStefano Zampini #define __FUNCT__ "MatMPIAIJRestrict" 8227*1e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 8228*1e0482f5SStefano Zampini { 8229*1e0482f5SStefano Zampini Mat At; 8230*1e0482f5SStefano Zampini IS rows; 8231*1e0482f5SStefano Zampini MPI_Comm comm; 8232*1e0482f5SStefano Zampini PetscInt rst,ren; 8233*1e0482f5SStefano Zampini PetscErrorCode ierr; 8234*1e0482f5SStefano Zampini PetscLayout rmap; 8235*1e0482f5SStefano Zampini 8236*1e0482f5SStefano Zampini PetscFunctionBegin; 8237*1e0482f5SStefano Zampini rst = ren = 0; 8238*1e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 8239*1e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 8240*1e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 8241*1e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 8242*1e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 8243*1e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 8244*1e0482f5SStefano Zampini } 8245*1e0482f5SStefano Zampini ierr = ISCreateStride(comm,ren-rst,rst,1,&rows);CHKERRQ(ierr); 8246*1e0482f5SStefano Zampini ierr = MatGetSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 8247*1e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 8248*1e0482f5SStefano Zampini 8249*1e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 8250*1e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 8251*1e0482f5SStefano Zampini IS from,to; 8252*1e0482f5SStefano Zampini Vec gvec; 8253*1e0482f5SStefano Zampini PetscInt lsize; 8254*1e0482f5SStefano Zampini 8255*1e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 8256*1e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 8257*1e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 8258*1e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 8259*1e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 8260*1e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 8261*1e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 8262*1e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 8263*1e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 8264*1e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 8265*1e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 8266*1e0482f5SStefano Zampini b->A = a->A; 8267*1e0482f5SStefano Zampini b->B = a->B; 8268*1e0482f5SStefano Zampini 8269*1e0482f5SStefano Zampini b->donotstash = a->donotstash; 8270*1e0482f5SStefano Zampini b->roworiented = a->roworiented; 8271*1e0482f5SStefano Zampini b->rowindices = 0; 8272*1e0482f5SStefano Zampini b->rowvalues = 0; 8273*1e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 8274*1e0482f5SStefano Zampini 8275*1e0482f5SStefano Zampini (*B)->rmap = rmap; 8276*1e0482f5SStefano Zampini (*B)->factortype = A->factortype; 8277*1e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 8278*1e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 8279*1e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 8280*1e0482f5SStefano Zampini 8281*1e0482f5SStefano Zampini if (a->colmap) { 8282*1e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 8283*1e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 8284*1e0482f5SStefano Zampini #else 8285*1e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 8286*1e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 8287*1e0482f5SStefano Zampini ierr = PetscMemcpy(b->colmap,a->colmap,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 8288*1e0482f5SStefano Zampini #endif 8289*1e0482f5SStefano Zampini } else b->colmap = 0; 8290*1e0482f5SStefano Zampini if (a->garray) { 8291*1e0482f5SStefano Zampini PetscInt len; 8292*1e0482f5SStefano Zampini len = a->B->cmap->n; 8293*1e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 8294*1e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 8295*1e0482f5SStefano Zampini if (len) { ierr = PetscMemcpy(b->garray,a->garray,len*sizeof(PetscInt));CHKERRQ(ierr); } 8296*1e0482f5SStefano Zampini } else b->garray = 0; 8297*1e0482f5SStefano Zampini 8298*1e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 8299*1e0482f5SStefano Zampini b->lvec = a->lvec; 8300*1e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 8301*1e0482f5SStefano Zampini 8302*1e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 8303*1e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 8304*1e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 8305*1e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 8306*1e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 8307*1e0482f5SStefano Zampini ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 8308*1e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 8309*1e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 8310*1e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 8311*1e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 8312*1e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)*B,"coarse_restrict_G");CHKERRQ(ierr); 8313*1e0482f5SStefano Zampini ierr = MatView(*B,NULL);CHKERRQ(ierr); 8314*1e0482f5SStefano Zampini } 8315*1e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 8316*1e0482f5SStefano Zampini PetscFunctionReturn(0); 8317*1e0482f5SStefano Zampini } 8318