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 7a13144ffSStefano Zampini /* returns B s.t. range(B) _|_ range(A) */ 8a13144ffSStefano Zampini #undef __FUNCT__ 9a13144ffSStefano Zampini #define __FUNCT__ "MatDense_OrthogonalComplement" 10a13144ffSStefano Zampini PetscErrorCode MatDense_OrthogonalComplement(Mat A, PetscInt lw, PetscScalar *work, PetscReal *rwork, Mat *B) 11a13144ffSStefano Zampini { 12a13144ffSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 13a13144ffSStefano Zampini PetscScalar *uwork,*data,*U, ds = 0.; 14a13144ffSStefano Zampini PetscReal *sing; 15a13144ffSStefano Zampini PetscBLASInt bM,bN,lwork,lierr,di = 1; 16a13144ffSStefano Zampini PetscInt ulw,i,nr,nc,n; 17a13144ffSStefano Zampini PetscErrorCode ierr; 18a13144ffSStefano Zampini 19a13144ffSStefano Zampini PetscFunctionBegin; 20a13144ffSStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 21a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"LAPACK _GESVD not available"); 22a13144ffSStefano Zampini #endif 23a13144ffSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 24a13144ffSStefano Zampini if (!nr || !nc) PetscFunctionReturn(0); 25a13144ffSStefano Zampini 26a13144ffSStefano Zampini /* workspace */ 27a13144ffSStefano Zampini if (!work) { 28a13144ffSStefano Zampini ulw = PetscMax(PetscMax(1,5*PetscMin(nr,nc)),3*PetscMin(nr,nc)+PetscMax(nr,nc)); 29f913dca9SStefano Zampini ierr = PetscMalloc1(ulw,&uwork);CHKERRQ(ierr); 30a13144ffSStefano Zampini } else { 31a13144ffSStefano Zampini ulw = lw; 32a13144ffSStefano Zampini uwork = work; 33a13144ffSStefano Zampini } 34a13144ffSStefano Zampini n = PetscMin(nr,nc); 35a13144ffSStefano Zampini if (!rwork) { 36a13144ffSStefano Zampini ierr = PetscMalloc1(n,&sing);CHKERRQ(ierr); 37a13144ffSStefano Zampini } else { 38a13144ffSStefano Zampini sing = rwork; 39a13144ffSStefano Zampini } 40a13144ffSStefano Zampini 41a13144ffSStefano Zampini /* SVD */ 42a13144ffSStefano Zampini ierr = PetscMalloc1(nr*nr,&U);CHKERRQ(ierr); 43a13144ffSStefano Zampini ierr = PetscBLASIntCast(nr,&bM);CHKERRQ(ierr); 44a13144ffSStefano Zampini ierr = PetscBLASIntCast(nc,&bN);CHKERRQ(ierr); 45a13144ffSStefano Zampini ierr = PetscBLASIntCast(ulw,&lwork);CHKERRQ(ierr); 46a13144ffSStefano Zampini ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); 47a13144ffSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 48a13144ffSStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,&lierr)); 49a13144ffSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 50a13144ffSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 51a13144ffSStefano Zampini ierr = MatDenseRestoreArray(A,&data);CHKERRQ(ierr); 52a13144ffSStefano Zampini for (i=0;i<n;i++) if (sing[i] < PETSC_SMALL) break; 53a13144ffSStefano Zampini if (!rwork) { 54a13144ffSStefano Zampini ierr = PetscFree(sing);CHKERRQ(ierr); 55a13144ffSStefano Zampini } 56a13144ffSStefano Zampini if (!work) { 57a13144ffSStefano Zampini ierr = PetscFree(uwork);CHKERRQ(ierr); 58a13144ffSStefano Zampini } 59a13144ffSStefano Zampini /* create B */ 60a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 61a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 62a13144ffSStefano Zampini ierr = PetscMemcpy(data,U+nr*i,(nr-i)*nr*sizeof(PetscScalar));CHKERRQ(ierr); 63a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 64a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 65a13144ffSStefano Zampini #else 66a13144ffSStefano Zampini PetscFunctionBegin; 67a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for complexes"); 68a13144ffSStefano Zampini #endif 69a13144ffSStefano Zampini PetscFunctionReturn(0); 70a13144ffSStefano Zampini } 71a13144ffSStefano Zampini 72a13144ffSStefano Zampini #undef __FUNCT__ 73a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCComputeNedelecChangeEdge" 74a13144ffSStefano Zampini PetscErrorCode PCBDDCComputeNedelecChangeEdge(Mat lG, IS edge, IS extrow, IS extcol, Mat* Gins, Mat* GKins, PetscScalar *work, PetscReal *rwork) 75a13144ffSStefano Zampini { 76a13144ffSStefano Zampini PetscErrorCode ierr; 77a13144ffSStefano Zampini Mat GE,GEd; 78a13144ffSStefano Zampini PetscInt rsize,csize,esize; 79a13144ffSStefano Zampini PetscScalar *ptr; 80a13144ffSStefano Zampini 81a13144ffSStefano Zampini PetscFunctionBegin; 82a13144ffSStefano Zampini ierr = ISGetSize(edge,&esize);CHKERRQ(ierr); 83c3c0e390SStefano Zampini if (!esize) PetscFunctionReturn(0); 84a13144ffSStefano Zampini ierr = ISGetSize(extrow,&rsize);CHKERRQ(ierr); 85a13144ffSStefano Zampini ierr = ISGetSize(extcol,&csize);CHKERRQ(ierr); 86a13144ffSStefano Zampini 87a13144ffSStefano Zampini /* gradients */ 88a13144ffSStefano Zampini ptr = work + 5*esize; 89a13144ffSStefano Zampini ierr = MatGetSubMatrix(lG,extrow,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 90a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,rsize,csize,ptr,Gins);CHKERRQ(ierr); 91a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,Gins);CHKERRQ(ierr); 92a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 93a13144ffSStefano Zampini 94a13144ffSStefano Zampini /* constants */ 95a13144ffSStefano Zampini ptr += rsize*csize; 96a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,esize,csize,ptr,&GEd);CHKERRQ(ierr); 97a13144ffSStefano Zampini ierr = MatGetSubMatrix(lG,edge,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 98a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,&GEd);CHKERRQ(ierr); 99a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 100a13144ffSStefano Zampini ierr = MatDense_OrthogonalComplement(GEd,5*esize,work,rwork,GKins);CHKERRQ(ierr); 101a13144ffSStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 102a13144ffSStefano Zampini PetscFunctionReturn(0); 103a13144ffSStefano Zampini } 104a13144ffSStefano Zampini 105a13144ffSStefano Zampini #undef __FUNCT__ 106a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCNedelecSupport" 107a13144ffSStefano Zampini PetscErrorCode PCBDDCNedelecSupport(PC pc) 108a13144ffSStefano Zampini { 109a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 110a13144ffSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1110569b399SStefano Zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe,lGinit; 112a13144ffSStefano Zampini MatNullSpace nnsp; 113a13144ffSStefano Zampini Vec tvec,*quads; 114a13144ffSStefano Zampini PetscSF sfv; 115c2151214SStefano Zampini ISLocalToGlobalMapping el2g,vl2g,fl2g; 116a13144ffSStefano Zampini MPI_Comm comm; 117c2151214SStefano Zampini IS lned,primals,allprimals,nedfieldlocal; 118c2151214SStefano Zampini IS *eedges,*extrows,*extcols,*alleedges; 119c2151214SStefano Zampini PetscBT btv,bte,btvc,btb,btvcand,btvi,btee; 120a13144ffSStefano Zampini PetscScalar *vals,*work; 121a13144ffSStefano Zampini PetscReal *rwork; 122a13144ffSStefano Zampini const PetscInt *idxs,*ii,*jj,*iit,*jjt; 123c2151214SStefano Zampini PetscInt ne,nv,Lv,order,n,field; 124a13144ffSStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 125a13144ffSStefano Zampini PetscInt i,j,extmem,cum,maxsize,rst,nee,nquads=2; 126a13144ffSStefano Zampini PetscInt *extrow,*extrowcum,*marks,*emarks,*vmarks,*gidxs; 127a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 128c2151214SStefano Zampini PetscBool print,eerr,done,lrc[2],conforming; 129a13144ffSStefano Zampini PetscErrorCode ierr; 130a13144ffSStefano Zampini 131a13144ffSStefano Zampini PetscFunctionBegin; 132a13144ffSStefano Zampini /* test variable order code and print debug info TODO: to be removed */ 133a13144ffSStefano Zampini print = PETSC_FALSE; 134a13144ffSStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_print_nedelec",&print,NULL);CHKERRQ(ierr); 135a13144ffSStefano Zampini ierr = PetscOptionsGetInt(NULL,NULL,"-pc_bddc_nedelec_order",&pcbddc->nedorder,NULL);CHKERRQ(ierr); 136a13144ffSStefano Zampini 137a13144ffSStefano Zampini /* Return to caller if there are no edges in the decomposition */ 138a13144ffSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 139a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&el2g,NULL);CHKERRQ(ierr); 140c2151214SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(el2g,&n);CHKERRQ(ierr); 141a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 142a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 143c2151214SStefano Zampini for (i=0;i<n;i++) { 144a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 145a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 146a13144ffSStefano Zampini break; 147a13144ffSStefano Zampini } 148a13144ffSStefano Zampini } 149a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 150a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 151a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 152a13144ffSStefano Zampini 153c2151214SStefano Zampini /* Get discrete gradient 154c2151214SStefano Zampini If it is defined for a subset of dofs, assumes G is given in global ordering for all the dofs */ 155a13144ffSStefano Zampini G = pcbddc->discretegradient; 156a13144ffSStefano Zampini order = pcbddc->nedorder; 157a13144ffSStefano Zampini conforming = pcbddc->conforming; 158c2151214SStefano Zampini field = pcbddc->nedfield; 159c2151214SStefano 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); 160c2151214SStefano Zampini if (pcbddc->n_ISForDofsLocal && field > -1) { 161c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 162c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 163c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 164c2151214SStefano Zampini } else { 165c2151214SStefano Zampini PetscBool testnedfield = PETSC_FALSE; 166c2151214SStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_nedelec_field",&testnedfield,NULL);CHKERRQ(ierr); 167c2151214SStefano Zampini if (!testnedfield) { 168c2151214SStefano Zampini ne = n; 169c2151214SStefano Zampini nedfieldlocal = NULL; 170c2151214SStefano Zampini } else { 171c2151214SStefano Zampini /* ierr = ISCreateStride(comm,n,0,1,&nedfieldlocal);CHKERRQ(ierr); */ 172c2151214SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 173c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 174c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 175c2151214SStefano Zampini for (i=0;i<n;i++) matis->sf_leafdata[i] = 1; 176c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 177c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 178c2151214SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 179c2151214SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 180c2151214SStefano Zampini for (i=0,cum=0;i<n;i++) { 181c2151214SStefano Zampini if (matis->sf_leafdata[i] > 1) { 182c2151214SStefano Zampini matis->sf_leafdata[cum++] = i; 183c2151214SStefano Zampini } 184c2151214SStefano Zampini } 185c2151214SStefano Zampini ierr = ISCreateGeneral(comm,cum,matis->sf_leafdata,PETSC_COPY_VALUES,&nedfieldlocal);CHKERRQ(ierr); 186c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 187c2151214SStefano Zampini } 188c2151214SStefano Zampini } 189a13144ffSStefano Zampini 190c2151214SStefano Zampini if (nedfieldlocal) { /* merge with previous code when testing is done */ 191c2151214SStefano Zampini IS is; 192c2151214SStefano Zampini 193c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 194c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 195c2151214SStefano Zampini /* need to map from the local Nedelec field to global numbering */ 196c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,nedfieldlocal,&is);CHKERRQ(ierr); 197c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&el2g);CHKERRQ(ierr); 198c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 199c2151214SStefano Zampini } else { 200c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)el2g);CHKERRQ(ierr); 201c2151214SStefano Zampini fl2g = NULL; 202c2151214SStefano Zampini } 203a13144ffSStefano Zampini 204a13144ffSStefano Zampini /* Sanity checks */ 205a13144ffSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 206a13144ffSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 207a13144ffSStefano 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); 208a13144ffSStefano Zampini 209a13144ffSStefano Zampini /* Drop connections for interior edges (this modifies G) */ 210c2151214SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 211c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 212c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 213c2151214SStefano Zampini if (nedfieldlocal) { 214c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 215c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 216c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 217c2151214SStefano Zampini } else { 218c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 219c2151214SStefano Zampini } 220c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 221c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 222c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 223c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 224c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 225c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 226c2151214SStefano Zampini } 227c2151214SStefano Zampini } 228a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 229a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 230c2151214SStefano Zampini ierr = MatZeroRows(G,cum,matis->sf_rootdata,0.,NULL,NULL);CHKERRQ(ierr); 231a13144ffSStefano Zampini 232a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 233a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 234a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 235a13144ffSStefano Zampini ierr = MatGetSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 236a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 237a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 238a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 239a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 240a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 241a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 242a13144ffSStefano Zampini if (print) { 243a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 244a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 245a13144ffSStefano Zampini } 246a13144ffSStefano Zampini 247a13144ffSStefano Zampini /* SF for nodal communications */ 248c2151214SStefano Zampini ierr = MatGetLocalSize(G,NULL,&Lv);CHKERRQ(ierr); 249a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 250a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 251a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 252a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 253a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 254a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 255a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 256a13144ffSStefano Zampini ierr = PetscMalloc2(nv,&sfvleaves,Lv,&sfvroots);CHKERRQ(ierr); 257a13144ffSStefano Zampini 258a13144ffSStefano Zampini /* Destroy temporary G created in MATIS format */ 259a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 260a13144ffSStefano Zampini 2610569b399SStefano Zampini /* Save lG */ 2620569b399SStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGinit);CHKERRQ(ierr); 2630569b399SStefano Zampini 264a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 2654e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 2664e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 267a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 268a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 269a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 270c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 271a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 272a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 273a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 274c2151214SStefano Zampini IS is; 275c2151214SStefano Zampini 276c2151214SStefano Zampini if (fl2g) { 277c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 278c2151214SStefano Zampini } else { 279c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 280c2151214SStefano Zampini } 281c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 282c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 283a13144ffSStefano Zampini for (i=0;i<cum;i++) { 284a13144ffSStefano Zampini if (idxs[i] >= 0) { 285a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 286a13144ffSStefano Zampini } 287a13144ffSStefano Zampini } 288c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 289c2151214SStefano Zampini if (fl2g) { 290c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 291c2151214SStefano Zampini } 292a13144ffSStefano Zampini } 293a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 294c2151214SStefano Zampini IS is; 295c2151214SStefano Zampini 296c2151214SStefano Zampini if (fl2g) { 297c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 298c2151214SStefano Zampini } else { 299c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 300c2151214SStefano Zampini } 301c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 302c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 303a13144ffSStefano Zampini for (i=0;i<cum;i++) { 304a13144ffSStefano Zampini if (idxs[i] >= 0) { 305a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 306a13144ffSStefano Zampini } 307a13144ffSStefano Zampini } 308c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 309c2151214SStefano Zampini if (fl2g) { 310c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 311a13144ffSStefano Zampini } 312c2151214SStefano Zampini } 313c2151214SStefano Zampini 314a13144ffSStefano Zampini /* need to remove coarse faces' dofs to ensure the 315a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 316a13144ffSStefano Zampini ierr = PetscCalloc1(ne,&marks);CHKERRQ(ierr); 31762b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 318a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 31962b0c6f7SStefano Zampini for (i=1;i<n_neigh;i++) 32062b0c6f7SStefano Zampini for (j=0;j<n_shared[i];j++) 32162b0c6f7SStefano Zampini marks[shared[i][j]]++; 322a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 32362b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 32462b0c6f7SStefano Zampini if (marks[i] > 1 || (marks[i] == 1 && PetscBTLookup(btb,i))) { 32562b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 32662b0c6f7SStefano Zampini } 32762b0c6f7SStefano Zampini } 32862b0c6f7SStefano Zampini 32962b0c6f7SStefano Zampini if (!conforming) { 33062b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 33162b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 33262b0c6f7SStefano Zampini } 3334e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 334dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 33562b0c6f7SStefano Zampini cum = 0; 336a13144ffSStefano Zampini for (i=0;i<ne;i++) { 337dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 33862b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 339a13144ffSStefano Zampini marks[cum++] = i; 340dec27d64SStefano Zampini continue; 341dec27d64SStefano Zampini } 342dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 34362b0c6f7SStefano Zampini if (!conforming) { 34462b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 345a13144ffSStefano Zampini marks[cum++] = i; 346a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 347a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 348a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 349a13144ffSStefano Zampini } 35062b0c6f7SStefano Zampini } else { 35162b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 35262b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 35362b0c6f7SStefano Zampini - at most 2 endpoints 35462b0c6f7SStefano Zampini - order-1 interior nodal dofs 35562b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 35662b0c6f7SStefano Zampini */ 35762b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 35862b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 35962b0c6f7SStefano Zampini PetscInt v = jj[j],k; 36062b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 36162b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 36262b0c6f7SStefano Zampini if (nconn > order) ends++; 36362b0c6f7SStefano Zampini else if (nconn == order) ints++; 36462b0c6f7SStefano Zampini else undef++; 36562b0c6f7SStefano Zampini } 36662b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 36762b0c6f7SStefano Zampini marks[cum++] = i; 36862b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 36962b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 37062b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 37162b0c6f7SStefano Zampini } 37262b0c6f7SStefano Zampini } 37362b0c6f7SStefano Zampini } 374a13144ffSStefano Zampini } 375dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 376dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 377dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 378dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 379a13144ffSStefano Zampini } 380dec27d64SStefano Zampini } 38162b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 382dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 3834e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 38462b0c6f7SStefano Zampini if (!conforming) { 38562b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 38662b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 38762b0c6f7SStefano Zampini } 3884e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 389a13144ffSStefano Zampini /* identify splitpoints and corner candidates: TODO variable order */ 3904e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 391a13144ffSStefano Zampini if (print) { 3924e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 3934e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 3944e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 395a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 396a13144ffSStefano Zampini } 3970569b399SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 398a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 399dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 400a13144ffSStefano Zampini for (i=0;i<nv;i++) { 401dec27d64SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i]; 402dec27d64SStefano Zampini if (!order) { 403dec27d64SStefano Zampini PetscReal vorder = 0.; 404dec27d64SStefano Zampini 405dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 406dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 407dec27d64SStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%d)",vorder,test); 408dec27d64SStefano Zampini ord = 1; 409dec27d64SStefano Zampini } 410a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 411dec27d64SStefano 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); 412a13144ffSStefano Zampini #endif 413dec27d64SStefano Zampini if (test >= 3*ord) { /* splitpoints */ 414a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d\n",i); 415a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 416dec27d64SStefano Zampini } else if (test == ord) { 417a13144ffSStefano Zampini if (order == 1) { 418a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 419a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 420a13144ffSStefano Zampini } else { 421a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 422a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 423a13144ffSStefano Zampini } 424a13144ffSStefano Zampini } 425a13144ffSStefano Zampini } 426dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 427a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 428a13144ffSStefano Zampini 429a13144ffSStefano Zampini /* Get the local G^T explicitly */ 4300569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 431a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 4324e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 433a13144ffSStefano Zampini 4344e64d54eSstefano_zampini /* Mark interior nodal dofs */ 435a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 4364e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 437a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 438a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 4394e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 440a13144ffSStefano Zampini } 441a13144ffSStefano Zampini } 442a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 443a13144ffSStefano Zampini 444a13144ffSStefano Zampini /* communicate corners and splitpoints */ 445a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 446a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 447a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 448a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 449a13144ffSStefano Zampini 450a13144ffSStefano Zampini if (print) { 451a13144ffSStefano Zampini IS tbz; 452a13144ffSStefano Zampini 453a13144ffSStefano Zampini cum = 0; 454a13144ffSStefano Zampini for (i=0;i<nv;i++) 455a13144ffSStefano Zampini if (sfvleaves[i]) 456a13144ffSStefano Zampini vmarks[cum++] = i; 457a13144ffSStefano Zampini 458a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 459a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 460a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 461a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 462a13144ffSStefano Zampini } 463a13144ffSStefano Zampini 464a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 465a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 466a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 467a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 468a13144ffSStefano Zampini 4694e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 4704e64d54eSstefano_zampini and interior nodal dofs */ 471a13144ffSStefano Zampini cum = 0; 472a13144ffSStefano Zampini for (i=0;i<nv;i++) { 473a13144ffSStefano Zampini if (sfvleaves[i]) { 474a13144ffSStefano Zampini vmarks[cum++] = i; 475a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 476a13144ffSStefano Zampini } 4774e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 478a13144ffSStefano Zampini } 4794e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 480a13144ffSStefano Zampini if (print) { 481a13144ffSStefano Zampini IS tbz; 482a13144ffSStefano Zampini 483a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 4844e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 485a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 486a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 487a13144ffSStefano Zampini } 488a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 489a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 490a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 491a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 492a13144ffSStefano Zampini 493a13144ffSStefano Zampini /* Recompute G */ 494a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 495a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 496a13144ffSStefano Zampini if (print) { 497a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 498a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 499a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 500a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 501a13144ffSStefano Zampini } 502a13144ffSStefano Zampini 503a13144ffSStefano Zampini /* Get primal dofs (if any) */ 504a13144ffSStefano Zampini cum = 0; 505a13144ffSStefano Zampini for (i=0;i<ne;i++) { 506a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 507a13144ffSStefano Zampini } 508c2151214SStefano Zampini if (fl2g) { 509c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 510c2151214SStefano Zampini } 511a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 512a13144ffSStefano Zampini if (print) { 513a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 514a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 515a13144ffSStefano Zampini } 516a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 517c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 518a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 519a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 520a13144ffSStefano Zampini 521a13144ffSStefano Zampini /* Compute edge connectivity */ 522a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 523a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 524a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 525d904f53bSStefano Zampini if (done && i && ii && jj) { /* when lG is empty, don't pass pointers */ 526c2151214SStefano Zampini if (fl2g) { 527c2151214SStefano Zampini PetscBT btf; 528c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 529c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 530c2151214SStefano Zampini 531c2151214SStefano Zampini /* create CSR for all local dofs */ 532c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 533c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 534c2151214SStefano 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); 535c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 536c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 537c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 538c2151214SStefano Zampini rest = PETSC_TRUE; 539c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 540c2151214SStefano Zampini } else { 541c2151214SStefano Zampini free = PETSC_TRUE; 542c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 543c2151214SStefano Zampini iiu[0] = 0; 544c2151214SStefano Zampini for (i=0;i<n;i++) { 545c2151214SStefano Zampini iiu[i+1] = i+1; 546c2151214SStefano Zampini jju[i] = -1; 547d904f53bSStefano Zampini } 548c2151214SStefano Zampini } 549c2151214SStefano Zampini 550c2151214SStefano Zampini /* import sizes of CSR */ 551c2151214SStefano Zampini iia[0] = 0; 552c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 553c2151214SStefano Zampini 554c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 555c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 556c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 557c2151214SStefano Zampini for (i=0;i<ne;i++) { 558c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 559c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 560c2151214SStefano Zampini } 561c2151214SStefano Zampini 562c2151214SStefano Zampini /* iia in CSR */ 563c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 564c2151214SStefano Zampini 565c2151214SStefano Zampini /* jja in CSR */ 566c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 567c2151214SStefano Zampini for (i=0;i<n;i++) 568c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 569c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 570c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 571c2151214SStefano Zampini 572c2151214SStefano Zampini /* map edge dofs connectivity */ 573c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 574c2151214SStefano Zampini for (i=0;i<ne;i++) { 575c2151214SStefano Zampini PetscInt e = idxs[i]; 576c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 577c2151214SStefano Zampini } 578c2151214SStefano Zampini 579c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 580c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 581c2151214SStefano Zampini if (rest) { 582c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 583c2151214SStefano Zampini } 584c2151214SStefano Zampini if (free) { 585c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 586c2151214SStefano Zampini } 587c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 588c2151214SStefano Zampini } else { 589c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 590c2151214SStefano Zampini } 591c2151214SStefano Zampini } 592c2151214SStefano Zampini 593a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 594a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 595a13144ffSStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 596a13144ffSStefano Zampini 597a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 598a13144ffSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 599c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 600a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 601a13144ffSStefano Zampini 602c2151214SStefano Zampini if (fl2g) { 603c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 604c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 605c2151214SStefano Zampini for (i=0;i<nee;i++) { 606c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 607c2151214SStefano Zampini } 608c2151214SStefano Zampini } else { 609c2151214SStefano Zampini eedges = alleedges; 610c2151214SStefano Zampini primals = allprimals; 611c2151214SStefano Zampini } 612c2151214SStefano Zampini 613a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 614a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 615c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 616c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 617c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 618c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 619c2151214SStefano Zampini if (print) { 620c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 621c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 622c2151214SStefano Zampini } 623c2151214SStefano Zampini 624c2151214SStefano Zampini maxsize = 0; 625a13144ffSStefano Zampini for (i=0;i<nee;i++) { 626a13144ffSStefano Zampini PetscInt size,mark = i+1; 627a13144ffSStefano Zampini 628a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 629a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 630a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 631a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 632a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 633a13144ffSStefano Zampini } 634a13144ffSStefano Zampini 635a13144ffSStefano Zampini /* Find coarse edge endpoints */ 636a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 637a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 638a13144ffSStefano Zampini for (i=0;i<nee;i++) { 639a13144ffSStefano Zampini PetscInt mark = i+1,size; 640a13144ffSStefano Zampini 641a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 642a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 643a13144ffSStefano Zampini if (print) { 644a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 645a13144ffSStefano Zampini ISView(eedges[i],NULL); 646a13144ffSStefano Zampini } 647a13144ffSStefano Zampini for (j=0;j<size;j++) { 648a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 649a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 650a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 651a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 652a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 653a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 654a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 655a13144ffSStefano Zampini PetscInt k2; 656a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 657a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 658c2151214SStefano 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])); 659c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 660c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 661c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 662a13144ffSStefano Zampini corner = PETSC_TRUE; 663a13144ffSStefano Zampini break; 664a13144ffSStefano Zampini } 665a13144ffSStefano Zampini } 666a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 667a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 668a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 669a13144ffSStefano Zampini } else { 670a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 671a13144ffSStefano Zampini } 672a13144ffSStefano Zampini } 673a13144ffSStefano Zampini } 674a13144ffSStefano Zampini } 675a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 676a13144ffSStefano Zampini } 677a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 678a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 679c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 680a13144ffSStefano Zampini 681a13144ffSStefano Zampini /* Reset marked primal dofs */ 682a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 683a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 684a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 685a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 686a13144ffSStefano Zampini 6870569b399SStefano Zampini /* Now use the initial lG */ 6880569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 6890569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 6900569b399SStefano Zampini lG = lGinit; 6910569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 6920569b399SStefano Zampini 693a13144ffSStefano Zampini /* Compute extended cols indices */ 694a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 695a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 696a13144ffSStefano Zampini i *= maxsize; 697a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extcols);CHKERRQ(ierr); 698a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&emarks);CHKERRQ(ierr); 699a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 700a13144ffSStefano Zampini eerr = PETSC_FALSE; 701a13144ffSStefano Zampini for (i=0;i<nee;i++) { 702a13144ffSStefano Zampini PetscInt size; 703a13144ffSStefano Zampini 704a13144ffSStefano Zampini cum = 0; 705a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 706a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 707a13144ffSStefano Zampini for (j=0;j<size;j++) { 708a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 709a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 710a13144ffSStefano Zampini } 711a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 712a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 713a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 714a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 715a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 716a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 717a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 718a13144ffSStefano Zampini if (cum != size -1) { 719a13144ffSStefano Zampini emarks[i] = 1; 720a13144ffSStefano Zampini if (print) { 721a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 722a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 723a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 724a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 725a13144ffSStefano Zampini } 726a13144ffSStefano Zampini eerr = PETSC_TRUE; 727a13144ffSStefano Zampini } 728a13144ffSStefano Zampini } 7294e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 730a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 731a13144ffSStefano Zampini if (done) { 732a13144ffSStefano Zampini PetscInt *newprimals; 733a13144ffSStefano Zampini 734a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 735a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 736a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 737a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 738a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 7390569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 740a13144ffSStefano Zampini for (i=0;i<nee;i++) { 741a13144ffSStefano Zampini if (emarks[i]) { 742a13144ffSStefano Zampini PetscInt size,mark = i+1; 743a13144ffSStefano Zampini 744a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 745a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 746c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 747a13144ffSStefano Zampini for (j=0;j<size;j++) { 748a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 749a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 750a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 751a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 752a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 753a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 754a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 755a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 756a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 757a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 758a13144ffSStefano Zampini newprimals[cum++] = ee2; 759a13144ffSStefano Zampini /* finally set the new corners */ 760a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 761a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 762a13144ffSStefano Zampini } 763a13144ffSStefano Zampini } 764a13144ffSStefano Zampini } 765a13144ffSStefano Zampini } 766a13144ffSStefano Zampini } 767a13144ffSStefano Zampini } 768a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 769a13144ffSStefano Zampini } 770a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 771a13144ffSStefano Zampini } 7720569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 773a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 774c2151214SStefano Zampini if (fl2g) { 775c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 776c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 777c2151214SStefano Zampini for (i=0;i<nee;i++) { 778c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 779c2151214SStefano Zampini } 780c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 781c2151214SStefano Zampini } 782c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 783a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 784a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 785a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 786a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 787a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 788c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 789c2151214SStefano Zampini if (fl2g) { 790c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 791c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 792c2151214SStefano Zampini for (i=0;i<nee;i++) { 793c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 794c2151214SStefano Zampini } 795c2151214SStefano Zampini } else { 796c2151214SStefano Zampini eedges = alleedges; 797c2151214SStefano Zampini primals = allprimals; 798c2151214SStefano Zampini } 799a13144ffSStefano Zampini 800a13144ffSStefano Zampini /* Mark again */ 801a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 802a13144ffSStefano Zampini for (i=0;i<nee;i++) { 803a13144ffSStefano Zampini PetscInt size,mark = i+1; 804a13144ffSStefano Zampini 805a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 806a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 807a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 808a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 809a13144ffSStefano Zampini } 810a13144ffSStefano Zampini if (print) { 811a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 812a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 813a13144ffSStefano Zampini } 814a13144ffSStefano Zampini 815a13144ffSStefano Zampini /* Recompute extended cols */ 816a13144ffSStefano Zampini eerr = PETSC_FALSE; 817a13144ffSStefano Zampini for (i=0;i<nee;i++) { 818a13144ffSStefano Zampini PetscInt size; 819a13144ffSStefano Zampini 820a13144ffSStefano Zampini cum = 0; 821a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 822a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 823a13144ffSStefano Zampini for (j=0;j<size;j++) { 824a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 825a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 826a13144ffSStefano Zampini if (!PetscBTLookup(btv,jj[k])) { 827a13144ffSStefano Zampini extrow[cum++] = jj[k]; 828a13144ffSStefano Zampini } 829a13144ffSStefano Zampini } 830a13144ffSStefano Zampini } 831a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 832a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 833a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 834a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 835a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 836a13144ffSStefano Zampini if (cum != size -1) { 837a13144ffSStefano Zampini if (print) { 838a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 839a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 840a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 841a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 842a13144ffSStefano Zampini } 843a13144ffSStefano Zampini eerr = PETSC_TRUE; 844a13144ffSStefano Zampini } 845a13144ffSStefano Zampini } 846a13144ffSStefano Zampini } 847a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 848a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 849a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 850a13144ffSStefano Zampini /* an error should not occur at this point */ 851a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 852a13144ffSStefano Zampini 8534e64d54eSstefano_zampini /* Check the number of endpoints */ 854c2151214SStefano Zampini /* TODO: fix case for circular edge */ 8554e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 8560569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 8574e64d54eSstefano_zampini for (i=0;i<nee;i++) { 8584e64d54eSstefano_zampini PetscInt size, found = 0; 8594e64d54eSstefano_zampini 8604e64d54eSstefano_zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 8614e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8624e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 8634e64d54eSstefano_zampini for (j=0;j<size;j++) { 8644e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 8654e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 8664e64d54eSstefano_zampini PetscInt vv = jj[k]; 8674e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 8684e64d54eSstefano_zampini found++; 8694e64d54eSstefano_zampini } 8704e64d54eSstefano_zampini } 8714e64d54eSstefano_zampini } 8724e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 8734e64d54eSstefano_zampini if (found != 2) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %d corners for edge %d\n",found,i); 8744e64d54eSstefano_zampini } 8750569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 8764e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 8774e64d54eSstefano_zampini 878a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 879a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 880a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 881a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 882a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 883a13144ffSStefano Zampini for (i=0;i<nv;i++) { 884a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 885a13144ffSStefano Zampini 886a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 887a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 888a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 889a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 890a13144ffSStefano Zampini if (emax < emarks[j]) { 891a13144ffSStefano Zampini emax = emarks[j]; 892a13144ffSStefano Zampini eemax = j; 893a13144ffSStefano Zampini } 894a13144ffSStefano Zampini } 895a13144ffSStefano Zampini /* not relevant for edges */ 896a13144ffSStefano Zampini if (!eemax) continue; 897a13144ffSStefano Zampini 898a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 899a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 900c2151214SStefano 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]); 901a13144ffSStefano Zampini } 902a13144ffSStefano Zampini } 903a13144ffSStefano Zampini } 904a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 905a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 906a13144ffSStefano Zampini #endif 907a13144ffSStefano Zampini 908a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 909a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 910a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 911a13144ffSStefano Zampini extmem *= maxsize; 912a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 913a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 914a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 915a13144ffSStefano Zampini for (i=0;i<nv;i++) { 916a13144ffSStefano Zampini PetscInt mark = 0,size,start; 917a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 918a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 919a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 920a13144ffSStefano Zampini mark = marks[jj[j]]; 921a13144ffSStefano Zampini 922a13144ffSStefano Zampini /* not relevant */ 923a13144ffSStefano Zampini if (!mark) continue; 924a13144ffSStefano Zampini 925a13144ffSStefano Zampini /* import extended row */ 926a13144ffSStefano Zampini mark--; 927a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 928a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 929a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 930a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 931a13144ffSStefano Zampini extrowcum[mark] += size; 932a13144ffSStefano Zampini } 933a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 934a13144ffSStefano Zampini cum = 0; 935a13144ffSStefano Zampini for (i=0;i<nee;i++) { 936a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 937a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 938a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 939a13144ffSStefano Zampini cum = PetscMax(cum,size); 940a13144ffSStefano Zampini } 941a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 942a13144ffSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 943a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 944a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 945a13144ffSStefano Zampini 946a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 947a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 948a13144ffSStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 949a13144ffSStefano Zampini for (i=0;i<maxsize;i++) vals[i] = 1.; 950a13144ffSStefano Zampini 951a13144ffSStefano Zampini /* Create vectors for quadrature rules */ 952c2151214SStefano Zampini /* TODO preserve other quadratures */ 953a13144ffSStefano Zampini ierr = PetscMalloc1(nquads,&quads);CHKERRQ(ierr); 954a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 955a13144ffSStefano Zampini ierr = MatCreateVecs(pc->pmat,&quads[i],NULL);CHKERRQ(ierr); 956a13144ffSStefano Zampini ierr = VecSetLocalToGlobalMapping(quads[i],el2g);CHKERRQ(ierr); 957a13144ffSStefano Zampini } 958a13144ffSStefano Zampini ierr = PCBDDCNullSpaceCreate(comm,PETSC_FALSE,nquads,quads,&nnsp);CHKERRQ(ierr); 959a13144ffSStefano Zampini 960a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 961a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 962c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 963c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 964a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 965a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 966a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 967a13144ffSStefano Zampini ierr = MatSetLocalToGlobalMapping(T,el2g,el2g);CHKERRQ(ierr); 968a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 969a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 970a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 971a13144ffSStefano Zampini 972a13144ffSStefano Zampini /* Defaults to identity */ 973c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 974a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 975a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 976a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 977a13144ffSStefano Zampini 978a13144ffSStefano Zampini for (i=0;i<nee;i++) { 979a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 980a13144ffSStefano Zampini 981a13144ffSStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],&Gins,&GKins,work,rwork);CHKERRQ(ierr); 982a13144ffSStefano Zampini if (Gins && GKins) { 983a13144ffSStefano Zampini PetscScalar *data; 984a13144ffSStefano Zampini const PetscInt *rows,*cols; 985a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 986a13144ffSStefano Zampini 987a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 988a13144ffSStefano Zampini /* H1 */ 989a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 990a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 991a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 992a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 993a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 994a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 995a13144ffSStefano Zampini /* complement */ 996a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 997a13144ffSStefano Zampini if (ncc > nquads-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet supported ncc %d nquads %d",ncc,nquads); 998a13144ffSStefano 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); 999a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 1000a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 1001a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 1002a13144ffSStefano Zampini /* Gins kernel quadratures */ 1003a13144ffSStefano Zampini for (j=0;j<ncc;j++) { 1004a13144ffSStefano Zampini ierr = VecSetValueLocal(quads[j],cols[nch+j],1.,INSERT_VALUES);CHKERRQ(ierr); 1005a13144ffSStefano Zampini } 1006a13144ffSStefano Zampini /* H1 average */ 1007a13144ffSStefano Zampini ierr = VecSetValuesLocal(quads[nquads-1],nch,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 1008a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1009a13144ffSStefano Zampini } 1010a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1011a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 1012a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1013a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1014a13144ffSStefano Zampini } 1015a13144ffSStefano Zampini 1016a13144ffSStefano Zampini /* Start assembling */ 1017a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1018a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 1019a13144ffSStefano Zampini ierr = VecAssemblyBegin(quads[i]);CHKERRQ(ierr); 1020a13144ffSStefano Zampini } 1021a13144ffSStefano Zampini 1022a13144ffSStefano Zampini /* Free */ 1023c2151214SStefano Zampini if (fl2g) { 1024c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1025c2151214SStefano Zampini for (i=0;i<nee;i++) { 1026c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1027c2151214SStefano Zampini } 1028c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1029c2151214SStefano Zampini } 1030c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1031c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1032c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1033a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1034a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 1035c2151214SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 1036c2151214SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1037a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1038a13144ffSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1039a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1040a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1041a13144ffSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1042a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1043a13144ffSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1044a13144ffSStefano Zampini 1045a13144ffSStefano Zampini /* Complete assembling */ 1046a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1047a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 1048a13144ffSStefano Zampini ierr = VecAssemblyEnd(quads[i]);CHKERRQ(ierr); 1049a13144ffSStefano Zampini } 1050a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 1051a13144ffSStefano Zampini ierr = VecDestroy(&quads[i]);CHKERRQ(ierr); 1052a13144ffSStefano Zampini } 1053a13144ffSStefano Zampini ierr = PetscFree(quads);CHKERRQ(ierr); 1054a13144ffSStefano Zampini 1055a13144ffSStefano Zampini /* set change of basis */ 1056a13144ffSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,PETSC_FALSE);CHKERRQ(ierr); 1057a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1058a13144ffSStefano Zampini 1059a13144ffSStefano Zampini /* set quadratures */ 1060a13144ffSStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnsp);CHKERRQ(ierr); 1061a13144ffSStefano Zampini ierr = MatNullSpaceDestroy(&nnsp);CHKERRQ(ierr); 1062a13144ffSStefano Zampini 1063a13144ffSStefano Zampini PetscFunctionReturn(0); 1064a13144ffSStefano Zampini } 1065a13144ffSStefano Zampini 1066d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1067d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1068d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1069d8203eabSStefano Zampini #undef __FUNCT__ 1070d8203eabSStefano Zampini #define __FUNCT__ "PCBDDCNullSpaceCreate" 1071d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1072d8203eabSStefano Zampini { 1073d8203eabSStefano Zampini PetscErrorCode ierr; 1074d8203eabSStefano Zampini PetscInt i; 1075d8203eabSStefano Zampini 1076d8203eabSStefano Zampini PetscFunctionBegin; 1077d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1078d8203eabSStefano Zampini PetscInt first,last; 1079d8203eabSStefano Zampini 1080d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 108186fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1082d8203eabSStefano Zampini if (i>=first && i < last) { 1083d8203eabSStefano Zampini PetscScalar *data; 1084d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1085d8203eabSStefano Zampini if (!has_const) { 1086d8203eabSStefano Zampini data[i-first] = 1.; 1087d8203eabSStefano Zampini } else { 108886fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 108986fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1090d8203eabSStefano Zampini } 1091d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1092d8203eabSStefano Zampini } 1093d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1094d8203eabSStefano Zampini } 1095d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1096d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1097d8203eabSStefano Zampini PetscInt first,last; 1098d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1099d8203eabSStefano Zampini if (i>=first && i < last) { 1100d8203eabSStefano Zampini PetscScalar *data; 1101d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1102d8203eabSStefano Zampini if (!has_const) { 1103d8203eabSStefano Zampini data[i-first] = 0.; 1104d8203eabSStefano Zampini } else { 110586fa73c5SStefano Zampini data[2*i-first] = 0.; 110686fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1107d8203eabSStefano Zampini } 1108d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1109d8203eabSStefano Zampini } 1110d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1111d8203eabSStefano Zampini } 1112d8203eabSStefano Zampini PetscFunctionReturn(0); 1113d8203eabSStefano Zampini } 1114d8203eabSStefano Zampini 1115669cc0f4SStefano Zampini #undef __FUNCT__ 1116669cc0f4SStefano Zampini #define __FUNCT__ "PCBDDCComputeNoNetFlux" 11178ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1118669cc0f4SStefano Zampini { 1119a198735bSStefano Zampini Mat loc_divudotp; 1120fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 11218ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1122669cc0f4SStefano Zampini IS *faces,*edges; 1123669cc0f4SStefano Zampini PetscScalar *vals; 1124669cc0f4SStefano Zampini const PetscScalar *array; 1125669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 11261ae86dd6SStefano Zampini PetscMPIInt rank; 1127a198735bSStefano Zampini PetscErrorCode ierr; 1128669cc0f4SStefano Zampini 1129669cc0f4SStefano Zampini PetscFunctionBegin; 1130669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1131669cc0f4SStefano Zampini if (graph->twodim) { 1132669cc0f4SStefano Zampini lmaxneighs = 2; 1133669cc0f4SStefano Zampini } else { 1134669cc0f4SStefano Zampini lmaxneighs = 1; 1135669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1136669cc0f4SStefano Zampini const PetscInt *idxs; 1137669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1138669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 1139669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1140669cc0f4SStefano Zampini } 1141669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 1142669cc0f4SStefano Zampini } 1143669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 1144669cc0f4SStefano Zampini maxsize = 0; 1145669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1146669cc0f4SStefano Zampini PetscInt nn; 1147669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1148669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1149669cc0f4SStefano Zampini } 1150669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1151669cc0f4SStefano Zampini PetscInt nn; 1152669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1153669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1154669cc0f4SStefano Zampini } 1155669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1156669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1157669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 11588ae0ca82SStefano Zampini if (!transpose) { 11598ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 11608ae0ca82SStefano Zampini } else { 11618ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 11628ae0ca82SStefano Zampini } 1163669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 11641ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1165d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1166669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 11678ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1168669cc0f4SStefano Zampini } 1169d8203eabSStefano Zampini 1170669cc0f4SStefano Zampini /* compute local quad vec */ 1171a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 11728ae0ca82SStefano Zampini if (!transpose) { 1173a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 11748ae0ca82SStefano Zampini } else { 11758ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 11768ae0ca82SStefano Zampini } 1177669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 11788ae0ca82SStefano Zampini if (!transpose) { 1179a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 11808ae0ca82SStefano Zampini } else { 11818ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 11828ae0ca82SStefano Zampini } 1183fa23a32eSStefano Zampini if (vl2l) { 1184fa23a32eSStefano Zampini ierr = VecGetSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1185fa23a32eSStefano Zampini } else { 1186fa23a32eSStefano Zampini vins = v; 1187fa23a32eSStefano Zampini } 1188fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1189669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 11909a962809SStefano Zampini 11911ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 11921ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1193669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1194669cc0f4SStefano Zampini const PetscInt *idxs; 1195669cc0f4SStefano Zampini PetscInt idx,nn,j; 1196669cc0f4SStefano Zampini 1197669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 1198669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1199669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 12001ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1201669cc0f4SStefano Zampini idx = -(idx+1); 1202669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1203669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 1204669cc0f4SStefano Zampini } 1205669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1206669cc0f4SStefano Zampini const PetscInt *idxs; 1207669cc0f4SStefano Zampini PetscInt idx,nn,j; 1208669cc0f4SStefano Zampini 1209669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1210669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1211669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 12121ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1213669cc0f4SStefano Zampini idx = -(idx+1); 1214669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1215669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1216669cc0f4SStefano Zampini } 1217c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1218fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1219fa23a32eSStefano Zampini if (vl2l) { 1220fa23a32eSStefano Zampini ierr = VecRestoreSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1221fa23a32eSStefano Zampini } 1222669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1223669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1224669cc0f4SStefano Zampini 1225669cc0f4SStefano Zampini /* assemble near null space */ 1226669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1227669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1228669cc0f4SStefano Zampini } 1229669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1230669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 1231669cc0f4SStefano Zampini } 1232669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1233669cc0f4SStefano Zampini PetscFunctionReturn(0); 1234669cc0f4SStefano Zampini } 1235669cc0f4SStefano Zampini 1236669cc0f4SStefano Zampini 1237a3df083aSStefano Zampini #undef __FUNCT__ 12381f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 12391f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 12401f4df5f7SStefano Zampini { 12411f4df5f7SStefano Zampini PetscErrorCode ierr; 12421f4df5f7SStefano Zampini Vec local,global; 12431f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12441f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 12451f4df5f7SStefano Zampini 12461f4df5f7SStefano Zampini PetscFunctionBegin; 12471f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 12481f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 12491f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 12501f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 12511f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 12521f4df5f7SStefano Zampini PetscInt i; 12531f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 12541f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 12551f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 12561f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 12571f4df5f7SStefano Zampini } 12581f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 12591f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 12601f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 12611f4df5f7SStefano Zampini } 12621f4df5f7SStefano Zampini } else { 1263986cdee1SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering if bs > 1 */ 12641f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1265986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 1266986cdee1SStefano Zampini if (i > 1) { 1267986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 12681f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 12691f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 12701f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 12711f4df5f7SStefano Zampini } 12721f4df5f7SStefano Zampini } 12731f4df5f7SStefano Zampini } 1274986cdee1SStefano Zampini } 12751f4df5f7SStefano Zampini 12761f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 12771f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 12781f4df5f7SStefano Zampini } 12791f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 12801f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 12811f4df5f7SStefano Zampini } 12821f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 12831f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 12841f4df5f7SStefano Zampini } 12851f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 12861f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 12871f4df5f7SStefano Zampini PetscFunctionReturn(0); 12881f4df5f7SStefano Zampini } 12891f4df5f7SStefano Zampini 12901f4df5f7SStefano Zampini #undef __FUNCT__ 12913e589ea0SStefano Zampini #define __FUNCT__ "PCBDDCBenignRemoveInterior" 12923e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 12933e589ea0SStefano Zampini { 12943e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 12953e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 12963e589ea0SStefano Zampini PetscErrorCode ierr; 12973e589ea0SStefano Zampini 12983e589ea0SStefano Zampini PetscFunctionBegin; 12993e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 13003e589ea0SStefano Zampini PetscFunctionReturn(0); 13013e589ea0SStefano Zampini } 13023e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 13033e589ea0SStefano Zampini Vec swap; 13043e589ea0SStefano Zampini 13053e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 13063e589ea0SStefano Zampini swap = pcbddc->work_change; 13073e589ea0SStefano Zampini pcbddc->work_change = r; 13083e589ea0SStefano Zampini r = swap; 13093e589ea0SStefano Zampini } 13103e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13113e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13123e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 13133e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 13143e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13153e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13163e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1317f913dca9SStefano Zampini pcbddc->work_change = r; 13183e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 13193e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 13203e589ea0SStefano Zampini } 13213e589ea0SStefano Zampini PetscFunctionReturn(0); 13223e589ea0SStefano Zampini } 13233e589ea0SStefano Zampini 13243e589ea0SStefano Zampini #undef __FUNCT__ 1325a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 1326a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1327a3df083aSStefano Zampini { 1328a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1329a3df083aSStefano Zampini PetscErrorCode ierr; 1330a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1331a3df083aSStefano Zampini 1332a3df083aSStefano Zampini PetscFunctionBegin; 1333a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1334a3df083aSStefano Zampini if (transpose) { 1335a3df083aSStefano Zampini apply_right = ctx->apply_left; 1336a3df083aSStefano Zampini apply_left = ctx->apply_right; 1337a3df083aSStefano Zampini } else { 1338a3df083aSStefano Zampini apply_right = ctx->apply_right; 1339a3df083aSStefano Zampini apply_left = ctx->apply_left; 1340a3df083aSStefano Zampini } 1341a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1342a3df083aSStefano Zampini if (apply_right) { 1343a3df083aSStefano Zampini const PetscScalar *ax; 1344a3df083aSStefano Zampini PetscInt nl,i; 1345a3df083aSStefano Zampini 1346a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1347a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1348a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1349a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1350a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1351a3df083aSStefano Zampini PetscScalar sum,val; 1352a3df083aSStefano Zampini const PetscInt *idxs; 1353a3df083aSStefano Zampini PetscInt nz,j; 1354a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1355a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1356a3df083aSStefano Zampini sum = 0.; 1357a3df083aSStefano Zampini if (ctx->apply_p0) { 1358a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1359a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1360a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1361a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1362a3df083aSStefano Zampini } 1363a3df083aSStefano Zampini } else { 1364a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1365a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1366a3df083aSStefano Zampini } 1367a3df083aSStefano Zampini } 1368a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1369a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1370a3df083aSStefano Zampini } 1371a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1372a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1373a3df083aSStefano Zampini } 1374a3df083aSStefano Zampini if (transpose) { 1375a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1376a3df083aSStefano Zampini } else { 1377a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1378a3df083aSStefano Zampini } 1379a3df083aSStefano Zampini if (reset_x) { 1380a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1381a3df083aSStefano Zampini } 1382a3df083aSStefano Zampini if (apply_left) { 1383a3df083aSStefano Zampini PetscScalar *ay; 1384a3df083aSStefano Zampini PetscInt i; 1385a3df083aSStefano Zampini 1386a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1387a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1388a3df083aSStefano Zampini PetscScalar sum,val; 1389a3df083aSStefano Zampini const PetscInt *idxs; 1390a3df083aSStefano Zampini PetscInt nz,j; 1391a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1392a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1393a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1394a3df083aSStefano Zampini if (ctx->apply_p0) { 1395a3df083aSStefano Zampini sum = 0.; 1396a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1397a3df083aSStefano Zampini sum += ay[idxs[j]]; 1398a3df083aSStefano Zampini ay[idxs[j]] += val; 1399a3df083aSStefano Zampini } 1400a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1401a3df083aSStefano Zampini } else { 1402a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1403a3df083aSStefano Zampini ay[idxs[j]] += val; 1404a3df083aSStefano Zampini } 1405a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1406a3df083aSStefano Zampini } 1407a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1408a3df083aSStefano Zampini } 1409a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1410a3df083aSStefano Zampini } 1411a3df083aSStefano Zampini PetscFunctionReturn(0); 1412a3df083aSStefano Zampini } 1413a3df083aSStefano Zampini 1414a3df083aSStefano Zampini #undef __FUNCT__ 1415a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 1416a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1417a3df083aSStefano Zampini { 1418a3df083aSStefano Zampini PetscErrorCode ierr; 1419a3df083aSStefano Zampini 1420a3df083aSStefano Zampini PetscFunctionBegin; 1421a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1422a3df083aSStefano Zampini PetscFunctionReturn(0); 1423a3df083aSStefano Zampini } 1424a3df083aSStefano Zampini 1425a3df083aSStefano Zampini #undef __FUNCT__ 1426a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 1427a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1428a3df083aSStefano Zampini { 1429a3df083aSStefano Zampini PetscErrorCode ierr; 1430a3df083aSStefano Zampini 1431a3df083aSStefano Zampini PetscFunctionBegin; 1432a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1433a3df083aSStefano Zampini PetscFunctionReturn(0); 1434a3df083aSStefano Zampini } 1435a3df083aSStefano Zampini 1436a3df083aSStefano Zampini #undef __FUNCT__ 1437a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 1438a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1439a3df083aSStefano Zampini { 1440a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1441a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1442a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1443a3df083aSStefano Zampini PetscErrorCode ierr; 1444a3df083aSStefano Zampini 1445a3df083aSStefano Zampini PetscFunctionBegin; 1446a3df083aSStefano Zampini if (!restore) { 14471dd7afcfSStefano Zampini Mat A_IB,A_BI; 1448a3df083aSStefano Zampini PetscScalar *work; 1449b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1450a3df083aSStefano Zampini 14519a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 14529a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1453a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1454a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1455a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1456a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1457a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1458a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1459a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 1460a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 1461a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 1462a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 1463a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 1464a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 1465059032f7SStefano Zampini if (reuse) { 1466a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 14671dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 1468059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 1469059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 1470059032f7SStefano Zampini PetscInt i; 1471059032f7SStefano Zampini 1472059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 1473059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1474059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1475059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1476059032f7SStefano Zampini } 1477059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 14781dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 1479059032f7SStefano Zampini } 1480a3df083aSStefano Zampini ctx->A = pcis->A_IB; 1481a3df083aSStefano Zampini ctx->work = work; 1482a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 1483a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1484a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1485a3df083aSStefano Zampini pcis->A_IB = A_IB; 1486a3df083aSStefano Zampini 1487a3df083aSStefano Zampini /* A_BI as A_IB^T */ 1488a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 1489a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 1490a3df083aSStefano Zampini pcis->A_BI = A_BI; 1491a3df083aSStefano Zampini } else { 14921dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 14931dd7afcfSStefano Zampini PetscFunctionReturn(0); 14941dd7afcfSStefano Zampini } 1495a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 1496a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1497a3df083aSStefano Zampini pcis->A_IB = ctx->A; 14981dd7afcfSStefano Zampini ctx->A = NULL; 14991dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 15001dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 15011dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 15021dd7afcfSStefano Zampini if (ctx->free) { 1503059032f7SStefano Zampini PetscInt i; 15041dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1505059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1506059032f7SStefano Zampini } 1507059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1508059032f7SStefano Zampini } 1509a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 1510a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 1511a3df083aSStefano Zampini } 1512a3df083aSStefano Zampini PetscFunctionReturn(0); 1513a3df083aSStefano Zampini } 1514a3df083aSStefano Zampini 1515a3df083aSStefano Zampini /* used just in bddc debug mode */ 1516a3df083aSStefano Zampini #undef __FUNCT__ 1517a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 1518a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 1519a3df083aSStefano Zampini { 1520a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1521a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1522a3df083aSStefano Zampini Mat An; 1523a3df083aSStefano Zampini PetscErrorCode ierr; 1524a3df083aSStefano Zampini 1525a3df083aSStefano Zampini PetscFunctionBegin; 1526a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 1527a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 1528a3df083aSStefano Zampini if (is1) { 1529a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 1530a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 1531a3df083aSStefano Zampini } else { 1532a3df083aSStefano Zampini *B = An; 1533a3df083aSStefano Zampini } 1534a3df083aSStefano Zampini PetscFunctionReturn(0); 1535a3df083aSStefano Zampini } 1536a3df083aSStefano Zampini 15371cf9b237SStefano Zampini /* TODO: add reuse flag */ 15381cf9b237SStefano Zampini #undef __FUNCT__ 15391cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 15401cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 15411cf9b237SStefano Zampini { 15421cf9b237SStefano Zampini Mat Bt; 15431cf9b237SStefano Zampini PetscScalar *a,*bdata; 15441cf9b237SStefano Zampini const PetscInt *ii,*ij; 15451cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 15461cf9b237SStefano Zampini PetscBool flg_row; 15471cf9b237SStefano Zampini PetscErrorCode ierr; 15481cf9b237SStefano Zampini 15491cf9b237SStefano Zampini PetscFunctionBegin; 15501cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 15511cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 15521cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 15531cf9b237SStefano Zampini nnz = n; 15541cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 15551cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 15561cf9b237SStefano Zampini } 15571cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 15581cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 15591cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 15601cf9b237SStefano Zampini nnz = 0; 15611cf9b237SStefano Zampini bii[0] = 0; 15621cf9b237SStefano Zampini for (i=0;i<n;i++) { 15631cf9b237SStefano Zampini PetscInt j; 15641cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 15651cf9b237SStefano Zampini PetscScalar entry = a[j]; 15661cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 15671cf9b237SStefano Zampini bij[nnz] = ij[j]; 15681cf9b237SStefano Zampini bdata[nnz] = entry; 15691cf9b237SStefano Zampini nnz++; 15701cf9b237SStefano Zampini } 15711cf9b237SStefano Zampini } 15721cf9b237SStefano Zampini bii[i+1] = nnz; 15731cf9b237SStefano Zampini } 15741cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 15751cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 15761cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 15771cf9b237SStefano Zampini { 15781cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 15791cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 15801cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 15811cf9b237SStefano Zampini } 15821cf9b237SStefano Zampini *B = Bt; 15831cf9b237SStefano Zampini PetscFunctionReturn(0); 15841cf9b237SStefano Zampini } 15851cf9b237SStefano Zampini 1586674ae819SStefano Zampini #undef __FUNCT__ 15874f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 15884f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 15894f1b2e48SStefano Zampini { 15904f1b2e48SStefano Zampini Mat B; 15914f1b2e48SStefano Zampini IS is_dummy,*cc_n; 15924f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 15934f1b2e48SStefano Zampini PCBDDCGraph graph; 15944f1b2e48SStefano Zampini PetscInt i,n; 15954f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 15964f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 15974f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 15984f1b2e48SStefano Zampini PetscErrorCode ierr; 15994f1b2e48SStefano Zampini 16004f1b2e48SStefano Zampini PetscFunctionBegin; 160163c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 160263c961adSStefano Zampini *ncc = 0; 160363c961adSStefano Zampini *cc = NULL; 160463c961adSStefano Zampini PetscFunctionReturn(0); 160563c961adSStefano Zampini } 16064f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 16074f1b2e48SStefano Zampini if (!isseqaij && filter) { 16081cf9b237SStefano Zampini PetscBool isseqdense; 16091cf9b237SStefano Zampini 16101cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 16111cf9b237SStefano Zampini if (!isseqdense) { 16124f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 16131cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 16141cf9b237SStefano Zampini PetscScalar *array; 16151cf9b237SStefano Zampini PetscReal chop=1.e-6; 16161cf9b237SStefano Zampini 16171cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 16181cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 16191cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 16201cf9b237SStefano Zampini for (i=0;i<n;i++) { 16211cf9b237SStefano Zampini PetscInt j; 16221cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 16231cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 16241cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 16251cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 16261cf9b237SStefano Zampini } 16271cf9b237SStefano Zampini } 16281cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 16299d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 16301cf9b237SStefano Zampini } 16314f1b2e48SStefano Zampini } else { 16324f1b2e48SStefano Zampini B = A; 16334f1b2e48SStefano Zampini } 16344f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 16354f1b2e48SStefano Zampini 16364f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 16374f1b2e48SStefano Zampini if (filter) { 16384f1b2e48SStefano Zampini PetscScalar *data; 16394f1b2e48SStefano Zampini PetscInt j,cum; 16404f1b2e48SStefano Zampini 16414f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 16424f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 16434f1b2e48SStefano Zampini cum = 0; 16444f1b2e48SStefano Zampini for (i=0;i<n;i++) { 16454f1b2e48SStefano Zampini PetscInt t; 16464f1b2e48SStefano Zampini 16474f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 16484f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 16494f1b2e48SStefano Zampini continue; 16504f1b2e48SStefano Zampini } 16514f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 16524f1b2e48SStefano Zampini } 16534f1b2e48SStefano Zampini t = xadj_filtered[i]; 16544f1b2e48SStefano Zampini xadj_filtered[i] = cum; 16554f1b2e48SStefano Zampini cum += t; 16564f1b2e48SStefano Zampini } 16574f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 16584f1b2e48SStefano Zampini } else { 16594f1b2e48SStefano Zampini xadj_filtered = NULL; 16604f1b2e48SStefano Zampini adjncy_filtered = NULL; 16614f1b2e48SStefano Zampini } 16624f1b2e48SStefano Zampini 16634f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 16644f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 16654f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 16664f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 16674f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 1668be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 16694f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 16704f1b2e48SStefano Zampini if (xadj_filtered) { 16714f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 16724f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 16734f1b2e48SStefano Zampini } else { 16744f1b2e48SStefano Zampini graph->xadj = xadj; 16754f1b2e48SStefano Zampini graph->adjncy = adjncy; 16764f1b2e48SStefano Zampini } 16774f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 16784f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 16794f1b2e48SStefano Zampini /* partial clean up */ 16804f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 16814f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 16821cf9b237SStefano Zampini if (A != B) { 16834f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 16844f1b2e48SStefano Zampini } 16854f1b2e48SStefano Zampini 16864f1b2e48SStefano Zampini /* get back data */ 16871cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 16881cf9b237SStefano Zampini if (cc) { 16894f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 16904f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 16914f1b2e48SStefano 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); 16924f1b2e48SStefano Zampini } 16934f1b2e48SStefano Zampini *cc = cc_n; 16941cf9b237SStefano Zampini } 16954f1b2e48SStefano Zampini /* clean up graph */ 16964f1b2e48SStefano Zampini graph->xadj = 0; 16974f1b2e48SStefano Zampini graph->adjncy = 0; 16984f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 16994f1b2e48SStefano Zampini PetscFunctionReturn(0); 17004f1b2e48SStefano Zampini } 17014f1b2e48SStefano Zampini 17024f1b2e48SStefano Zampini #undef __FUNCT__ 17035408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 17045408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 17055408967cSStefano Zampini { 17065408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 17075408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1708dee84bffSStefano Zampini IS dirIS = NULL; 17094f1b2e48SStefano Zampini PetscInt i; 17105408967cSStefano Zampini PetscErrorCode ierr; 17115408967cSStefano Zampini 17125408967cSStefano Zampini PetscFunctionBegin; 1713dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 17145408967cSStefano Zampini if (zerodiag) { 17155408967cSStefano Zampini Mat A; 17165408967cSStefano Zampini Vec vec3_N; 17175408967cSStefano Zampini PetscScalar *vals; 17185408967cSStefano Zampini const PetscInt *idxs; 1719d12d3064SStefano Zampini PetscInt nz,*count; 17205408967cSStefano Zampini 17215408967cSStefano Zampini /* p0 */ 17225408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 17235408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 17245408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 17255408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 17264f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 17275408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 17285408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 17295408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 17305408967cSStefano Zampini /* v_I */ 17315408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 17325408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 17335408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 17345408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 17355408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 17365408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 17375408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 17385408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 17395408967cSStefano Zampini if (dirIS) { 17405408967cSStefano Zampini PetscInt n; 17415408967cSStefano Zampini 17425408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 17435408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 17445408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 17455408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 17465408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 17475408967cSStefano Zampini } 17485408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 17495408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 17505408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 17515408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 1752669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 17535408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 17545408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 17559a962809SStefano 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])); 17565408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 17575408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 1758d12d3064SStefano Zampini 1759d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 1760d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 1761d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 1762d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 1763d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 1764d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 17659a962809SStefano 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]); 1766d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 1767d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 17685408967cSStefano Zampini } 1769dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 17705408967cSStefano Zampini 17715408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 17725408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 17734f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 17745408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 17754f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 17765408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 1777f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1778f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 1779f2a566d8SStefano 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); 1780f2a566d8SStefano Zampini } 17815408967cSStefano Zampini PetscFunctionReturn(0); 17825408967cSStefano Zampini } 17835408967cSStefano Zampini 17845408967cSStefano Zampini #undef __FUNCT__ 1785339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 1786339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 1787339f8db1SStefano Zampini { 1788339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 17894f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 1790b0f5fe93SStefano Zampini PetscInt nz,n; 17911f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 17924f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 1793339f8db1SStefano Zampini PetscErrorCode ierr; 1794339f8db1SStefano Zampini 1795339f8db1SStefano Zampini PetscFunctionBegin; 17969f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 17979f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1798a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 1799a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 1800a3df083aSStefano Zampini } 1801a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1802a3df083aSStefano Zampini pcbddc->benign_n = 0; 18031ae86dd6SStefano Zampini /* if a local info on dofs is present, assumes that the last field represents "pressures" 18044f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 18054f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 18064f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 18071ae86dd6SStefano Zampini since the local Schur complements are already SPD 18084f1b2e48SStefano Zampini */ 18094f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 18104f1b2e48SStefano Zampini have_null = PETSC_TRUE; 181140fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 18124f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 18134f1b2e48SStefano Zampini 18144f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 18154f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 18164f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 18174f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 1818ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 181940fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 182040fa8d13SStefano Zampini if (!sorted) { 182140fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 182240fa8d13SStefano Zampini } 182340fa8d13SStefano Zampini } else { 182440fa8d13SStefano Zampini pressures = NULL; 182540fa8d13SStefano Zampini } 182697d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 182797d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 182827b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 182997d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 1830339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 1831339f8db1SStefano Zampini if (!sorted) { 1832339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 1833339f8db1SStefano Zampini } 1834339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 18354f1b2e48SStefano Zampini if (!nz) { 18364f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 18374f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 183840fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 183940fa8d13SStefano Zampini } 18404f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 18414f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 18424f1b2e48SStefano Zampini zerodiag_subs = NULL; 18434f1b2e48SStefano Zampini pcbddc->benign_n = 0; 18441f4df5f7SStefano Zampini n_interior_dofs = 0; 18451f4df5f7SStefano Zampini interior_dofs = NULL; 18461f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 18471f4df5f7SStefano Zampini PetscInt n,i,j; 18481f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 18491f4df5f7SStefano Zampini PetscInt *iwork; 18501f4df5f7SStefano Zampini 18511f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 18521f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 18531f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 18541f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 185590648384SStefano Zampini for (i=1;i<n_neigh;i++) 18561f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 18571f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 18581f4df5f7SStefano Zampini for (i=0;i<n;i++) 18591f4df5f7SStefano Zampini if (!iwork[i]) 18601f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 18611f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 18621f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 18631f4df5f7SStefano Zampini } 18644f1b2e48SStefano Zampini if (has_null_pressures) { 18654f1b2e48SStefano Zampini IS *subs; 18661f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 18671f4df5f7SStefano Zampini const PetscInt *idxs; 18681f4df5f7SStefano Zampini PetscScalar *array; 18691f4df5f7SStefano Zampini Vec *work; 18701f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 18714f1b2e48SStefano Zampini 18724f1b2e48SStefano Zampini subs = pcbddc->local_subs; 18734f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 18741f4df5f7SStefano 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) */ 18751f4df5f7SStefano Zampini if (pcbddc->current_level) { 18761f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 18771f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 18781f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 18791f4df5f7SStefano Zampini /* work[0] = 1_p */ 18801f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 18811f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 18821f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 18831f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 18841f4df5f7SStefano Zampini /* work[0] = 1_v */ 18851f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 18861f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 18871f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 18881f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 18891f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 18901f4df5f7SStefano Zampini } 18914f1b2e48SStefano Zampini if (nsubs > 1) { 18924f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 18934f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 18944f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 18954f1b2e48SStefano Zampini IS t_zerodiag_subs; 18964f1b2e48SStefano Zampini PetscInt nl; 18974f1b2e48SStefano Zampini 18984f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 18994f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 19004f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 19014f1b2e48SStefano Zampini if (nl) { 19024f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 19034f1b2e48SStefano Zampini 19041f4df5f7SStefano Zampini if (pcbddc->current_level) { 19051f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 19061f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 19071f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 19081f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 19091f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 19101f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 19111f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 19121f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 19131f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 19141f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 19151f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 19161f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 19171f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 19181f4df5f7SStefano Zampini valid = PETSC_FALSE; 19191f4df5f7SStefano Zampini break; 19201f4df5f7SStefano Zampini } 19211f4df5f7SStefano Zampini } 19221f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 19231f4df5f7SStefano Zampini } 19241f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 19251f4df5f7SStefano Zampini IS t_bc; 19261f4df5f7SStefano Zampini PetscInt nzb; 19271f4df5f7SStefano Zampini 19281f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 19291f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 19301f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 19311f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 19321f4df5f7SStefano Zampini } 19331f4df5f7SStefano Zampini if (valid && pressures) { 19344f1b2e48SStefano Zampini IS t_pressure_subs; 19354f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 19364f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 19374f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 19384f1b2e48SStefano Zampini } 19394f1b2e48SStefano Zampini if (valid) { 19404f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 19414f1b2e48SStefano Zampini pcbddc->benign_n++; 19424f1b2e48SStefano Zampini } else { 19434f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 19444f1b2e48SStefano Zampini } 19454f1b2e48SStefano Zampini } 19464f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 19474f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 19484f1b2e48SStefano Zampini } 19494f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 19504f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 19511f4df5f7SStefano Zampini 19521f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 19531f4df5f7SStefano Zampini PetscInt nzb; 19541f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 19551f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 19561f4df5f7SStefano Zampini } 19571f4df5f7SStefano Zampini if (valid && pressures) { 19584f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 19594f1b2e48SStefano Zampini } 19601f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 19611f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 19621f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 19631f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 19641f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 19651f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 19661f4df5f7SStefano Zampini valid = PETSC_FALSE; 19671f4df5f7SStefano Zampini break; 19681f4df5f7SStefano Zampini } 19691f4df5f7SStefano Zampini } 19701f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 19711f4df5f7SStefano Zampini } 19724f1b2e48SStefano Zampini if (valid) { 19734f1b2e48SStefano Zampini pcbddc->benign_n = 1; 1974ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 19754f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 19764f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 19774f1b2e48SStefano Zampini } 19784f1b2e48SStefano Zampini } 19791f4df5f7SStefano Zampini if (pcbddc->current_level) { 19801f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 19814f1b2e48SStefano Zampini } 19821f4df5f7SStefano Zampini } 19831f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 19844f1b2e48SStefano Zampini 19854f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 1986b9b0e38cSStefano Zampini PetscInt n; 1987b9b0e38cSStefano Zampini 19884f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 19894f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 1990b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 1991b9b0e38cSStefano Zampini if (n) { 19924f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 19934f1b2e48SStefano Zampini have_null = PETSC_FALSE; 19944f1b2e48SStefano Zampini } 1995b9b0e38cSStefano Zampini } 19964f1b2e48SStefano Zampini 19974f1b2e48SStefano Zampini /* final check for null pressures */ 19984f1b2e48SStefano Zampini if (zerodiag && pressures) { 19994f1b2e48SStefano Zampini PetscInt nz,np; 20004f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 20014f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 20024f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 20034f1b2e48SStefano Zampini } 20044f1b2e48SStefano Zampini 20054f1b2e48SStefano Zampini if (recompute_zerodiag) { 20064f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 20074f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 20084f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 20094f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 20104f1b2e48SStefano Zampini } else { 20114f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 20124f1b2e48SStefano Zampini 20134f1b2e48SStefano Zampini nzn = 0; 20144f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 20154f1b2e48SStefano Zampini PetscInt ns; 20164f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 20174f1b2e48SStefano Zampini nzn += ns; 20184f1b2e48SStefano Zampini } 20194f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 20204f1b2e48SStefano Zampini nzn = 0; 20214f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 20224f1b2e48SStefano Zampini PetscInt ns,*idxs; 20234f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 20244f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 20254f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 20264f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 20274f1b2e48SStefano Zampini nzn += ns; 20284f1b2e48SStefano Zampini } 20294f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 20304f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 20314f1b2e48SStefano Zampini } 20324f1b2e48SStefano Zampini have_null = PETSC_FALSE; 20334f1b2e48SStefano Zampini } 20344f1b2e48SStefano Zampini 2035669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2036a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2037a198735bSStefano Zampini Mat A,loc_divudotp; 2038a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2039a198735bSStefano Zampini IS row,col,isused = NULL; 2040a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2041a198735bSStefano Zampini 20421f4df5f7SStefano Zampini if (pressures) { 20431f4df5f7SStefano Zampini isused = pressures; 20441f4df5f7SStefano Zampini } else { 20451f4df5f7SStefano Zampini isused = zerodiag; 20461f4df5f7SStefano Zampini } 2047a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2048669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 20491ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 20501ae86dd6SStefano 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"); 2051a198735bSStefano Zampini n_isused = 0; 2052a198735bSStefano Zampini if (isused) { 2053a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2054a198735bSStefano Zampini } 2055a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2056a198735bSStefano Zampini st = st-n_isused; 20571ae86dd6SStefano Zampini if (n) { 2058a198735bSStefano Zampini const PetscInt *gidxs; 2059a198735bSStefano Zampini 2060a198735bSStefano Zampini ierr = MatGetSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2061a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2062a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2063a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2064a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2065a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 20661ae86dd6SStefano Zampini } else { 2067a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2068a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2069a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2070a198735bSStefano Zampini } 2071a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2072a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2073a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2074a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2075a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2076a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2077a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2078a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2079a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2080a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2081a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2082a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2083a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2084a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 20851ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20861ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20871ae86dd6SStefano Zampini } 2088b3afcdbeSStefano Zampini 2089b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 20904f1b2e48SStefano Zampini if (has_null_pressures) { 20914f1b2e48SStefano Zampini IS zerodiagc; 20924f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 20934f1b2e48SStefano Zampini PetscInt i,s,*nnz; 20944f1b2e48SStefano Zampini 20954f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2096339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 2097339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 2098339f8db1SStefano Zampini /* local change of basis for pressures */ 2099339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 210097d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2101339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2102339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2103339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 21044f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 21054f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 21064f1b2e48SStefano Zampini PetscInt nzs,j; 21074f1b2e48SStefano Zampini 21084f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 21094f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 21104f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 21114f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 21124f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 21134f1b2e48SStefano Zampini } 2114339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2115339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2116339f8db1SStefano Zampini /* set identity on velocities */ 2117339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 2118339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 2119339f8db1SStefano Zampini } 21204f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 21214f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 21229f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 21234f1b2e48SStefano 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); 2124339f8db1SStefano Zampini /* set change on pressures */ 21254f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 21264f1b2e48SStefano Zampini PetscScalar *array; 21274f1b2e48SStefano Zampini PetscInt nzs; 21284f1b2e48SStefano Zampini 21294f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 21304f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 21314f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2132339f8db1SStefano Zampini PetscScalar vals[2]; 2133339f8db1SStefano Zampini PetscInt cols[2]; 2134339f8db1SStefano Zampini 2135339f8db1SStefano Zampini cols[0] = idxs[i]; 21364f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2137339f8db1SStefano Zampini vals[0] = 1.; 2138b0f5fe93SStefano Zampini vals[1] = 1.; 21394f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2140339f8db1SStefano Zampini } 21414f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 21424f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 21434f1b2e48SStefano Zampini array[nzs-1] = 1.; 21444f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 21454f1b2e48SStefano Zampini /* store local idxs for p0 */ 21464f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 21474f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2148339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 21494f1b2e48SStefano Zampini } 2150339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2151339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2152a3df083aSStefano Zampini /* project if needed */ 2153a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 21541dd7afcfSStefano Zampini Mat M; 21551dd7afcfSStefano Zampini 21561dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2157339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 21581dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 21591dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2160a3df083aSStefano Zampini } 21614f1b2e48SStefano Zampini /* store global idxs for p0 */ 21624f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2163339f8db1SStefano Zampini } 2164ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 21654f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 2166b0f5fe93SStefano Zampini 2167b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 2168b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 216927b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 217027b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2171339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2172339f8db1SStefano Zampini PetscFunctionReturn(0); 2173339f8db1SStefano Zampini } 2174339f8db1SStefano Zampini 2175339f8db1SStefano Zampini #undef __FUNCT__ 2176015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 2177015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2178efc2fbd9SStefano Zampini { 2179efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2180de9d7bd0SStefano Zampini PetscScalar *array; 2181efc2fbd9SStefano Zampini PetscErrorCode ierr; 2182efc2fbd9SStefano Zampini 2183efc2fbd9SStefano Zampini PetscFunctionBegin; 2184efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2185efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 21864f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2187efc2fbd9SStefano Zampini } 2188de9d7bd0SStefano Zampini if (get) { 2189efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 21904f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 21914f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2192efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2193de9d7bd0SStefano Zampini } else { 2194de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2195de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2196de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2197de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2198efc2fbd9SStefano Zampini } 2199efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2200efc2fbd9SStefano Zampini } 2201efc2fbd9SStefano Zampini 2202efc2fbd9SStefano Zampini #undef __FUNCT__ 2203c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 2204c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2205c263805aSStefano Zampini { 2206c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2207c263805aSStefano Zampini PetscErrorCode ierr; 2208c263805aSStefano Zampini 2209c263805aSStefano Zampini PetscFunctionBegin; 2210c263805aSStefano Zampini /* TODO: add error checking 2211c263805aSStefano Zampini - avoid nested pop (or push) calls. 2212c263805aSStefano Zampini - cannot push before pop. 22131c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2214c263805aSStefano Zampini */ 22154f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2216efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2217efc2fbd9SStefano Zampini } 2218c263805aSStefano Zampini if (pop) { 2219a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 22204f1b2e48SStefano Zampini IS is_p0; 22214f1b2e48SStefano Zampini MatReuse reuse; 2222c263805aSStefano Zampini 2223c263805aSStefano Zampini /* extract B_0 */ 22244f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 22254f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 22264f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 22274f1b2e48SStefano Zampini } 22284f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 22294f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2230c263805aSStefano Zampini /* remove rows and cols from local problem */ 2231c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 223297d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 22334f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 22344f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2235a3df083aSStefano Zampini } else { 2236a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2237a3df083aSStefano Zampini PetscScalar *vals; 2238a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2239a3df083aSStefano Zampini 2240a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2241a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2242a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 22430b5adadeSStefano Zampini PetscInt *nnz; 2244a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2245a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2246a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2247331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2248331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2249331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2250331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2251331e053bSStefano Zampini } 2252331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2253331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2254331e053bSStefano Zampini } 2255a3df083aSStefano Zampini 2256a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2257a3df083aSStefano Zampini PetscScalar *array; 2258a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2259a3df083aSStefano Zampini 2260a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2261a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2262a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2263a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2264a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2265a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2266a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2267a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2268a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2269a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2270a3df083aSStefano Zampini cum = 0; 2271a3df083aSStefano Zampini for (j=0;j<n;j++) { 227222db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2273a3df083aSStefano Zampini vals[cum] = array[j]; 2274a3df083aSStefano Zampini idxs_ins[cum] = j; 2275a3df083aSStefano Zampini cum++; 2276a3df083aSStefano Zampini } 2277a3df083aSStefano Zampini } 2278a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2279a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2280a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2281a3df083aSStefano Zampini } 2282a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2283a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2284a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2285a3df083aSStefano Zampini } 2286c263805aSStefano Zampini } else { /* push */ 2287a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 22884f1b2e48SStefano Zampini PetscInt i; 22894f1b2e48SStefano Zampini 22904f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 22914f1b2e48SStefano Zampini PetscScalar *B0_vals; 22924f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 22934f1b2e48SStefano Zampini 22944f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 22954f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 22967b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 22974f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 22984f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 22994f1b2e48SStefano Zampini } 2300c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2301c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2302a3df083aSStefano Zampini } else { 2303a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2304a3df083aSStefano Zampini } 2305c263805aSStefano Zampini } 2306c263805aSStefano Zampini PetscFunctionReturn(0); 2307c263805aSStefano Zampini } 2308c263805aSStefano Zampini 2309c263805aSStefano Zampini #undef __FUNCT__ 2310b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 231108122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2312b1b3d7a2SStefano Zampini { 2313b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 231408122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 231508122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 231608122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 231708122e43SStefano Zampini PetscScalar *work,lwork; 231808122e43SStefano Zampini PetscScalar *St,*S,*eigv; 231908122e43SStefano Zampini PetscScalar *Sarray,*Starray; 232008122e43SStefano Zampini PetscReal *eigs,thresh; 23211b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2322f6f667cfSStefano Zampini PetscBool allocated_S_St; 232308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 232408122e43SStefano Zampini PetscReal *rwork; 232508122e43SStefano Zampini #endif 2326b1b3d7a2SStefano Zampini PetscErrorCode ierr; 2327b1b3d7a2SStefano Zampini 2328b1b3d7a2SStefano Zampini PetscFunctionBegin; 2329b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 2330af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 2331af25d912SStefano 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); 233206a4e24aSStefano Zampini 2333fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2334fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2335fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2336fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 23371575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2338fd14bc51SStefano Zampini } 2339fd14bc51SStefano Zampini 2340e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 2341e496cd5dSStefano 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); 2342e496cd5dSStefano Zampini } 2343e496cd5dSStefano Zampini 234408122e43SStefano Zampini /* max size of subsets */ 234508122e43SStefano Zampini mss = 0; 234608122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 234708122e43SStefano Zampini PetscInt subset_size; 2348862806e4SStefano Zampini 234908122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 235008122e43SStefano Zampini mss = PetscMax(mss,subset_size); 235108122e43SStefano Zampini } 235208122e43SStefano Zampini 235308122e43SStefano Zampini /* min/max and threshold */ 235408122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 2355f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 235608122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 2357f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 2358f6f667cfSStefano Zampini if (nmin) { 2359f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 2360f6f667cfSStefano Zampini } 236108122e43SStefano Zampini 236208122e43SStefano Zampini /* allocate lapack workspace */ 236308122e43SStefano Zampini cum = cum2 = 0; 236408122e43SStefano Zampini maxneigs = 0; 236508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 236608122e43SStefano Zampini PetscInt n,subset_size; 2367f6f667cfSStefano Zampini 236808122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 236908122e43SStefano Zampini n = PetscMin(subset_size,nmax); 23709162d606SStefano Zampini cum += subset_size; 23719162d606SStefano Zampini cum2 += subset_size*n; 237208122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 237308122e43SStefano Zampini } 237408122e43SStefano Zampini if (mss) { 23759ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 237608122e43SStefano Zampini PetscBLASInt B_itype = 1; 237708122e43SStefano Zampini PetscBLASInt B_N = mss; 23784c6709b3SStefano Zampini PetscReal zero = 0.0; 23794c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 238008122e43SStefano Zampini 238108122e43SStefano Zampini B_lwork = -1; 238208122e43SStefano Zampini S = NULL; 238308122e43SStefano Zampini St = NULL; 2384a58a30b4SStefano Zampini eigs = NULL; 2385a58a30b4SStefano Zampini eigv = NULL; 2386a58a30b4SStefano Zampini B_iwork = NULL; 2387a58a30b4SStefano Zampini B_ifail = NULL; 2388d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2389d1710679SStefano Zampini rwork = NULL; 2390d1710679SStefano Zampini #endif 23918bec7fa6SStefano Zampini thresh = 1.0; 239208122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 239308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 239408122e43SStefano 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)); 239508122e43SStefano Zampini #else 239608122e43SStefano 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)); 239708122e43SStefano Zampini #endif 239808122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 239908122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 240008122e43SStefano Zampini } else { 240108122e43SStefano Zampini /* TODO */ 240208122e43SStefano Zampini } 240308122e43SStefano Zampini } else { 240408122e43SStefano Zampini lwork = 0; 240508122e43SStefano Zampini } 240608122e43SStefano Zampini 240708122e43SStefano Zampini nv = 0; 2408d62866d3SStefano 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) */ 2409d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 241008122e43SStefano Zampini } 24114c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 2412f6f667cfSStefano Zampini if (allocated_S_St) { 2413f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 2414f6f667cfSStefano Zampini } 2415f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 241608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 241708122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 241808122e43SStefano Zampini #endif 24199162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 24209162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 24219162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 242208122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 24239162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 242408122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 242508122e43SStefano Zampini 242608122e43SStefano Zampini maxneigs = 0; 242772b8c272SStefano Zampini cum = cumarray = 0; 24289162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 24299162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 2430d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 243108122e43SStefano Zampini const PetscInt *idxs; 243208122e43SStefano Zampini 2433d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 243408122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 243508122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 243608122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 243708122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 24389162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 24399162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 244008122e43SStefano Zampini } 2441d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 244208122e43SStefano Zampini } 244308122e43SStefano Zampini 244408122e43SStefano Zampini if (mss) { /* multilevel */ 244508122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 244608122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 244708122e43SStefano Zampini } 244808122e43SStefano Zampini 2449ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 245008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 245108122e43SStefano Zampini const PetscInt *idxs; 24529d54b7f4SStefano Zampini PetscReal upper,lower; 2453862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 245408122e43SStefano Zampini PetscBLASInt B_N; 2455aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 245608122e43SStefano Zampini 24579d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 24589d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 24599d54b7f4SStefano Zampini lower = thresh; 24609d54b7f4SStefano Zampini } else { 24619d54b7f4SStefano Zampini upper = 1./thresh; 24629d54b7f4SStefano Zampini lower = 0.; 24639d54b7f4SStefano Zampini } 2464862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 2465ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 2466f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 2467f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 24689ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 2469aff50787SStefano Zampini PetscInt j,k; 2470aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 2471aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 2472aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 247308122e43SStefano Zampini } 247408122e43SStefano Zampini for (j=0;j<subset_size;j++) { 2475aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 2476aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 2477aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 2478aff50787SStefano Zampini } 247908122e43SStefano Zampini } 248008122e43SStefano Zampini } else { 248108122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 248208122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 248308122e43SStefano Zampini } 24848bec7fa6SStefano Zampini } else { 2485f6f667cfSStefano Zampini S = Sarray + cumarray; 2486f6f667cfSStefano Zampini St = Starray + cumarray; 24878bec7fa6SStefano Zampini } 2488aff50787SStefano Zampini /* see if we can save some work */ 2489b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 2490aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 2491aff50787SStefano Zampini } 2492aff50787SStefano Zampini 2493b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 2494aff50787SStefano Zampini B_neigs = 0; 2495aff50787SStefano Zampini } else { 24969ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 249708122e43SStefano Zampini PetscBLASInt B_itype = 1; 2498f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 24994c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 25009552c7c7SStefano Zampini PetscInt nmin_s; 2501b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 250208122e43SStefano Zampini 2503fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 25048bec7fa6SStefano 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]]); 2505fd14bc51SStefano Zampini } 2506d16cbb6bSStefano Zampini 2507b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 2508b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 2509b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 2510b7ab4a40SStefano Zampini } 2511b7ab4a40SStefano Zampini 251208122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2513b7ab4a40SStefano Zampini if (compute_range) { 2514d16cbb6bSStefano Zampini 2515d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 251608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 25179d54b7f4SStefano 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)); 251808122e43SStefano Zampini #else 25199d54b7f4SStefano 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)); 252008122e43SStefano Zampini #endif 2521b7ab4a40SStefano Zampini } else if (!same_data) { 2522d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 2523d16cbb6bSStefano Zampini B_IL = 1; 2524d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 25259d54b7f4SStefano 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)); 2526d16cbb6bSStefano Zampini #else 25279d54b7f4SStefano 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)); 2528d16cbb6bSStefano Zampini #endif 2529b7ab4a40SStefano Zampini } else { /* same_data is true, so get the adaptive function requested by the user */ 2530b7ab4a40SStefano Zampini PetscInt k; 2531b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 2532b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 2533b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 2534b7ab4a40SStefano Zampini nmin = nmax; 2535b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 2536b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 2537b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 2538b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 2539b7ab4a40SStefano Zampini } 2540d16cbb6bSStefano Zampini } 254108122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 254208122e43SStefano Zampini if (B_ierr) { 25436c4ed002SBarry 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); 25446c4ed002SBarry 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); 25456c4ed002SBarry 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); 254608122e43SStefano Zampini } 254708122e43SStefano Zampini 254808122e43SStefano Zampini if (B_neigs > nmax) { 2549fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2550fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 2551fd14bc51SStefano Zampini } 25529d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 255308122e43SStefano Zampini B_neigs = nmax; 255408122e43SStefano Zampini } 255508122e43SStefano Zampini 25569552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 25579552c7c7SStefano Zampini if (B_neigs < nmin_s) { 255808122e43SStefano Zampini PetscBLASInt B_neigs2; 255908122e43SStefano Zampini 25609d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2561f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 25629d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 25639d54b7f4SStefano Zampini } else { 25649d54b7f4SStefano Zampini B_IL = B_neigs + 1; 25659d54b7f4SStefano Zampini B_IU = nmin_s; 25669d54b7f4SStefano Zampini } 2567fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2568fd14bc51SStefano 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); 2569fd14bc51SStefano Zampini } 25709ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 25711ae86dd6SStefano Zampini PetscInt j,k; 257208122e43SStefano Zampini for (j=0;j<subset_size;j++) { 25731ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 25741ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 25751ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 257608122e43SStefano Zampini } 257708122e43SStefano Zampini } 257808122e43SStefano Zampini } else { 257908122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 258008122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 258108122e43SStefano Zampini } 258208122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 258308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 25849d54b7f4SStefano 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)); 258508122e43SStefano Zampini #else 25869d54b7f4SStefano 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)); 258708122e43SStefano Zampini #endif 258808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 258908122e43SStefano Zampini B_neigs += B_neigs2; 259008122e43SStefano Zampini } 259108122e43SStefano Zampini if (B_ierr) { 25926c4ed002SBarry 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); 25936c4ed002SBarry 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); 25946c4ed002SBarry 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); 259508122e43SStefano Zampini } 2596fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2597ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 259808122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 259908122e43SStefano Zampini if (eigs[j] == 0.0) { 2600ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 260108122e43SStefano Zampini } else { 26029d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2603ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 26049d54b7f4SStefano Zampini } else { 26059d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 26069d54b7f4SStefano Zampini } 2607fd14bc51SStefano Zampini } 260808122e43SStefano Zampini } 260908122e43SStefano Zampini } 261008122e43SStefano Zampini } else { 261108122e43SStefano Zampini /* TODO */ 261208122e43SStefano Zampini } 2613aff50787SStefano Zampini } 26146c3e6151SStefano Zampini /* change the basis back to the original one */ 26156c3e6151SStefano Zampini if (sub_schurs->change) { 261672b8c272SStefano Zampini Mat change,phi,phit; 26176c3e6151SStefano Zampini 26186c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 26196c3e6151SStefano Zampini PetscInt ii; 26206c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 26216c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 26226c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 2623684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2624684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 2625684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 2626684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2627684229deSStefano Zampini #else 26286c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 2629684229deSStefano Zampini #endif 26306c3e6151SStefano Zampini } 26316c3e6151SStefano Zampini } 26326c3e6151SStefano Zampini } 263372b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 26346c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 263572b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 26366c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 26376c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 26386c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 26396c3e6151SStefano Zampini } 26408bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 26418bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 26429162d606SStefano Zampini if (B_neigs) { 26439162d606SStefano 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); 2644fd14bc51SStefano Zampini 2645fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 26469552c7c7SStefano Zampini PetscInt ii; 26479552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 2648ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 26499552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 2650ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2651ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2652ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2653ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2654ac47001eSStefano Zampini #else 2655ac47001eSStefano 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); 2656ac47001eSStefano Zampini #endif 26579552c7c7SStefano Zampini } 26589552c7c7SStefano Zampini } 2659fd14bc51SStefano Zampini } 26609162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 26619162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 26629162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 26639162d606SStefano Zampini cum++; 266408122e43SStefano Zampini } 266508122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 266608122e43SStefano Zampini /* shift for next computation */ 266708122e43SStefano Zampini cumarray += subset_size*subset_size; 266808122e43SStefano Zampini } 2669fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2670fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2671fd14bc51SStefano Zampini } 267208122e43SStefano Zampini 267308122e43SStefano Zampini if (mss) { 267408122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 267508122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 2676f6f667cfSStefano Zampini /* destroy matrices (junk) */ 2677f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 2678f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 267908122e43SStefano Zampini } 2680f6f667cfSStefano Zampini if (allocated_S_St) { 2681f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 2682f6f667cfSStefano Zampini } 2683f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 268408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 268508122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 268608122e43SStefano Zampini #endif 268708122e43SStefano Zampini if (pcbddc->dbg_flag) { 26881b968477SStefano Zampini PetscInt maxneigs_r; 2689b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 26909b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 269108122e43SStefano Zampini } 269208122e43SStefano Zampini PetscFunctionReturn(0); 269308122e43SStefano Zampini } 2694b1b3d7a2SStefano Zampini 2695674ae819SStefano Zampini #undef __FUNCT__ 2696c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 2697c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 2698c8587f34SStefano Zampini { 26998629588bSStefano Zampini PetscScalar *coarse_submat_vals; 2700c8587f34SStefano Zampini PetscErrorCode ierr; 2701c8587f34SStefano Zampini 2702c8587f34SStefano Zampini PetscFunctionBegin; 2703f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 27045e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 2705c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 2706c8587f34SStefano Zampini 2707684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 27080fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 2709684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 2710c8587f34SStefano Zampini 27118629588bSStefano Zampini /* 27128629588bSStefano Zampini Setup local correction and local part of coarse basis. 27138629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 27148629588bSStefano Zampini */ 271547f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 27168629588bSStefano Zampini 27178629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 27188629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 27198629588bSStefano Zampini 27208629588bSStefano Zampini /* free */ 27218629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 2722c8587f34SStefano Zampini PetscFunctionReturn(0); 2723c8587f34SStefano Zampini } 2724c8587f34SStefano Zampini 2725c8587f34SStefano Zampini #undef __FUNCT__ 2726674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 2727674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 2728674ae819SStefano Zampini { 2729674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2730674ae819SStefano Zampini PetscErrorCode ierr; 2731674ae819SStefano Zampini 2732674ae819SStefano Zampini PetscFunctionBegin; 2733674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 273430368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 2735674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 2736785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 2737674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 2738f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2739f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2740785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 274163602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 274263602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 2743674ae819SStefano Zampini PetscFunctionReturn(0); 2744674ae819SStefano Zampini } 2745674ae819SStefano Zampini 2746674ae819SStefano Zampini #undef __FUNCT__ 2747674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 2748674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 2749674ae819SStefano Zampini { 2750674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 27514f1b2e48SStefano Zampini PetscInt i; 2752674ae819SStefano Zampini PetscErrorCode ierr; 2753674ae819SStefano Zampini 2754674ae819SStefano Zampini PetscFunctionBegin; 2755a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 2756b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2757674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 275816909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 27591dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 2760674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2761669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 2762fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 2763a13144ffSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 2764674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 27654f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 27664f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 27674f1b2e48SStefano Zampini } 27684f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 2769b334f244SStefano Zampini if (pcbddc->sub_schurs) { 2770b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 2771b334f244SStefano Zampini } 2772c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 27738af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 2774674ae819SStefano Zampini PetscFunctionReturn(0); 2775674ae819SStefano Zampini } 2776674ae819SStefano Zampini 2777674ae819SStefano Zampini #undef __FUNCT__ 2778674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 2779674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 2780674ae819SStefano Zampini { 2781674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2782674ae819SStefano Zampini PetscErrorCode ierr; 2783674ae819SStefano Zampini 2784674ae819SStefano Zampini PetscFunctionBegin; 2785674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 278658da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 2787ca92afb2SStefano Zampini PetscScalar *array; 278806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 278906656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 279058da7f69SStefano Zampini } 2791674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 2792674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 279315aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 279415aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 2795674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 2796674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 2797674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 279806656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 2799674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 2800674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 28018ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2802674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2803674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2804674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 2805f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 2806f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 2807f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2808f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2809727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 28100e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2811f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 281270cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 281381d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 28140369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 28151dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 28164f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 28178b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 2818ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 2819ca92afb2SStefano Zampini PetscInt i; 2820ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2821ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2822ca92afb2SStefano Zampini } 2823ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2824ca92afb2SStefano Zampini } 28254f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 2826674ae819SStefano Zampini PetscFunctionReturn(0); 2827674ae819SStefano Zampini } 2828674ae819SStefano Zampini 2829674ae819SStefano Zampini #undef __FUNCT__ 2830f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 2831f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 28326bfb1811SStefano Zampini { 28336bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 28346bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 28356bfb1811SStefano Zampini VecType impVecType; 28364f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 28376bfb1811SStefano Zampini PetscErrorCode ierr; 28386bfb1811SStefano Zampini 28396bfb1811SStefano Zampini PetscFunctionBegin; 28406c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 2841e7b262bdSStefano Zampini /* get sizes */ 28424f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 2843b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 28446bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 2845e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 2846e7b262bdSStefano Zampini /* R nodes */ 2847e7b262bdSStefano Zampini old_size = -1; 2848e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 2849e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 2850e7b262bdSStefano Zampini } 2851e7b262bdSStefano Zampini if (n_R != old_size) { 2852e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 2853e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 28546bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 28556bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 28566bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 28576bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 2858e7b262bdSStefano Zampini } 2859e7b262bdSStefano Zampini /* local primal dofs */ 2860e7b262bdSStefano Zampini old_size = -1; 2861e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 2862e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 2863e7b262bdSStefano Zampini } 2864e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 2865e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 286683b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 2867e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 28686bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 2869e7b262bdSStefano Zampini } 2870e7b262bdSStefano Zampini /* local explicit constraints */ 2871e7b262bdSStefano Zampini old_size = -1; 2872e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 2873e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 2874e7b262bdSStefano Zampini } 2875e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 2876e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 287783b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 287883b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 287983b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 288083b7ccabSStefano Zampini } 28816bfb1811SStefano Zampini PetscFunctionReturn(0); 28826bfb1811SStefano Zampini } 28836bfb1811SStefano Zampini 28846bfb1811SStefano Zampini #undef __FUNCT__ 288547f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 288647f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 288788ebb749SStefano Zampini { 288825084f0cSStefano Zampini PetscErrorCode ierr; 288925084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 289088ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 289188ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2892d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 289325084f0cSStefano Zampini /* submatrices of local problem */ 289480677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 289506656605SStefano Zampini /* submatrices of local coarse problem */ 289606656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 289725084f0cSStefano Zampini /* working matrices */ 289806656605SStefano Zampini Mat C_CR; 289925084f0cSStefano Zampini /* additional working stuff */ 290006656605SStefano Zampini PC pc_R; 29014f1b2e48SStefano Zampini Mat F; 29025cbda25cSStefano Zampini Vec dummy_vec; 2903a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 290425084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 290506656605SStefano Zampini PetscScalar *work; 290606656605SStefano Zampini PetscInt *idx_V_B; 2907ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 290806656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 2909ffd830a3SStefano Zampini 291025084f0cSStefano Zampini /* some shortcuts to scalars */ 291106656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 291288ebb749SStefano Zampini 291388ebb749SStefano Zampini PetscFunctionBegin; 29149a962809SStefano 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"); 2915ffd830a3SStefano Zampini 2916ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 2917b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 29184f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 2919b371cd4fSStefano Zampini n_B = pcis->n_B; 2920b371cd4fSStefano Zampini n_D = pcis->n - n_B; 292188ebb749SStefano Zampini n_R = pcis->n - n_vertices; 292288ebb749SStefano Zampini 292388ebb749SStefano Zampini /* vertices in boundary numbering */ 2924785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 29250e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 29266c4ed002SBarry 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); 292788ebb749SStefano Zampini 292806656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 2929019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 293006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 293106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 293206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 293306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 293406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 293506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 293606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 293706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 293806656605SStefano Zampini 293906656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 294006656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 294106656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 294206656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 294306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 2944ffd830a3SStefano Zampini lda_rhs = n_R; 2945a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 294606656605SStefano Zampini if (isLU || isILU || isCHOL) { 294706656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 2948b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 2949df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2950d62866d3SStefano Zampini MatFactorType type; 2951d62866d3SStefano Zampini 2952df4d28bfSStefano Zampini F = reuse_solver->F; 29536816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 2954d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 2955ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 295622db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 295706656605SStefano Zampini } else { 295806656605SStefano Zampini F = NULL; 295906656605SStefano Zampini } 296006656605SStefano Zampini 2961ffd830a3SStefano Zampini /* allocate workspace */ 2962ffd830a3SStefano Zampini n = 0; 2963ffd830a3SStefano Zampini if (n_constraints) { 2964ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 2965ffd830a3SStefano Zampini } 2966ffd830a3SStefano Zampini if (n_vertices) { 2967ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 2968ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 2969ffd830a3SStefano Zampini } 2970ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 2971ffd830a3SStefano Zampini 29725cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 29735cbda25cSStefano Zampini dummy_vec = NULL; 29745cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 29755cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 29765cbda25cSStefano Zampini } 29775cbda25cSStefano Zampini 297888ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 297988ebb749SStefano Zampini if (n_constraints) { 298072b8c272SStefano Zampini Mat M1,M2,M3,C_B; 298106656605SStefano Zampini IS is_aux; 298280677318SStefano Zampini PetscScalar *array,*array2; 298306656605SStefano Zampini 2984f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 298580677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 298688ebb749SStefano Zampini 298725084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 298825084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 29898ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 299072b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 299188ebb749SStefano Zampini 299280677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 299380677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 2994ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 299588ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 299606656605SStefano Zampini const PetscScalar *row_cmat_values; 299706656605SStefano Zampini const PetscInt *row_cmat_indices; 299806656605SStefano Zampini PetscInt size_of_constraint,j; 299988ebb749SStefano Zampini 300006656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 300106656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 3002ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 300306656605SStefano Zampini } 300406656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 300506656605SStefano Zampini } 3006ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 300706656605SStefano Zampini if (F) { 300806656605SStefano Zampini Mat B; 300906656605SStefano Zampini 3010ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 3011a3df083aSStefano Zampini if (need_benign_correction) { 3012df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3013a3df083aSStefano Zampini 301472b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 301572b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 3016a3df083aSStefano Zampini } 301780677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 3018a3df083aSStefano Zampini if (need_benign_correction) { 3019a3df083aSStefano Zampini PetscScalar *marr; 3020df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3021a3df083aSStefano Zampini 3022a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 30235cbda25cSStefano Zampini if (lda_rhs != n_R) { 30245cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 30255cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 30265cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 30275cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 30285cbda25cSStefano Zampini } 30295cbda25cSStefano Zampini } else { 3030a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 3031a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 30325cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3033a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3034a3df083aSStefano Zampini } 30355cbda25cSStefano Zampini } 3036a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 3037a3df083aSStefano Zampini } 303806656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 303906656605SStefano Zampini } else { 304080677318SStefano Zampini PetscScalar *marr; 304180677318SStefano Zampini 304280677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 304306656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3044ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3045ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 304606656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 304706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 304806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 304906656605SStefano Zampini } 305080677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 305106656605SStefano Zampini } 305280677318SStefano Zampini if (!pcbddc->switch_static) { 305380677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 305480677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 305580677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 305680677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3057ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 305880677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 305980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 306080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 306180677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 306280677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 306380677318SStefano Zampini } 306480677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 306580677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 306672b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 306780677318SStefano Zampini } else { 3068ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3069ffd830a3SStefano Zampini IS dummy; 3070ffd830a3SStefano Zampini 3071ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 307272b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3073ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3074ffd830a3SStefano Zampini } else { 307580677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 307680677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3077ffd830a3SStefano Zampini } 307825084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 307980677318SStefano Zampini } 308080677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 308180677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 308280677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 308306656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 308406656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 308580677318SStefano Zampini if (isCHOL) { 308680677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 308780677318SStefano Zampini } else { 308825084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 308980677318SStefano Zampini } 309080677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 309106656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 309225084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 309325084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 309425084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 309580677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 309672b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 309772b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 309806656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 309906656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 3100f4ddd8eeSStefano Zampini } 3101fc227af8SStefano Zampini 3102fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 310388ebb749SStefano Zampini if (n_vertices) { 310406656605SStefano Zampini IS is_aux; 31053a50541eSStefano Zampini 3106b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 31076816873aSStefano Zampini IS tis; 31086816873aSStefano Zampini 31096816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 31106816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 31116816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 31126816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 31136816873aSStefano Zampini } else { 31143a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 31156816873aSStefano Zampini } 31169577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 31179577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 311804708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 311925084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 312088ebb749SStefano Zampini } 312188ebb749SStefano Zampini 312288ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 3123f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 312406656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 312506656605SStefano Zampini if (pcbddc->coarse_phi_D) { 312606656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 312706656605SStefano Zampini } 3128f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 312906656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 313006656605SStefano Zampini PetscScalar *marray; 313106656605SStefano Zampini 313206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 313306656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 3134f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3135f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3136f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3137f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3138f4ddd8eeSStefano Zampini } 3139f4ddd8eeSStefano Zampini } 314006656605SStefano Zampini 3141f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 314206656605SStefano Zampini PetscScalar *marray; 314388ebb749SStefano Zampini 314406656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 31458eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 314606656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 314788ebb749SStefano Zampini } 31483301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 314906656605SStefano Zampini n *= 2; 315088ebb749SStefano Zampini } 315106656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 315206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 315306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 31548eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 315506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 315606656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 315788ebb749SStefano Zampini } 31583301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 315906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 31608eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 316106656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 316206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 316388ebb749SStefano Zampini } 316488ebb749SStefano Zampini } else { 3165c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 3166c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 31671b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3168c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 3169c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 3170c0553b1fSStefano Zampini } 317188ebb749SStefano Zampini } 317206656605SStefano Zampini } 3173019a44ceSStefano Zampini 317406656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 31754f1b2e48SStefano Zampini p0_lidx_I = NULL; 31764f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 3177d12edf2fSStefano Zampini const PetscInt *idxs; 3178d12edf2fSStefano Zampini 3179d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 31804f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 31814f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 31824f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 31834f1b2e48SStefano Zampini } 3184d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 3185d12edf2fSStefano Zampini } 3186d16cbb6bSStefano Zampini 318706656605SStefano Zampini /* vertices */ 318806656605SStefano Zampini if (n_vertices) { 318916f15bc4SStefano Zampini 3190af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 319104708bb6SStefano Zampini 319216f15bc4SStefano Zampini if (n_R) { 319314393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 319406656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 319516f15bc4SStefano Zampini PetscScalar *x,*y; 319604708bb6SStefano Zampini PetscBool isseqaij; 319706656605SStefano Zampini 319821eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 319914393ed6SStefano Zampini if (need_benign_correction) { 320014393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 320114393ed6SStefano Zampini IS is_p0; 320214393ed6SStefano Zampini PetscInt *idxs_p0,n; 320314393ed6SStefano Zampini 320414393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 320514393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 320614393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 3207af25d912SStefano 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); 320814393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 320914393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 321014393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 321114393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 321214393ed6SStefano Zampini } 321314393ed6SStefano Zampini 3214ffd830a3SStefano Zampini if (lda_rhs == n_R) { 3215af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3216ffd830a3SStefano Zampini } else { 3217ca92afb2SStefano Zampini PetscScalar *av,*array; 3218ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 3219ca92afb2SStefano Zampini PetscInt n; 3220ca92afb2SStefano Zampini PetscBool flg_row; 3221ffd830a3SStefano Zampini 3222ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 3223ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 32249d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3225ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3226ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 3227ca92afb2SStefano Zampini for (i=0;i<n;i++) { 3228ca92afb2SStefano Zampini PetscInt j; 3229ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 3230ffd830a3SStefano Zampini } 3231ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3232ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3233ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 3234ffd830a3SStefano Zampini } 3235ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3236a3df083aSStefano Zampini if (need_benign_correction) { 3237df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3238a3df083aSStefano Zampini PetscScalar *marr; 3239a3df083aSStefano Zampini 3240a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 324114393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 324214393ed6SStefano Zampini 324314393ed6SStefano Zampini | 0 0 0 | (V) 324414393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 324514393ed6SStefano Zampini | 0 0 -1 | (p0) 324614393ed6SStefano Zampini 324714393ed6SStefano Zampini */ 3248df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 324914393ed6SStefano Zampini const PetscScalar *vals; 325014393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 325114393ed6SStefano Zampini PetscInt n,j,nz; 325214393ed6SStefano Zampini 3253df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3254df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 325514393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 325614393ed6SStefano Zampini for (j=0;j<n;j++) { 325714393ed6SStefano Zampini PetscScalar val = vals[j]; 325814393ed6SStefano Zampini PetscInt k,col = idxs[j]; 325914393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 326014393ed6SStefano Zampini } 326114393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3262df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 326314393ed6SStefano Zampini } 326472b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 326572b8c272SStefano Zampini } 326672b8c272SStefano Zampini if (F) { 326714393ed6SStefano Zampini /* need to correct the rhs */ 326872b8c272SStefano Zampini if (need_benign_correction) { 326972b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 327072b8c272SStefano Zampini PetscScalar *marr; 327172b8c272SStefano Zampini 327272b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 32735cbda25cSStefano Zampini if (lda_rhs != n_R) { 32745cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 32755cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 32765cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 32775cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 32785cbda25cSStefano Zampini } 32795cbda25cSStefano Zampini } else { 3280a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3281a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 32825cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3283a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3284a3df083aSStefano Zampini } 32855cbda25cSStefano Zampini } 3286a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 3287a3df083aSStefano Zampini } 328806656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 328914393ed6SStefano Zampini /* need to correct the solution */ 3290a3df083aSStefano Zampini if (need_benign_correction) { 3291df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3292a3df083aSStefano Zampini PetscScalar *marr; 3293a3df083aSStefano Zampini 3294a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 32955cbda25cSStefano Zampini if (lda_rhs != n_R) { 32965cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 32975cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 32985cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 32995cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 33005cbda25cSStefano Zampini } 33015cbda25cSStefano Zampini } else { 3302a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3303a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 33045cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3305a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3306a3df083aSStefano Zampini } 33075cbda25cSStefano Zampini } 3308a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 3309a3df083aSStefano Zampini } 331006656605SStefano Zampini } else { 331106656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 331206656605SStefano Zampini for (i=0;i<n_vertices;i++) { 3313ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 3314ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 331506656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 331606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 331706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 331806656605SStefano Zampini } 331906656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 332006656605SStefano Zampini } 332180677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3322ffd830a3SStefano Zampini /* S_VV and S_CV */ 332306656605SStefano Zampini if (n_constraints) { 332406656605SStefano Zampini Mat B; 332580677318SStefano Zampini 3326ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 332780677318SStefano Zampini for (i=0;i<n_vertices;i++) { 3328ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3329ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 333080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 333180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 333280677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 333380677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 333480677318SStefano Zampini } 3335ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 333680677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 333780677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 3338ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 333980677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 334006656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 3341ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 3342ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 334306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 334406656605SStefano Zampini } 334504708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 334604708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 3347511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 334804708bb6SStefano Zampini } 3349ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3350ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 3351ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3352ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 3353ffd830a3SStefano Zampini } 335406656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 335514393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 335614393ed6SStefano Zampini if (need_benign_correction) { 3357df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 335814393ed6SStefano Zampini PetscScalar *marr,*sums; 335914393ed6SStefano Zampini 336014393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 3361f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 3362df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 336314393ed6SStefano Zampini const PetscScalar *vals; 336414393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 336514393ed6SStefano Zampini PetscInt n,j,nz; 336614393ed6SStefano Zampini 3367df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3368df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 336914393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 337014393ed6SStefano Zampini PetscInt k; 337114393ed6SStefano Zampini sums[j] = 0.; 337214393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 337314393ed6SStefano Zampini } 337414393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 337514393ed6SStefano Zampini for (j=0;j<n;j++) { 337614393ed6SStefano Zampini PetscScalar val = vals[j]; 337714393ed6SStefano Zampini PetscInt k; 337814393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 337914393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 338014393ed6SStefano Zampini } 338114393ed6SStefano Zampini } 338214393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3383df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 338414393ed6SStefano Zampini } 338514393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 3386f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 338714393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 338814393ed6SStefano Zampini } 338980677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 339006656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 339106656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 339206656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 339306656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 339406656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 339506656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 339606656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3397d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 3398019a44ceSStefano Zampini } else { 3399d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3400d16cbb6bSStefano Zampini } 340121eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 3402d16cbb6bSStefano Zampini 340306656605SStefano Zampini /* coarse basis functions */ 340406656605SStefano Zampini for (i=0;i<n_vertices;i++) { 340516f15bc4SStefano Zampini PetscScalar *y; 340616f15bc4SStefano Zampini 3407ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 340806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 340906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 341006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 341106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 341206656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 341306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 341406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 341506656605SStefano Zampini 341606656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 34174f1b2e48SStefano Zampini PetscInt j; 34184f1b2e48SStefano Zampini 341906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 342006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 342106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 342206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 342306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 34244f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 342506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 342606656605SStefano Zampini } 342706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 342806656605SStefano Zampini } 342904708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 343004708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 343106656605SStefano Zampini } 34325cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 343306656605SStefano Zampini 343406656605SStefano Zampini if (n_constraints) { 343506656605SStefano Zampini Mat B; 343606656605SStefano Zampini 3437ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 343806656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 343980677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 344006656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 344106656605SStefano Zampini if (n_vertices) { 344280677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 344380677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 344480677318SStefano Zampini } else { 344580677318SStefano Zampini Mat S_VCt; 344680677318SStefano Zampini 3447ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3448ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 344972b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 3450ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 3451ffd830a3SStefano Zampini } 345280677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 345380677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 345480677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 345580677318SStefano Zampini } 345606656605SStefano Zampini } 345706656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 345806656605SStefano Zampini /* coarse basis functions */ 345906656605SStefano Zampini for (i=0;i<n_constraints;i++) { 346006656605SStefano Zampini PetscScalar *y; 346106656605SStefano Zampini 3462ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 346306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 346406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 346506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 346606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 346706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 346806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 346906656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 34704f1b2e48SStefano Zampini PetscInt j; 34714f1b2e48SStefano Zampini 347206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 347306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 347406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 347506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 347606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 34774f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 347806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 347906656605SStefano Zampini } 348006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 348106656605SStefano Zampini } 348206656605SStefano Zampini } 348380677318SStefano Zampini if (n_constraints) { 348480677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 348580677318SStefano Zampini } 34864f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 348772b8c272SStefano Zampini 348872b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 348972b8c272SStefano Zampini if (pcbddc->benign_n) { 349072b8c272SStefano Zampini Mat B0_B,B0_BPHI; 349172b8c272SStefano Zampini IS is_dummy; 349272b8c272SStefano Zampini PetscScalar *data; 349372b8c272SStefano Zampini PetscInt j; 349472b8c272SStefano Zampini 349572b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 349672b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 349772b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 349872b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 349986c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 350072b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 350172b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 350272b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 350372b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 350472b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 350572b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 350672b8c272SStefano Zampini } 350772b8c272SStefano Zampini } 350872b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 350972b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 351072b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 351172b8c272SStefano Zampini } 3512019a44ceSStefano Zampini 351306656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 35143301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3515ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 3516ffd830a3SStefano Zampini PetscScalar *marray; 351706656605SStefano Zampini 351806656605SStefano Zampini if (n_constraints) { 3519ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 352006656605SStefano Zampini 3521af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 352206656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 3523ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 352416f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 352506656605SStefano Zampini if (n_vertices) { 3526ffd830a3SStefano Zampini Mat S_VCT; 352706656605SStefano Zampini 352806656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 3529ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 353016f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 353106656605SStefano Zampini } 3532ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 35335b782168SStefano Zampini } else { 35345b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 353506656605SStefano Zampini } 353616f15bc4SStefano Zampini if (n_vertices && n_R) { 3537ffd830a3SStefano Zampini PetscScalar *av,*marray; 3538ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 3539ffd830a3SStefano Zampini PetscInt n; 3540ffd830a3SStefano Zampini PetscBool flg_row; 354106656605SStefano Zampini 3542ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 3543af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3544ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3545ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 3546ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3547ffd830a3SStefano Zampini for (i=0;i<n;i++) { 3548ffd830a3SStefano Zampini PetscInt j; 3549ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 3550ffd830a3SStefano Zampini } 3551ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 3552ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3553ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 355406656605SStefano Zampini } 355506656605SStefano Zampini 3556ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 3557ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3558ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 3559ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 3560ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 356106656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 356206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 356306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 356406656605SStefano Zampini } 3565ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 35665b782168SStefano Zampini if (B_C) { 3567ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 3568ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 3569ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 3570ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 3571ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 3572ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3573ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 357406656605SStefano Zampini } 3575ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 35765b782168SStefano Zampini } 357706656605SStefano Zampini /* coarse basis functions */ 357806656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 357906656605SStefano Zampini PetscScalar *y; 358006656605SStefano Zampini 3581ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 358206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 358306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 358406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 358506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 358606656605SStefano Zampini if (i<n_vertices) { 358706656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 358806656605SStefano Zampini } 358906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 359006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 359106656605SStefano Zampini 359206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 359306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 359406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 359506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 359606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 359706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 359806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 359906656605SStefano Zampini } 360006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 360106656605SStefano Zampini } 3602ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 3603ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 360406656605SStefano Zampini } 3605d62866d3SStefano Zampini /* free memory */ 360688ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 360706656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 360806656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 360906656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 361006656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 3611d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3612d62866d3SStefano Zampini if (n_vertices) { 3613d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 3614d62866d3SStefano Zampini } 3615d62866d3SStefano Zampini if (n_constraints) { 3616d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 3617d62866d3SStefano Zampini } 361888ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 361988ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 362088ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 3621d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 362288ebb749SStefano Zampini Mat coarse_sub_mat; 362325084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 362488ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 362588ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 362688ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 36278bec7fa6SStefano Zampini Mat C_B,CPHI; 36288bec7fa6SStefano Zampini IS is_dummy; 36298bec7fa6SStefano Zampini Vec mones; 363088ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 363188ebb749SStefano Zampini PetscReal real_value; 363288ebb749SStefano Zampini 3633a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 3634a3df083aSStefano Zampini Mat A; 3635a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 3636a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 3637a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 3638a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 3639a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3640a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 3641a3df083aSStefano Zampini } else { 364288ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 364388ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 364488ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 364588ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3646a3df083aSStefano Zampini } 364788ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 364888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 3649ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 365088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 365188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 365288ebb749SStefano Zampini } 365388ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 365488ebb749SStefano Zampini 365525084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 36563301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 365725084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3658ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 365988ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 366088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 366188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 366288ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 366388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 366488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 366588ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 366688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 366788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 366888ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 366988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 367088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 367188ebb749SStefano Zampini } else { 367288ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 367388ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 367488ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 367588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 367688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 367788ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 367888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 367988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 368088ebb749SStefano Zampini } 368188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 368288ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 368388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 3684511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 36854f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3686fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 3687d12edf2fSStefano Zampini PetscScalar *data,*data2; 36884f1b2e48SStefano Zampini PetscInt j; 3689d12edf2fSStefano Zampini 36904f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 3691fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 3692d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 369386c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 3694d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 3695d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 36964f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 36974f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 3698d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 36994f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 37004f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 37014f1b2e48SStefano Zampini } 3702d12edf2fSStefano Zampini } 3703d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 3704d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 3705d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 3706d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 3707d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 3708d12edf2fSStefano Zampini } 3709d12edf2fSStefano Zampini #if 0 3710d12edf2fSStefano Zampini { 3711d12edf2fSStefano Zampini PetscViewer viewer; 3712d12edf2fSStefano Zampini char filename[256]; 3713ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 3714d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 3715d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3716ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 3717ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 3718ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 3719d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 372072b8c272SStefano Zampini if (save_change) { 372172b8c272SStefano Zampini Mat phi_B; 372272b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 372372b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 372472b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 372572b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 372672b8c272SStefano Zampini } else { 3727ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 3728ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 372972b8c272SStefano Zampini } 3730ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 3731ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 3732ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 3733ffd830a3SStefano Zampini } 3734ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 3735ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 3736ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 3737ffd830a3SStefano Zampini } 373872b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 3739ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 3740ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 3741ffd830a3SStefano Zampini } 3742d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3743d12edf2fSStefano Zampini } 3744d12edf2fSStefano Zampini #endif 374581d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 37468bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 37471575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 374806656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 37498bec7fa6SStefano Zampini 37508bec7fa6SStefano Zampini /* check constraints */ 3751a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 3752a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 37534f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 37548bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3755a00504b5SStefano Zampini } else { 3756a00504b5SStefano Zampini PetscScalar *data; 3757a00504b5SStefano Zampini Mat tmat; 3758a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 3759a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 3760a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 3761a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3762a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3763a00504b5SStefano Zampini } 37648bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 37658bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 37668bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 37678bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 3768bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 3769ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 3770bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3771bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 3772bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 3773bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 3774bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 377588ebb749SStefano Zampini } 37768bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 37778bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 37788bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 37798bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 378025084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 378188ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 378288ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 378388ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 378488ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 378588ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 378688ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 378788ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 378888ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 378988ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 379088ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 3791ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 379288ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 379388ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 379488ebb749SStefano Zampini } 379588ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 379688ebb749SStefano Zampini } 37978629588bSStefano Zampini /* get back data */ 37988629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 379988ebb749SStefano Zampini PetscFunctionReturn(0); 380088ebb749SStefano Zampini } 380188ebb749SStefano Zampini 380288ebb749SStefano Zampini #undef __FUNCT__ 3803d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 3804d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 3805aa0d41d4SStefano Zampini { 3806d65f70fdSStefano Zampini Mat *work_mat; 3807d65f70fdSStefano Zampini IS isrow_s,iscol_s; 3808d65f70fdSStefano Zampini PetscBool rsorted,csorted; 3809c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 3810aa0d41d4SStefano Zampini PetscErrorCode ierr; 3811aa0d41d4SStefano Zampini 3812aa0d41d4SStefano Zampini PetscFunctionBegin; 3813d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 3814d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 3815d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 3816d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 3817aa0d41d4SStefano Zampini 3818d65f70fdSStefano Zampini if (!rsorted) { 3819906d46d4SStefano Zampini const PetscInt *idxs; 3820906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 3821aa0d41d4SStefano Zampini 3822d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 3823d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 3824d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3825d65f70fdSStefano Zampini idxs_perm_r[i] = i; 3826aa0d41d4SStefano Zampini } 3827d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 3828d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 3829d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3830d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 3831aa0d41d4SStefano Zampini } 3832d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 3833d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 3834d65f70fdSStefano Zampini } else { 3835d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 3836d65f70fdSStefano Zampini isrow_s = isrow; 3837aa0d41d4SStefano Zampini } 3838906d46d4SStefano Zampini 3839d65f70fdSStefano Zampini if (!csorted) { 3840d65f70fdSStefano Zampini if (isrow == iscol) { 3841d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 3842d65f70fdSStefano Zampini iscol_s = isrow_s; 3843d65f70fdSStefano Zampini } else { 3844d65f70fdSStefano Zampini const PetscInt *idxs; 3845d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 3846906d46d4SStefano Zampini 3847d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 3848d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 3849d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3850d65f70fdSStefano Zampini idxs_perm_c[i] = i; 3851d65f70fdSStefano Zampini } 3852d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 3853d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 3854d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3855d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 3856d65f70fdSStefano Zampini } 3857d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 3858d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 3859d65f70fdSStefano Zampini } 3860d65f70fdSStefano Zampini } else { 3861d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 3862d65f70fdSStefano Zampini iscol_s = iscol; 3863d65f70fdSStefano Zampini } 3864d65f70fdSStefano Zampini 3865d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 3866d65f70fdSStefano Zampini 3867d65f70fdSStefano Zampini if (!rsorted || !csorted) { 3868906d46d4SStefano Zampini Mat new_mat; 3869d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 3870906d46d4SStefano Zampini 3871d65f70fdSStefano Zampini if (!rsorted) { 3872d65f70fdSStefano Zampini PetscInt *idxs_r,i; 3873d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 3874d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3875d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 3876906d46d4SStefano Zampini } 3877d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 3878d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 3879d65f70fdSStefano Zampini } else { 3880d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 3881906d46d4SStefano Zampini } 3882d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 3883d65f70fdSStefano Zampini 3884d65f70fdSStefano Zampini if (!csorted) { 3885d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 3886d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 3887d65f70fdSStefano Zampini is_perm_c = is_perm_r; 3888d65f70fdSStefano Zampini } else { 3889d65f70fdSStefano Zampini PetscInt *idxs_c,i; 3890f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 3891d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 3892d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3893d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 3894d65f70fdSStefano Zampini } 3895d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 3896d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 3897d65f70fdSStefano Zampini } 3898d65f70fdSStefano Zampini } else { 3899d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 3900d65f70fdSStefano Zampini } 3901d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 3902d65f70fdSStefano Zampini 3903d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 3904d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 3905d65f70fdSStefano Zampini work_mat[0] = new_mat; 3906d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 3907d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 3908d65f70fdSStefano Zampini } 3909d65f70fdSStefano Zampini 3910d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 3911d65f70fdSStefano Zampini *B = work_mat[0]; 3912d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 3913d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 3914d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 3915d65f70fdSStefano Zampini PetscFunctionReturn(0); 3916d65f70fdSStefano Zampini } 3917d65f70fdSStefano Zampini 3918d65f70fdSStefano Zampini #undef __FUNCT__ 39195e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 39205e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 3921aa0d41d4SStefano Zampini { 3922aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 39235e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3924d65f70fdSStefano Zampini Mat new_mat; 39255e8657edSStefano Zampini IS is_local,is_global; 3926d65f70fdSStefano Zampini PetscInt local_size; 3927d65f70fdSStefano Zampini PetscBool isseqaij; 3928aa0d41d4SStefano Zampini PetscErrorCode ierr; 3929aa0d41d4SStefano Zampini 3930aa0d41d4SStefano Zampini PetscFunctionBegin; 3931aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 39325e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 39335e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 3934b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 3935aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 3936d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 3937aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 3938906d46d4SStefano Zampini 3939906d46d4SStefano Zampini /* check */ 3940906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3941906d46d4SStefano Zampini Vec x,x_change; 3942906d46d4SStefano Zampini PetscReal error; 3943906d46d4SStefano Zampini 39445e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 3945906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 39465e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 3947e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3948e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3949d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 3950e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3951e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3952906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3953906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3954906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3955906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 3956906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3957906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3958906d46d4SStefano Zampini } 3959906d46d4SStefano Zampini 396022d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 39619b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 396222d5777bSStefano Zampini if (isseqaij) { 3963a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3964a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 3965aa0d41d4SStefano Zampini } else { 3966a00504b5SStefano Zampini Mat work_mat; 39671cf9b237SStefano Zampini 3968a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3969aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 3970a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 39711d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 3972aa0d41d4SStefano Zampini } 39733301b35fSStefano Zampini if (matis->A->symmetric_set) { 39743301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 3975e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 39763301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 3977e496cd5dSStefano Zampini #endif 39783301b35fSStefano Zampini } 3979d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 3980aa0d41d4SStefano Zampini PetscFunctionReturn(0); 3981aa0d41d4SStefano Zampini } 3982aa0d41d4SStefano Zampini 3983aa0d41d4SStefano Zampini #undef __FUNCT__ 3984a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 39858ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 3986a64d13efSStefano Zampini { 3987a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3988a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3989d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 399053892102SStefano Zampini PetscInt *idx_R_local=NULL; 39913a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 39923a50541eSStefano Zampini PetscInt vbs,bs; 39936816873aSStefano Zampini PetscBT bitmask=NULL; 3994a64d13efSStefano Zampini PetscErrorCode ierr; 3995a64d13efSStefano Zampini 3996a64d13efSStefano Zampini PetscFunctionBegin; 3997b23d619eSStefano Zampini /* 3998b23d619eSStefano Zampini No need to setup local scatters if 3999b23d619eSStefano Zampini - primal space is unchanged 4000b23d619eSStefano Zampini AND 4001b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 4002b23d619eSStefano Zampini AND 4003b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 4004b23d619eSStefano Zampini */ 4005b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 4006f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 4007f4ddd8eeSStefano Zampini } 4008f4ddd8eeSStefano Zampini /* destroy old objects */ 4009f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 4010f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 4011f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 4012a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 4013b371cd4fSStefano Zampini n_B = pcis->n_B; 4014b371cd4fSStefano Zampini n_D = pcis->n - n_B; 4015b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 40163a50541eSStefano Zampini 4017a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 40186816873aSStefano Zampini 401953892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 4020b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4021854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 4022a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 4023a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 40240e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 4025a64d13efSStefano Zampini } 4026a64d13efSStefano Zampini 4027a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 40284641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 40296816873aSStefano Zampini idx_R_local[n_R++] = i; 4030a64d13efSStefano Zampini } 4031a64d13efSStefano Zampini } 4032df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 4033df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 40346816873aSStefano Zampini 4035df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4036df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 40376816873aSStefano Zampini } 40383a50541eSStefano Zampini 40393a50541eSStefano Zampini /* Block code */ 40403a50541eSStefano Zampini vbs = 1; 40413a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 40423a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 40433a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 40443a50541eSStefano Zampini PetscInt *vary; 4045b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4046785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 40473a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 4048d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 4049d3df7717SStefano 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 */ 40500e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 4051d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 40523a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 40533a50541eSStefano Zampini is_blocked = PETSC_FALSE; 40543a50541eSStefano Zampini break; 40553a50541eSStefano Zampini } 40563a50541eSStefano Zampini } 4057d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 4058d3df7717SStefano Zampini } else { 4059d3df7717SStefano Zampini /* Verify directly the R set */ 4060d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 4061d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 4062d3df7717SStefano Zampini for (j=1; j<bs; j++) { 4063d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 4064d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 4065d3df7717SStefano Zampini break; 4066d3df7717SStefano Zampini } 4067d3df7717SStefano Zampini } 4068d3df7717SStefano Zampini } 4069d3df7717SStefano Zampini } 40703a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 40713a50541eSStefano Zampini vbs = bs; 40723a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 40733a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 40743a50541eSStefano Zampini } 40753a50541eSStefano Zampini } 40763a50541eSStefano Zampini } 40773a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 4078b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4079df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 408053892102SStefano Zampini 4081df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4082df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 408353892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 4084df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 408553892102SStefano Zampini } else { 40863a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 408753892102SStefano Zampini } 4088a64d13efSStefano Zampini 4089a64d13efSStefano Zampini /* print some info if requested */ 4090a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 4091a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4092a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 40931575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4094a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 4095a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 40964f1b2e48SStefano 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); 4097a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4098a64d13efSStefano Zampini } 4099a64d13efSStefano Zampini 4100a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 4101b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 41026816873aSStefano Zampini IS is_aux1,is_aux2; 41036816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 41046816873aSStefano Zampini 41053a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4106854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 4107854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 4108a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 41094641a718SStefano Zampini for (i=0; i<n_D; i++) { 41104641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 41114641a718SStefano Zampini } 4112a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4113a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 41144641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 41154641a718SStefano Zampini aux_array1[j++] = i; 4116a64d13efSStefano Zampini } 4117a64d13efSStefano Zampini } 4118a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4119a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4120a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 41214641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 41224641a718SStefano Zampini aux_array2[j++] = i; 4123a64d13efSStefano Zampini } 4124a64d13efSStefano Zampini } 4125a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4126a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 4127a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 4128a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4129a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 4130a64d13efSStefano Zampini 41318eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4132785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 4133a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 41344641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 41354641a718SStefano Zampini aux_array1[j++] = i; 4136a64d13efSStefano Zampini } 4137a64d13efSStefano Zampini } 4138a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4139a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 4140a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4141a64d13efSStefano Zampini } 41424641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 41433a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4144d62866d3SStefano Zampini } else { 4145df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 41466816873aSStefano Zampini IS tis; 41476816873aSStefano Zampini PetscInt schur_size; 41486816873aSStefano Zampini 4149df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 41506816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 4151df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 41526816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 41536816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 41546816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 41556816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 41566816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 4157d62866d3SStefano Zampini } 4158d62866d3SStefano Zampini } 4159a64d13efSStefano Zampini PetscFunctionReturn(0); 4160a64d13efSStefano Zampini } 4161a64d13efSStefano Zampini 4162304d26faSStefano Zampini 4163304d26faSStefano Zampini #undef __FUNCT__ 4164304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 4165684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 4166304d26faSStefano Zampini { 4167304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4168304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4169304d26faSStefano Zampini PC pc_temp; 4170304d26faSStefano Zampini Mat A_RR; 4171f4ddd8eeSStefano Zampini MatReuse reuse; 4172304d26faSStefano Zampini PetscScalar m_one = -1.0; 4173304d26faSStefano Zampini PetscReal value; 417404708bb6SStefano Zampini PetscInt n_D,n_R; 4175c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 4176304d26faSStefano Zampini PetscErrorCode ierr; 4177e604994aSStefano Zampini /* prefixes stuff */ 4178312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 4179e604994aSStefano Zampini size_t len; 4180304d26faSStefano Zampini 4181304d26faSStefano Zampini PetscFunctionBegin; 4182304d26faSStefano Zampini 4183e604994aSStefano Zampini /* compute prefixes */ 4184e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 4185e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 4186e604994aSStefano Zampini if (!pcbddc->current_level) { 4187e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4188e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4189e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4190e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4191e604994aSStefano Zampini } else { 4192e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4193312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4194e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4195e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 4196312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4197312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 419834d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 419934d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4200e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4201e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4202e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 4203e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 4204e604994aSStefano Zampini } 4205e604994aSStefano Zampini 4206304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 4207684f6988SStefano Zampini if (dirichlet) { 4208d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4209450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 42109a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 4211450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 4212a3df083aSStefano Zampini Mat A_IIn; 4213a3df083aSStefano Zampini 4214a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 4215a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 4216a3df083aSStefano Zampini pcis->A_II = A_IIn; 4217a3df083aSStefano Zampini } 4218450f8f5eSStefano Zampini } 42193301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 42203301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 4221964fefecSStefano Zampini } 4222ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 4223964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 4224304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 4225304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 4226304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 4227304d26faSStefano Zampini /* default */ 4228304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 4229e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 42309577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 4231304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 42329577ea80SStefano Zampini if (issbaij) { 42339577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 42349577ea80SStefano Zampini } else { 4235304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 42369577ea80SStefano Zampini } 4237304d26faSStefano Zampini /* Allow user's customization */ 4238304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 4239304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4240304d26faSStefano Zampini } 4241d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 4242b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4243df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4244d62866d3SStefano Zampini 4245df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 4246d5574798SStefano Zampini } 4247304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4248304d26faSStefano Zampini if (!n_D) { 4249304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 4250304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4251304d26faSStefano Zampini } 4252304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 4253304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 4254304d26faSStefano Zampini /* set ksp_D into pcis data */ 4255304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 4256304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 4257304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 4258684f6988SStefano Zampini } 4259304d26faSStefano Zampini 4260304d26faSStefano Zampini /* NEUMANN PROBLEM */ 4261684f6988SStefano Zampini A_RR = 0; 4262684f6988SStefano Zampini if (neumann) { 4263d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 426404708bb6SStefano Zampini PetscInt ibs,mbs; 426504708bb6SStefano Zampini PetscBool issbaij; 426604708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4267f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 42688ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 4269f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 4270f4ddd8eeSStefano Zampini PetscInt nn_R; 427181d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 4272f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4273f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 4274f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 4275f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 4276f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4277f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4278f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 4279727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 4280f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4281f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4282f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 4283f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 4284f4ddd8eeSStefano Zampini } 4285f4ddd8eeSStefano Zampini } 4286f4ddd8eeSStefano Zampini /* last check */ 4287d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 4288f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4289f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4290f4ddd8eeSStefano Zampini } 4291f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 4292f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4293f4ddd8eeSStefano Zampini } 4294a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 4295af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 4296af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 429704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 429804708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 429904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 430004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 430104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 4302af732b37SStefano Zampini } else { 4303511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 43046816873aSStefano Zampini } 430504708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 430604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 430704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 430804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 430904708bb6SStefano Zampini } else { 4310511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 431104708bb6SStefano Zampini } 431204708bb6SStefano Zampini } 4313a00504b5SStefano Zampini /* extract A_RR */ 4314b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4315a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4316a00504b5SStefano Zampini 4317a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 431816e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4319a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 432016e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 432116e386b8SStefano Zampini } else { 4322a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 4323a00504b5SStefano Zampini } 4324a00504b5SStefano Zampini } else { 4325a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4326a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 4327a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4328a00504b5SStefano Zampini } 4329a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 4330f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 433116e386b8SStefano Zampini } 43323301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 43333301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 43346816873aSStefano Zampini } 4335f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 4336304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 4337304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 4338304d26faSStefano Zampini /* default */ 4339304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 4340e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 4341304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 43429577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 43439577ea80SStefano Zampini if (issbaij) { 43449577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 43459577ea80SStefano Zampini } else { 4346304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 43479577ea80SStefano Zampini } 4348304d26faSStefano Zampini /* Allow user's customization */ 4349304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 4350304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4351304d26faSStefano Zampini } 4352304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4353304d26faSStefano Zampini if (!n_R) { 4354304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 4355304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4356304d26faSStefano Zampini } 43575cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 4358df4d28bfSStefano Zampini /* Reuse solver if it is present */ 4359b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4360df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4361d62866d3SStefano Zampini 4362df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 4363d62866d3SStefano Zampini } 4364304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 4365304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 4366684f6988SStefano Zampini } 4367304d26faSStefano Zampini 4368684f6988SStefano Zampini if (pcbddc->dbg_flag) { 4369684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 43701575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4371684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4372684f6988SStefano Zampini } 4373c7017625SStefano Zampini 4374c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 4375c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 4376c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 4377c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 4378c7017625SStefano Zampini } 4379c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 4380c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 4381c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 4382c7017625SStefano Zampini } 4383c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 4384c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 4385c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 4386c7017625SStefano Zampini } 4387c7017625SStefano Zampini 4388c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 4389c7017625SStefano Zampini if (pcbddc->dbg_flag) { 4390684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 43910fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 43920fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 43930fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 43940fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 43950fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 4396e604994aSStefano 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); 4397c7017625SStefano Zampini if (check_corr[0]) { 4398c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 4399c7017625SStefano Zampini } 4400304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4401304d26faSStefano Zampini } 4402684f6988SStefano Zampini if (neumann) { /* Neumann */ 44030fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 44040fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 44050fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 44060fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 44070fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 4408e604994aSStefano 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); 4409c7017625SStefano Zampini if (check_corr[1]) { 4410c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 4411c7017625SStefano Zampini } 4412304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4413304d26faSStefano Zampini } 4414684f6988SStefano Zampini } 44155cbda25cSStefano Zampini /* free Neumann problem's matrix */ 44165cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4417304d26faSStefano Zampini PetscFunctionReturn(0); 4418304d26faSStefano Zampini } 4419304d26faSStefano Zampini 4420304d26faSStefano Zampini #undef __FUNCT__ 4421ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 442280677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 4423674ae819SStefano Zampini { 4424674ae819SStefano Zampini PetscErrorCode ierr; 4425674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4426be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4427b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 4428674ae819SStefano Zampini 4429674ae819SStefano Zampini PetscFunctionBegin; 4430b334f244SStefano Zampini if (!reuse_solver) { 443180677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 443220c7b377SStefano Zampini } 443380677318SStefano Zampini if (!pcbddc->switch_static) { 443480677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 443580677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 443680677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 443720c7b377SStefano Zampini } 4438b334f244SStefano Zampini if (!reuse_solver) { 443980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 444080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 444120c7b377SStefano Zampini } else { 4442df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4443be83ff47SStefano Zampini 4444df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4445df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 444620c7b377SStefano Zampini } 4447be83ff47SStefano Zampini } else { 444880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 444980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 445080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 445180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 445280677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 445380677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 445480677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 445580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 445680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4457674ae819SStefano Zampini } 4458674ae819SStefano Zampini } 4459b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 446080677318SStefano Zampini if (applytranspose) { 446180677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 446280677318SStefano Zampini } else { 446380677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 446480677318SStefano Zampini } 4465be83ff47SStefano Zampini } else { 4466df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4467be83ff47SStefano Zampini 4468be83ff47SStefano Zampini if (applytranspose) { 4469df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4470be83ff47SStefano Zampini } else { 4471df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4472be83ff47SStefano Zampini } 4473be83ff47SStefano Zampini } 447480677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 447580677318SStefano Zampini if (!pcbddc->switch_static) { 4476b334f244SStefano Zampini if (!reuse_solver) { 447780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 447880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4479be83ff47SStefano Zampini } else { 4480df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4481be83ff47SStefano Zampini 4482df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4483df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4484be83ff47SStefano Zampini } 448580677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 448680677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 448780677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 448880677318SStefano Zampini } 448980677318SStefano Zampini } else { 449080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 449180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 449280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 449380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 449480677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 449580677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 449680677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 449780677318SStefano Zampini } 449880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 449980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 450080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 450180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4502674ae819SStefano Zampini } 4503674ae819SStefano Zampini PetscFunctionReturn(0); 4504674ae819SStefano Zampini } 4505674ae819SStefano Zampini 4506dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 4507674ae819SStefano Zampini #undef __FUNCT__ 4508674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 4509dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 4510674ae819SStefano Zampini { 4511674ae819SStefano Zampini PetscErrorCode ierr; 4512674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4513674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 4514674ae819SStefano Zampini const PetscScalar zero = 0.0; 4515674ae819SStefano Zampini 4516674ae819SStefano Zampini PetscFunctionBegin; 4517dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 45184fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4519dc359a40SStefano Zampini if (applytranspose) { 4520674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 45218eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 4522dc359a40SStefano Zampini } else { 4523674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 4524674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 452515aaf578SStefano Zampini } 45264fee134fSStefano Zampini } else { 45274fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 45284fee134fSStefano Zampini } 4529efc2fbd9SStefano Zampini 4530efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 45314f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4532efc2fbd9SStefano Zampini PetscScalar *array; 45334f1b2e48SStefano Zampini PetscInt j; 4534efc2fbd9SStefano Zampini 4535efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 45364f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 4537efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4538efc2fbd9SStefano Zampini } 4539efc2fbd9SStefano Zampini 454012edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 454112edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 454212edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 454312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 454412edc857SStefano Zampini 45459f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 454612edc857SStefano Zampini if (pcbddc->coarse_ksp) { 454751694757SStefano Zampini Mat coarse_mat; 4548964fefecSStefano Zampini Vec rhs,sol; 454951694757SStefano Zampini MatNullSpace nullsp; 455027b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 4551964fefecSStefano Zampini 455227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 455327b6a85dSStefano Zampini PC coarse_pc; 455427b6a85dSStefano Zampini 455527b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 455627b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 455727b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 455827b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 455927b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 456027b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 45613bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 456227b6a85dSStefano Zampini } 456327b6a85dSStefano Zampini } 4564964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 4565964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 456651694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 456751694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 456851694757SStefano Zampini if (nullsp) { 456951694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 457051694757SStefano Zampini } 457112edc857SStefano Zampini if (applytranspose) { 45729a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 4573964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 45742701bc32SStefano Zampini } else { 45751f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 45762701bc32SStefano Zampini PC coarse_pc; 45772701bc32SStefano Zampini 45782701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 45792701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 45803e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 45812701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 458212edc857SStefano Zampini } else { 4583964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 458412edc857SStefano Zampini } 45852701bc32SStefano Zampini } 45861d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 458727b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 458827b6a85dSStefano Zampini PC coarse_pc; 458927b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 459027b6a85dSStefano Zampini 459127b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 459227b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 459327b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 45943bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 459527b6a85dSStefano Zampini } 459651694757SStefano Zampini if (nullsp) { 459751694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 459851694757SStefano Zampini } 459912edc857SStefano Zampini } 4600674ae819SStefano Zampini 4601674ae819SStefano Zampini /* Local solution on R nodes */ 46024fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 460380677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 46049f00e9b4SStefano Zampini } 46059f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 46069f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 460712edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4608674ae819SStefano Zampini 46094fee134fSStefano Zampini /* Sum contributions from the two levels */ 46104fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4611dc359a40SStefano Zampini if (applytranspose) { 4612dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 4613dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4614dc359a40SStefano Zampini } else { 4615674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 46168eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4617dc359a40SStefano Zampini } 4618efc2fbd9SStefano Zampini /* store p0 */ 46194f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4620efc2fbd9SStefano Zampini PetscScalar *array; 46214f1b2e48SStefano Zampini PetscInt j; 4622efc2fbd9SStefano Zampini 4623efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 46244f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 4625efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4626efc2fbd9SStefano Zampini } 46274fee134fSStefano Zampini } else { /* expand the coarse solution */ 46284fee134fSStefano Zampini if (applytranspose) { 46294fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 46304fee134fSStefano Zampini } else { 46314fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 46324fee134fSStefano Zampini } 46334fee134fSStefano Zampini } 4634674ae819SStefano Zampini PetscFunctionReturn(0); 4635674ae819SStefano Zampini } 4636674ae819SStefano Zampini 4637674ae819SStefano Zampini #undef __FUNCT__ 4638674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 463912edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 4640674ae819SStefano Zampini { 4641674ae819SStefano Zampini PetscErrorCode ierr; 4642674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 464358da7f69SStefano Zampini PetscScalar *array; 464412edc857SStefano Zampini Vec from,to; 4645674ae819SStefano Zampini 4646674ae819SStefano Zampini PetscFunctionBegin; 464712edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 464812edc857SStefano Zampini from = pcbddc->coarse_vec; 464912edc857SStefano Zampini to = pcbddc->vec1_P; 465012edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 465112edc857SStefano Zampini Vec tvec; 465258da7f69SStefano Zampini 465358da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 465458da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 465512edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 465658da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 465758da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 465858da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 465912edc857SStefano Zampini } 466012edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 466112edc857SStefano Zampini from = pcbddc->vec1_P; 466212edc857SStefano Zampini to = pcbddc->coarse_vec; 466312edc857SStefano Zampini } 466412edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 4665674ae819SStefano Zampini PetscFunctionReturn(0); 4666674ae819SStefano Zampini } 4667674ae819SStefano Zampini 4668674ae819SStefano Zampini #undef __FUNCT__ 4669674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 467012edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 4671674ae819SStefano Zampini { 4672674ae819SStefano Zampini PetscErrorCode ierr; 4673674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 467458da7f69SStefano Zampini PetscScalar *array; 467512edc857SStefano Zampini Vec from,to; 4676674ae819SStefano Zampini 4677674ae819SStefano Zampini PetscFunctionBegin; 467812edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 467912edc857SStefano Zampini from = pcbddc->coarse_vec; 468012edc857SStefano Zampini to = pcbddc->vec1_P; 468112edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 468212edc857SStefano Zampini from = pcbddc->vec1_P; 468312edc857SStefano Zampini to = pcbddc->coarse_vec; 468412edc857SStefano Zampini } 468512edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 468612edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 468712edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 468812edc857SStefano Zampini Vec tvec; 468958da7f69SStefano Zampini 469012edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 469158da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 469258da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 469358da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 469458da7f69SStefano Zampini } 469558da7f69SStefano Zampini } else { 469658da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 469758da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 469812edc857SStefano Zampini } 469912edc857SStefano Zampini } 4700674ae819SStefano Zampini PetscFunctionReturn(0); 4701674ae819SStefano Zampini } 4702674ae819SStefano Zampini 4703984c4197SStefano Zampini /* uncomment for testing purposes */ 4704984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 4705674ae819SStefano Zampini #undef __FUNCT__ 4706674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 4707674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 4708674ae819SStefano Zampini { 4709674ae819SStefano Zampini PetscErrorCode ierr; 4710674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4711674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4712674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4713984c4197SStefano Zampini /* one and zero */ 4714984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 4715984c4197SStefano Zampini /* space to store constraints and their local indices */ 47169162d606SStefano Zampini PetscScalar *constraints_data; 47179162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 47189162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 47199162d606SStefano Zampini PetscInt *constraints_n; 4720984c4197SStefano Zampini /* iterators */ 4721b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 4722984c4197SStefano Zampini /* BLAS integers */ 4723e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 4724e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 4725c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 4726727cdba6SStefano Zampini /* reuse */ 47270e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 47280e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 4729984c4197SStefano Zampini /* change of basis */ 4730b3d85658SStefano Zampini PetscBool qr_needed; 47319162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 4732984c4197SStefano Zampini /* auxiliary stuff */ 473364efe560SStefano Zampini PetscInt *nnz,*is_indices; 47348a0068c3SStefano Zampini PetscInt ncc; 4735984c4197SStefano Zampini /* some quantities */ 473645a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 4737a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 4738984c4197SStefano Zampini 4739674ae819SStefano Zampini PetscFunctionBegin; 47408e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 47418e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 47428e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 474316909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 4744088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 4745088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 47460e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 47470e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 47480e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 47490e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 47500e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 4751088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 4752cf5a6209SStefano Zampini 4753cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 47549162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 4755cf5a6209SStefano Zampini MatNullSpace nearnullsp; 4756cf5a6209SStefano Zampini const Vec *nearnullvecs; 4757cf5a6209SStefano Zampini Vec *localnearnullsp; 4758cf5a6209SStefano Zampini PetscScalar *array; 4759cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 4760cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 4761674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 4762b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 4763674ae819SStefano Zampini PetscScalar *work; 4764674ae819SStefano Zampini PetscReal *singular_vals; 4765674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4766674ae819SStefano Zampini PetscReal *rwork; 4767674ae819SStefano Zampini #endif 4768674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4769674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 4770674ae819SStefano Zampini #else 4771964fefecSStefano Zampini PetscBLASInt dummy_int=1; 4772964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 4773674ae819SStefano Zampini #endif 4774674ae819SStefano Zampini 4775674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 4776d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 4777e4d548c7SStefano Zampini /* print some info */ 47781f4df5f7SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs) { 4779e4d548c7SStefano Zampini PetscInt nv; 4780e4d548c7SStefano Zampini 4781c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 4782e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 4783e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4784e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 4785e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 4786e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 4787e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 4788e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4789e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4790e4d548c7SStefano Zampini } 4791e4d548c7SStefano Zampini 4792d06fc5fdSStefano Zampini /* free unneeded index sets */ 4793d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 4794d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 4795674ae819SStefano Zampini } 4796d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 4797d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 4798d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 4799d06fc5fdSStefano Zampini } 4800d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 4801d06fc5fdSStefano Zampini n_ISForEdges = 0; 4802d06fc5fdSStefano Zampini } 4803d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 4804d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 4805d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 4806d06fc5fdSStefano Zampini } 4807d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 4808d06fc5fdSStefano Zampini n_ISForFaces = 0; 4809d06fc5fdSStefano Zampini } 481070022509SStefano Zampini 4811674ae819SStefano Zampini /* check if near null space is attached to global mat */ 4812674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 4813674ae819SStefano Zampini if (nearnullsp) { 4814674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 4815f4ddd8eeSStefano Zampini /* remove any stored info */ 4816f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 4817f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 4818f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 4819f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 4820f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 4821473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 4822f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 4823f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 4824f4ddd8eeSStefano Zampini } 4825984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 4826984c4197SStefano Zampini nnsp_size = 0; 4827674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 4828674ae819SStefano Zampini } 4829984c4197SStefano Zampini /* get max number of constraints on a single cc */ 4830984c4197SStefano Zampini max_constraints = nnsp_size; 4831984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 4832984c4197SStefano Zampini 4833674ae819SStefano Zampini /* 4834674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 48359162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 48369162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 48379162d606SStefano Zampini There can be multiple constraints per connected component 4838674ae819SStefano Zampini */ 4839674ae819SStefano Zampini n_vertices = 0; 4840674ae819SStefano Zampini if (ISForVertices) { 4841674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 4842674ae819SStefano Zampini } 48439162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 48449162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 48459162d606SStefano Zampini 48469162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 48479162d606SStefano Zampini total_counts *= max_constraints; 4848674ae819SStefano Zampini total_counts += n_vertices; 48494641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 48509162d606SStefano Zampini 4851674ae819SStefano Zampini total_counts = 0; 4852674ae819SStefano Zampini max_size_of_constraint = 0; 4853674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 48549162d606SStefano Zampini IS used_is; 4855674ae819SStefano Zampini if (i<n_ISForEdges) { 48569162d606SStefano Zampini used_is = ISForEdges[i]; 4857674ae819SStefano Zampini } else { 48589162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 4859674ae819SStefano Zampini } 48609162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 4861674ae819SStefano Zampini total_counts += j; 4862674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 4863674ae819SStefano Zampini } 48649162d606SStefano 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); 48659162d606SStefano Zampini 4866984c4197SStefano Zampini /* get local part of global near null space vectors */ 4867785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 4868984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 4869984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 4870e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4871e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4872984c4197SStefano Zampini } 4873674ae819SStefano Zampini 4874242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 4875242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 4876a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 4877242a89d7SStefano Zampini 4878984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 4879a773dcb8SStefano Zampini if (!skip_lapack) { 4880674ae819SStefano Zampini PetscScalar temp_work; 4881911cabfeSStefano Zampini 4882674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4883984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 4884785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 4885785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 4886785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 4887674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4888785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 4889674ae819SStefano Zampini #endif 4890674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 4891c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 4892c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 4893674ae819SStefano Zampini lwork = -1; 4894674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4895674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 4896c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 4897674ae819SStefano Zampini #else 4898c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 4899674ae819SStefano Zampini #endif 4900674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4901984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 4902674ae819SStefano Zampini #else /* on missing GESVD */ 4903674ae819SStefano Zampini /* SVD */ 4904674ae819SStefano Zampini PetscInt max_n,min_n; 4905674ae819SStefano Zampini max_n = max_size_of_constraint; 4906984c4197SStefano Zampini min_n = max_constraints; 4907984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 4908674ae819SStefano Zampini min_n = max_size_of_constraint; 4909984c4197SStefano Zampini max_n = max_constraints; 4910674ae819SStefano Zampini } 4911785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 4912674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4913785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 4914674ae819SStefano Zampini #endif 4915674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 4916674ae819SStefano Zampini lwork = -1; 4917e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 4918e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 4919b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 4920674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4921674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 49229162d606SStefano 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)); 4923674ae819SStefano Zampini #else 49249162d606SStefano 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)); 4925674ae819SStefano Zampini #endif 4926674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4927984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 4928984c4197SStefano Zampini #endif /* on missing GESVD */ 4929674ae819SStefano Zampini /* Allocate optimal workspace */ 4930674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 4931854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 4932674ae819SStefano Zampini } 4933674ae819SStefano Zampini /* Now we can loop on constraining sets */ 4934674ae819SStefano Zampini total_counts = 0; 49359162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 49369162d606SStefano Zampini constraints_data_ptr[0] = 0; 4937674ae819SStefano Zampini /* vertices */ 49389162d606SStefano Zampini if (n_vertices) { 4939674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 49409162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 4941674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 49429162d606SStefano Zampini constraints_n[total_counts] = 1; 49439162d606SStefano Zampini constraints_data[total_counts] = 1.0; 49449162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 49459162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 4946674ae819SStefano Zampini total_counts++; 4947674ae819SStefano Zampini } 4948674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4949674ae819SStefano Zampini n_vertices = total_counts; 4950674ae819SStefano Zampini } 4951984c4197SStefano Zampini 4952674ae819SStefano Zampini /* edges and faces */ 49539162d606SStefano Zampini total_counts_cc = total_counts; 4954911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 49559162d606SStefano Zampini IS used_is; 49569162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 49579162d606SStefano Zampini 4958911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 49599162d606SStefano Zampini used_is = ISForEdges[ncc]; 4960984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 4961674ae819SStefano Zampini } else { 49629162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 4963984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 4964674ae819SStefano Zampini } 4965674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 49669162d606SStefano Zampini 49679162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 49689162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4969984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 4970984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 4971674ae819SStefano Zampini if (nnsp_has_cnst) { 49725b08dc53SStefano Zampini PetscScalar quad_value; 49739162d606SStefano Zampini 49749162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 49759162d606SStefano Zampini idxs_copied = PETSC_TRUE; 49769162d606SStefano Zampini 4977a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 4978674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 4979a773dcb8SStefano Zampini } else { 4980a773dcb8SStefano Zampini quad_value = 1.0; 4981a773dcb8SStefano Zampini } 4982674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 49839162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 4984674ae819SStefano Zampini } 49859162d606SStefano Zampini temp_constraints++; 4986674ae819SStefano Zampini total_counts++; 4987674ae819SStefano Zampini } 4988674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 4989984c4197SStefano Zampini PetscReal real_value; 49909162d606SStefano Zampini PetscScalar *ptr_to_data; 49919162d606SStefano Zampini 4992984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 49939162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 4994674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 49959162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 4996674ae819SStefano Zampini } 4997984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 4998984c4197SStefano Zampini /* check if array is null on the connected component */ 4999e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 50009162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 50015b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 5002674ae819SStefano Zampini temp_constraints++; 5003674ae819SStefano Zampini total_counts++; 50049162d606SStefano Zampini if (!idxs_copied) { 50059162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 50069162d606SStefano Zampini idxs_copied = PETSC_TRUE; 5007674ae819SStefano Zampini } 5008674ae819SStefano Zampini } 50099162d606SStefano Zampini } 50109162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 501145a1bb75SStefano Zampini valid_constraints = temp_constraints; 5012eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 5013a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 50149162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 50159162d606SStefano Zampini 50169162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5017a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 50189162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 5019a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 50209162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 5021a773dcb8SStefano Zampini } else { /* perform SVD */ 5022984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 50239162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5024674ae819SStefano Zampini 5025674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5026984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 5027984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 5028984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 5029984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 5030984c4197SStefano Zampini from that computed using LAPACKgesvd 5031984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 5032984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 5033984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 5034674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 5035e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5036984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5037674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 5038674ae819SStefano Zampini for (k=0;k<j+1;k++) { 50399162d606SStefano 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)); 5040674ae819SStefano Zampini } 5041674ae819SStefano Zampini } 5042e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 5043e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5044e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 5045674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5046c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 5047674ae819SStefano Zampini #else 5048c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 5049674ae819SStefano Zampini #endif 5050674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5051984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 5052984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 5053674ae819SStefano Zampini j = 0; 5054984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 5055674ae819SStefano Zampini total_counts = total_counts-j; 505645a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 5057e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 5058c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5059c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5060c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 5061c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5062c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 5063c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5064674ae819SStefano Zampini if (j<temp_constraints) { 5065984c4197SStefano Zampini PetscInt ii; 5066984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 5067674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 50689162d606SStefano 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)); 5069674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5070984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 5071674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 50729162d606SStefano 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]; 5073674ae819SStefano Zampini } 5074674ae819SStefano Zampini } 5075674ae819SStefano Zampini } 5076674ae819SStefano Zampini #else /* on missing GESVD */ 5077e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5078e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5079b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5080674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5081674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 50829162d606SStefano 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)); 5083674ae819SStefano Zampini #else 50849162d606SStefano 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)); 5085674ae819SStefano Zampini #endif 5086984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 5087674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5088984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 5089e310c8b4SStefano Zampini k = temp_constraints; 5090e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 5091674ae819SStefano Zampini j = 0; 5092e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 509345a1bb75SStefano Zampini valid_constraints = k-j; 5094911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 5095984c4197SStefano Zampini #endif /* on missing GESVD */ 5096674ae819SStefano Zampini } 5097a773dcb8SStefano Zampini } 50989162d606SStefano Zampini /* update pointers information */ 50999162d606SStefano Zampini if (valid_constraints) { 51009162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 51019162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 51029162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 51039162d606SStefano Zampini /* set change_of_basis flag */ 510445a1bb75SStefano Zampini if (boolforchange) { 5105b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 51069162d606SStefano Zampini } 5107b3d85658SStefano Zampini total_counts_cc++; 510845a1bb75SStefano Zampini } 510945a1bb75SStefano Zampini } 5110984c4197SStefano Zampini /* free workspace */ 51118f1c130eSStefano Zampini if (!skip_lapack) { 5112984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 5113984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5114984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 5115984c4197SStefano Zampini #endif 5116984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 5117984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5118984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 5119984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 5120984c4197SStefano Zampini #endif 5121984c4197SStefano Zampini } 5122984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5123984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 5124984c4197SStefano Zampini } 5125984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 5126cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 5127cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5128cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5129cf5a6209SStefano Zampini } 5130cf5a6209SStefano Zampini if (n_ISForFaces) { 5131cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5132cf5a6209SStefano Zampini } 5133cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5134cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5135cf5a6209SStefano Zampini } 5136cf5a6209SStefano Zampini if (n_ISForEdges) { 5137cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5138cf5a6209SStefano Zampini } 5139cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 514008122e43SStefano Zampini } else { 514108122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5142984c4197SStefano Zampini 514308122e43SStefano Zampini total_counts = 0; 514408122e43SStefano Zampini n_vertices = 0; 5145d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 5146d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 514708122e43SStefano Zampini } 514808122e43SStefano Zampini max_constraints = 0; 51499162d606SStefano Zampini total_counts_cc = 0; 515008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 515108122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 51529162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 515308122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 515408122e43SStefano Zampini } 51559162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 51569162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 51579162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 51589162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 515974d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 51609162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 51619162d606SStefano Zampini total_counts_cc = 0; 51629162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 51639162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 51649162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 516508122e43SStefano Zampini } 516608122e43SStefano Zampini } 51679162d606SStefano Zampini #if 0 51689162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 51699162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 51709162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 51719162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 51729162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 51739162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 51749162d606SStefano Zampini } 51759162d606SStefano Zampini printf("\n"); 51769162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 51779162d606SStefano Zampini } 51781b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 51798bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 51801b968477SStefano Zampini } 51811b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 51828bec7fa6SStefano 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]); 51831b968477SStefano Zampini } 518408122e43SStefano Zampini #endif 518508122e43SStefano Zampini 51868bec7fa6SStefano Zampini max_size_of_constraint = 0; 51879162d606SStefano 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]); 51889162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 518908122e43SStefano Zampini /* Change of basis */ 5190b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 519108122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 519208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 519308122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 5194b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 519508122e43SStefano Zampini } 519608122e43SStefano Zampini } 519708122e43SStefano Zampini } 519808122e43SStefano Zampini } 5199984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 52004f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 520108122e43SStefano Zampini 52029162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 52039162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 52046c4ed002SBarry 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); 5205674ae819SStefano Zampini 5206674ae819SStefano Zampini /* Create constraint matrix */ 5207674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 520816f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 5209984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 5210984c4197SStefano Zampini 5211984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 5212a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 5213a717540cSStefano Zampini qr_needed = PETSC_FALSE; 521474d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 5215984c4197SStefano Zampini total_primal_vertices=0; 5216b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 52179162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 52189162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 521972b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 52209162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 5221b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 522264efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 52239162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 52249162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 5225a717540cSStefano Zampini } 5226b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 522791af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 5228a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 5229a717540cSStefano Zampini qr_needed = PETSC_TRUE; 5230a717540cSStefano Zampini } 5231fa434743SStefano Zampini } else { 5232b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 5233fa434743SStefano Zampini } 5234a717540cSStefano Zampini } 5235b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 5236b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 5237674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 523870022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5239b3d85658SStefano Zampini 52404f1b2e48SStefano 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); 52410e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 52420e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 5243984c4197SStefano Zampini 5244984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 524574d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 5246785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 5247984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 524874d5cdf7SStefano Zampini 5249984c4197SStefano Zampini j = total_primal_vertices; 525074d5cdf7SStefano Zampini total_counts = total_primal_vertices; 5251b3d85658SStefano Zampini cum = total_primal_vertices; 52529162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 52534641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 5254b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 5255b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 5256b3d85658SStefano Zampini cum++; 52579162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 525874d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 525974d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 526074d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 526174d5cdf7SStefano Zampini } 52629162d606SStefano Zampini j += constraints_n[i]; 5263674ae819SStefano Zampini } 5264674ae819SStefano Zampini } 5265674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 5266674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 5267088faed8SStefano Zampini 5268674ae819SStefano Zampini /* set values in constraint matrix */ 5269984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 52700e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5271674ae819SStefano Zampini } 5272984c4197SStefano Zampini total_counts = total_primal_vertices; 52739162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 52744641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 52759162d606SStefano Zampini PetscInt *cols; 52769162d606SStefano Zampini 52779162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 52789162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 52799162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 52809162d606SStefano Zampini PetscInt row = total_counts+k; 52819162d606SStefano Zampini PetscScalar *vals; 52829162d606SStefano Zampini 52839162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 52849162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 52859162d606SStefano Zampini } 52869162d606SStefano Zampini total_counts += constraints_n[i]; 5287674ae819SStefano Zampini } 5288674ae819SStefano Zampini } 5289674ae819SStefano Zampini /* assembling */ 5290674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5291674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5292088faed8SStefano Zampini 5293984c4197SStefano Zampini /* 52946a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5295984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 5296f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 5297984c4197SStefano Zampini */ 5298674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 5299674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 5300026de310SStefano Zampini /* dual and primal dofs on a single cc */ 5301984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 5302984c4197SStefano Zampini /* working stuff for GEQRF */ 530381d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 5304984c4197SStefano Zampini PetscBLASInt lqr_work; 5305984c4197SStefano Zampini /* working stuff for UNGQR */ 5306984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 5307984c4197SStefano Zampini PetscBLASInt lgqr_work; 5308984c4197SStefano Zampini /* working stuff for TRTRS */ 5309984c4197SStefano Zampini PetscScalar *trs_rhs; 53103f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 5311984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 5312984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 5313984c4197SStefano Zampini PetscScalar *start_vals; 5314984c4197SStefano Zampini /* working stuff for values insertion */ 53154641a718SStefano Zampini PetscBT is_primal; 531664efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 5317906d46d4SStefano Zampini /* matrix sizes */ 5318906d46d4SStefano Zampini PetscInt global_size,local_size; 5319906d46d4SStefano Zampini /* temporary change of basis */ 5320906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 5321cf5a6209SStefano Zampini /* extra space for debugging */ 5322cf5a6209SStefano Zampini PetscScalar *dbg_work; 5323984c4197SStefano Zampini 5324906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 5325906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 532616f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 5327bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 5328906d46d4SStefano Zampini /* nonzeros for local mat */ 5329bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 53301dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5331bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 53321dd7afcfSStefano Zampini } else { 53331dd7afcfSStefano Zampini const PetscInt *ii; 53341dd7afcfSStefano Zampini PetscInt n; 53351dd7afcfSStefano Zampini PetscBool flg_row; 53361dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 53371dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 53381dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 53391dd7afcfSStefano Zampini } 53409162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 5341a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 53429162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 5343a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 53449162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 5345a717540cSStefano Zampini } else { 53469162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 53479162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 5348a717540cSStefano Zampini } 5349a717540cSStefano Zampini } 5350a717540cSStefano Zampini } 5351906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 5352bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 53531dd7afcfSStefano Zampini /* Set interior change in the matrix */ 53541dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5355bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 5356906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 5357a717540cSStefano Zampini } 53581dd7afcfSStefano Zampini } else { 53591dd7afcfSStefano Zampini const PetscInt *ii,*jj; 53601dd7afcfSStefano Zampini PetscScalar *aa; 53611dd7afcfSStefano Zampini PetscInt n; 53621dd7afcfSStefano Zampini PetscBool flg_row; 53631dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 53641dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 53651dd7afcfSStefano Zampini for (i=0;i<n;i++) { 53661dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 53671dd7afcfSStefano Zampini } 53681dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 53691dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 53701dd7afcfSStefano Zampini } 5371a717540cSStefano Zampini 5372a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5373a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5374a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5375a717540cSStefano Zampini } 5376a717540cSStefano Zampini 5377a717540cSStefano Zampini 5378a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 5379a717540cSStefano Zampini /* 5380a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 5381a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 5382a717540cSStefano Zampini 5383a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 5384a717540cSStefano Zampini 5385a6b551f4SStefano 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) 5386a6b551f4SStefano Zampini 5387a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 5388a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 5389a717540cSStefano Zampini | ... | 5390a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 5391a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 5392a717540cSStefano Zampini 5393a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 5394a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 5395a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 5396a6b551f4SStefano Zampini 5397a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 5398a717540cSStefano Zampini */ 5399a717540cSStefano Zampini if (qr_needed) { 5400984c4197SStefano Zampini /* space to store Q */ 5401854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 54024e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 54034e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 5404984c4197SStefano Zampini /* first we issue queries for optimal work */ 54053f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 54063f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 54073f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5408984c4197SStefano Zampini lqr_work = -1; 54093f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 5410984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 5411984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 5412785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 5413984c4197SStefano Zampini lgqr_work = -1; 54143f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 54153f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 54163f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 54173f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 54183f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 54193f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 5420984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 5421984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 5422785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 5423984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 5424785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 5425a717540cSStefano Zampini /* allocating workspace for check */ 5426a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5427cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 5428a717540cSStefano Zampini } 5429a717540cSStefano Zampini } 5430984c4197SStefano Zampini /* array to store whether a node is primal or not */ 54314641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 5432473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 54330e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 54346c4ed002SBarry 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); 543539e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 543639e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 543739e2fb2aSStefano Zampini } 543839e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 5439984c4197SStefano Zampini 5440a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 54419162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 54429162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 54434641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 5444984c4197SStefano Zampini /* get constraint info */ 54459162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 5446984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 5447984c4197SStefano Zampini 5448984c4197SStefano Zampini if (pcbddc->dbg_flag) { 54499162d606SStefano 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); 5450674ae819SStefano Zampini } 5451984c4197SStefano Zampini 5452fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 5453a717540cSStefano Zampini 5454a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 5455a717540cSStefano Zampini if (pcbddc->dbg_flag) { 54569162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5457a717540cSStefano Zampini } 5458984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 54599162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5460984c4197SStefano Zampini 5461984c4197SStefano Zampini /* compute QR decomposition of constraints */ 54623f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 54633f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 54643f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5465674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 54663f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 5467984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 5468674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5469984c4197SStefano Zampini 5470984c4197SStefano Zampini /* explictly compute R^-T */ 5471984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 5472984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 54733f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 54743f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 54753f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 54763f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 5477984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 54783f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 5479984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 5480984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5481984c4197SStefano Zampini 5482a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 54833f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 54843f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 54853f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 54863f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5487984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 54883f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 5489984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 5490984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5491984c4197SStefano Zampini 5492984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 5493984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 5494984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 54953f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 54963f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 54973f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 54983f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 54993f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 55003f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5501984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 55029162d606SStefano 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)); 5503984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 55049162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5505984c4197SStefano Zampini 5506984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 55079162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 5508984c4197SStefano Zampini /* insert cols for primal dofs */ 5509984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 5510984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 55119162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5512906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5513984c4197SStefano Zampini } 5514984c4197SStefano Zampini /* insert cols for dual dofs */ 5515984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 55169162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 5517984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 55189162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5519906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5520984c4197SStefano Zampini j++; 5521674ae819SStefano Zampini } 5522674ae819SStefano Zampini } 5523984c4197SStefano Zampini 5524984c4197SStefano Zampini /* check change of basis */ 5525984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5526984c4197SStefano Zampini PetscInt ii,jj; 5527984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 5528c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 5529c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5530c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 5531c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5532c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 5533c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 5534984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5535cf5a6209SStefano 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)); 5536984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5537984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5538984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5539cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 5540cf5a6209SStefano 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; 5541674ae819SStefano Zampini } 5542674ae819SStefano Zampini } 5543984c4197SStefano Zampini if (!valid_qr) { 554422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 5545984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5546984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5547cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 5548cf5a6209SStefano 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])); 5549674ae819SStefano Zampini } 5550cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 5551cf5a6209SStefano 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])); 5552984c4197SStefano Zampini } 5553984c4197SStefano Zampini } 5554984c4197SStefano Zampini } 5555674ae819SStefano Zampini } else { 555622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 5557674ae819SStefano Zampini } 5558674ae819SStefano Zampini } 5559a717540cSStefano Zampini } else { /* simple transformation block */ 5560a717540cSStefano Zampini PetscInt row,col; 5561a6b551f4SStefano Zampini PetscScalar val,norm; 5562a6b551f4SStefano Zampini 5563a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 55649162d606SStefano 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)); 5565a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 55669162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 55679162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5568bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 55699162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 5570906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 55719162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 5572a717540cSStefano Zampini } else { 5573a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 55749162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5575a717540cSStefano Zampini if (row != col) { 55769162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 5577a717540cSStefano Zampini } else { 55789162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 5579a717540cSStefano Zampini } 5580906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 5581a717540cSStefano Zampini } 5582a717540cSStefano Zampini } 5583a717540cSStefano Zampini } 558498a51de6SStefano Zampini if (pcbddc->dbg_flag) { 558522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 5586a717540cSStefano Zampini } 5587674ae819SStefano Zampini } 5588984c4197SStefano Zampini } else { 5589984c4197SStefano Zampini if (pcbddc->dbg_flag) { 55909162d606SStefano 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); 5591674ae819SStefano Zampini } 5592674ae819SStefano Zampini } 5593674ae819SStefano Zampini } 5594a717540cSStefano Zampini 5595a717540cSStefano Zampini /* free workspace */ 5596a717540cSStefano Zampini if (qr_needed) { 5597984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5598cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 5599984c4197SStefano Zampini } 5600984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 5601984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 5602984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 5603984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 5604984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 5605674ae819SStefano Zampini } 5606a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 5607906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5608906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5609906d46d4SStefano Zampini 5610906d46d4SStefano Zampini /* assembling of global change of variable */ 561188c03ad3SStefano Zampini if (!pcbddc->fake_change) { 5612bbb9e6c6SStefano Zampini Mat tmat; 561316f15bc4SStefano Zampini PetscInt bs; 561416f15bc4SStefano Zampini 5615906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 5616906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 5617bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 5618bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 5619bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5620bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 562116f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 562216f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 5623906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 5624bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 5625bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5626bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 5627bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5628bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5629e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5630e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5631bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 5632bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 563388c03ad3SStefano Zampini 5634906d46d4SStefano Zampini /* check */ 5635906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 5636906d46d4SStefano Zampini PetscReal error; 5637906d46d4SStefano Zampini Vec x,x_change; 5638906d46d4SStefano Zampini 5639906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 5640906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 5641906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 5642906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 5643e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5644e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5645bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 5646e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5647e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5648906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 5649906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 5650906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 5651906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5652bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 5653906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 5654906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 5655906d46d4SStefano Zampini } 5656b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 5657b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 5658b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5659bf3a8328SStefano Zampini 56609a962809SStefano 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); 5661b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 5662ac632422SStefano Zampini Mat S_new,tmat; 5663bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 5664bbb9e6c6SStefano Zampini 5665bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 56666816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 5667bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5668bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 5669bf3a8328SStefano Zampini IS is_V; 5670b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 5671b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 5672b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 5673b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 5674b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 5675bf3a8328SStefano Zampini } 5676bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 5677ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 5678b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 5679ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 5680bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5681bf3a8328SStefano Zampini const PetscScalar *array; 5682bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 5683bf3a8328SStefano Zampini PetscInt i,n_V; 5684bf3a8328SStefano Zampini 5685b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 5686b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 5687b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 5688b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 5689b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 5690b087196eSStefano Zampini for (i=0;i<n_V;i++) { 5691b087196eSStefano Zampini PetscScalar val; 5692b087196eSStefano Zampini PetscInt idx; 5693b087196eSStefano Zampini 5694b087196eSStefano Zampini idx = idxs_V[i]; 5695b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 5696b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 5697b087196eSStefano Zampini } 5698b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5699b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5700bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 5701bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 5702bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 5703bf3a8328SStefano Zampini } 5704ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 5705ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 5706ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 5707ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 5708b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 5709ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 5710bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5711b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 5712bf3a8328SStefano Zampini } 5713ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 5714ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 5715ac632422SStefano Zampini } 5716b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 571788c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 5718b96c3477SStefano Zampini } 5719c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 5720b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 5721c9db6a07SStefano Zampini PetscInt i; 5722c9db6a07SStefano Zampini 5723c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5724c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 5725c9db6a07SStefano Zampini } 5726c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 5727c9db6a07SStefano Zampini } 5728b96c3477SStefano Zampini } 572916909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 573016909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 573116909a7fSStefano Zampini } else { 5732906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 573316909a7fSStefano Zampini } 57341dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 573527b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 573672b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 573772b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 573872b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 573972b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 574072b8c272SStefano Zampini } 57411dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 574227b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 5743b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 5744b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 5745906d46d4SStefano Zampini } else { 57461dd7afcfSStefano Zampini Mat benign_global = NULL; 574727b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 57481dd7afcfSStefano Zampini Mat tmat; 57491dd7afcfSStefano Zampini 57501dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 57511dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 57521dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 57531dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 57541dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 57551dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 57561dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 57571dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 57581dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 57591dd7afcfSStefano Zampini if (pcbddc->benign_change) { 57601dd7afcfSStefano Zampini Mat M; 57611dd7afcfSStefano Zampini 57621dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 57631dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 57641dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 57651dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 5766906d46d4SStefano Zampini } else { 57671dd7afcfSStefano Zampini Mat eye; 57681dd7afcfSStefano Zampini PetscScalar *array; 57691dd7afcfSStefano Zampini 57701dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 57711dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 57721dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 57731dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 5774906d46d4SStefano Zampini } 57751dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 57761dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 57771dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 57781dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 57791dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 57801dd7afcfSStefano Zampini } 57811dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 57821dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 57831dd7afcfSStefano Zampini } 57841dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 57851dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 57861dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 578727b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 57881dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 57891dd7afcfSStefano Zampini } 57901dd7afcfSStefano Zampini } 579116909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 579216909a7fSStefano Zampini IS is_global; 579316909a7fSStefano Zampini const PetscInt *gidxs; 579416909a7fSStefano Zampini 579516909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 579616909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 579716909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 579816909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 579916909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 580016909a7fSStefano Zampini } 58011dd7afcfSStefano Zampini } 58021dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 58031dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 5804b9b85e73SStefano Zampini } 5805a717540cSStefano Zampini 580672b8c272SStefano Zampini if (!pcbddc->fake_change) { 58074f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 58084f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 58094f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 58104f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 5811019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 5812019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 5813019a44ceSStefano Zampini pcbddc->local_primal_size++; 5814019a44ceSStefano Zampini } 5815019a44ceSStefano Zampini 5816019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 5817727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 5818727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 58199f47a83aSStefano 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); 5820c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 58210e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 58229f47a83aSStefano 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); 5823727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 5824727cdba6SStefano Zampini } 58250e6343abSStefano Zampini } 5826727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 5827b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 582872b8c272SStefano Zampini } 582972b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 5830727cdba6SStefano Zampini 5831a717540cSStefano Zampini /* flush dbg viewer */ 5832b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 5833b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5834b8ffe317SStefano Zampini } 5835a717540cSStefano Zampini 5836e310c8b4SStefano Zampini /* free workspace */ 5837a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 58384641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 583908122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 58409162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 58419162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 584208122e43SStefano Zampini } else { 58439162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 58449162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 58459162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 584608122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 584708122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 58489162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 58499162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 585008122e43SStefano Zampini } 5851674ae819SStefano Zampini PetscFunctionReturn(0); 5852674ae819SStefano Zampini } 5853674ae819SStefano Zampini 5854674ae819SStefano Zampini #undef __FUNCT__ 5855674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 5856674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 5857674ae819SStefano Zampini { 585871582508SStefano Zampini ISLocalToGlobalMapping map; 5859674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5860674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 586114f95afaSStefano Zampini PetscInt ierr,i,N; 5862674ae819SStefano Zampini 5863674ae819SStefano Zampini PetscFunctionBegin; 58648af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 58658e61c736SStefano Zampini /* Reset previously computed graph */ 58668e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 5867674ae819SStefano Zampini /* Init local Graph struct */ 58687fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 586971582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 5870be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 5871674ae819SStefano Zampini 5872575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 58739a962809SStefano 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); 58749577ea80SStefano Zampini 5875674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 5876d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 58774d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 58784d379d7bSStefano Zampini PetscInt nvtxs; 5879e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 5880674ae819SStefano Zampini 58812fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 58822fffb893SStefano Zampini if (flg_row) { 58834d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 5884b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 58852fffb893SStefano Zampini } 58862fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 5887674ae819SStefano Zampini } 58889b28b941SStefano Zampini if (pcbddc->dbg_flag) { 58899b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5890674ae819SStefano Zampini } 5891674ae819SStefano Zampini 5892674ae819SStefano Zampini /* Setup of Graph */ 58934b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 589414f95afaSStefano 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); 5895674ae819SStefano Zampini 58964f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 58974f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 58984f1b2e48SStefano Zampini PetscInt *local_subs; 58994f1b2e48SStefano Zampini 59004f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 59014f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 59024f1b2e48SStefano Zampini const PetscInt *idxs; 59034f1b2e48SStefano Zampini PetscInt nl,j; 59044f1b2e48SStefano Zampini 59054f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 59064f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 590771582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 59084f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 59094f1b2e48SStefano Zampini } 59104f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 59114f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 59124f1b2e48SStefano Zampini } 59138af8fcf9SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 59148af8fcf9SStefano Zampini } 59154f1b2e48SStefano Zampini 5916cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 5917674ae819SStefano Zampini /* Graph's connected components analysis */ 5918674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 591971582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 59208af8fcf9SStefano Zampini } 5921674ae819SStefano Zampini PetscFunctionReturn(0); 5922674ae819SStefano Zampini } 5923674ae819SStefano Zampini 59249a7d3425SStefano Zampini #undef __FUNCT__ 59259a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 59269a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 59279a7d3425SStefano Zampini { 59289a7d3425SStefano Zampini PetscInt i,j; 59299a7d3425SStefano Zampini PetscScalar *alphas; 59309a7d3425SStefano Zampini PetscErrorCode ierr; 59319a7d3425SStefano Zampini 59329a7d3425SStefano Zampini PetscFunctionBegin; 5933785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 59349a7d3425SStefano Zampini for (i=0;i<n;i++) { 59359a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 5936669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 5937669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 5938669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 59399a7d3425SStefano Zampini } 59409a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 59419a7d3425SStefano Zampini PetscFunctionReturn(0); 59429a7d3425SStefano Zampini } 59439a7d3425SStefano Zampini 5944e7931f94SStefano Zampini #undef __FUNCT__ 594570cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 594657de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 5947e7931f94SStefano Zampini { 594857de7509SStefano Zampini Mat A; 5949e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 5950e7931f94SStefano Zampini PetscMPIInt size,rank,color; 595152e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 595252e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 595327b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 595457de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 595527b6a85dSStefano Zampini PetscInt xadj_count, *count; 595627b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 595727b6a85dSStefano Zampini PetscSubcomm psubcomm; 595827b6a85dSStefano Zampini MPI_Comm subcomm; 595952e5ac9dSStefano Zampini PetscErrorCode ierr; 5960a57a6d2fSStefano Zampini 5961e7931f94SStefano Zampini PetscFunctionBegin; 596257de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 596357de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 596457de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 596557de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 596657de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 596757de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 596857de7509SStefano Zampini 596957de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 597057de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 597157de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 597257de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 597357de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 597457de7509SStefano Zampini im_active = !!(n); 597557de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 597657de7509SStefano Zampini void_procs = size - active_procs; 597757de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 597857de7509SStefano Zampini if (void_procs) { 597957de7509SStefano Zampini PetscInt ncand; 598057de7509SStefano Zampini 598157de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 598257de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 598357de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 598457de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 598557de7509SStefano Zampini if (!procs_candidates[i]) { 598657de7509SStefano Zampini procs_candidates[ncand++] = i; 598757de7509SStefano Zampini } 598857de7509SStefano Zampini } 598957de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 599057de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 599157de7509SStefano Zampini } 599257de7509SStefano Zampini 599314f0bfb9SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix 599414f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 599514f0bfb9SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1) { 599614f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 599714f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 599814f0bfb9SStefano Zampini else dest = rank; 599957de7509SStefano Zampini if (im_active) { 600057de7509SStefano Zampini issize = 1; 600157de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 600214f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 600357de7509SStefano Zampini } else { 600414f0bfb9SStefano Zampini isidx = dest; 600557de7509SStefano Zampini } 600657de7509SStefano Zampini } else { 600757de7509SStefano Zampini issize = 0; 600857de7509SStefano Zampini isidx = -1; 600957de7509SStefano Zampini } 601057de7509SStefano Zampini *n_subdomains = active_procs; 601157de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 6012daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 601357de7509SStefano Zampini PetscFunctionReturn(0); 601457de7509SStefano Zampini } 6015c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 6016c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 601727b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 6018e7931f94SStefano Zampini 6019e7931f94SStefano Zampini /* Get info on mapping */ 60203bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 60213bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6022e7931f94SStefano Zampini 6023e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 6024785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 6025e7931f94SStefano Zampini xadj[0] = 0; 6026e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 6027785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 6028785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 602927b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 603027b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 603127b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 603227b6a85dSStefano Zampini count[shared[i][j]] += 1; 6033e7931f94SStefano Zampini 603427b6a85dSStefano Zampini xadj_count = 0; 60352b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 603627b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 603727b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 6038d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 6039d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 6040d023bfaeSStefano Zampini xadj_count++; 604127b6a85dSStefano Zampini break; 604227b6a85dSStefano Zampini } 6043e7931f94SStefano Zampini } 6044e7931f94SStefano Zampini } 6045d023bfaeSStefano Zampini xadj[1] = xadj_count; 604627b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 60473bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6048e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 6049e7931f94SStefano Zampini 60503837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 6051e7931f94SStefano Zampini 605227b6a85dSStefano Zampini /* Restrict work on active processes only */ 605327b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 605427b6a85dSStefano Zampini if (void_procs) { 605527b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 605627b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 605727b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 605827b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 605927b6a85dSStefano Zampini } else { 606027b6a85dSStefano Zampini psubcomm = NULL; 606127b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 606227b6a85dSStefano Zampini } 606327b6a85dSStefano Zampini 606427b6a85dSStefano Zampini v_wgt = NULL; 606527b6a85dSStefano Zampini if (!color) { 6066e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 6067e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 6068e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6069c8587f34SStefano Zampini } else { 607052e5ac9dSStefano Zampini Mat subdomain_adj; 607152e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 607252e5ac9dSStefano Zampini MatPartitioning partitioner; 607327b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 607452e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 607557de7509SStefano Zampini PetscMPIInt size; 6076b0c7d250SStefano Zampini PetscBool aggregate; 6077b0c7d250SStefano Zampini 607827b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 607927b6a85dSStefano Zampini if (void_procs) { 608027b6a85dSStefano Zampini PetscInt prank = rank; 6081785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 608227b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 6083e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 6084e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 6085c8587f34SStefano Zampini } 6086e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 608727b6a85dSStefano Zampini } else { 608827b6a85dSStefano Zampini oldranks = NULL; 608927b6a85dSStefano Zampini } 6090b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 609127b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 6092b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 6093b0c7d250SStefano Zampini PetscMPIInt nrank; 6094b0c7d250SStefano Zampini PetscScalar *vals; 6095b0c7d250SStefano Zampini 609627b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 6097b0c7d250SStefano Zampini lrows = 0; 6098b0c7d250SStefano Zampini if (nrank<redprocs) { 6099b0c7d250SStefano Zampini lrows = size/redprocs; 6100b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 6101b0c7d250SStefano Zampini } 610227b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 6103b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 6104b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6105b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6106b0c7d250SStefano Zampini row = nrank; 6107b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 6108b0c7d250SStefano Zampini cols = adjncy; 6109b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 6110b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 6111b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 6112b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6113b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 611452e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 611552e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 611652e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6117b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 611827b6a85dSStefano Zampini if (use_vwgt) { 611927b6a85dSStefano Zampini Vec v; 612027b6a85dSStefano Zampini const PetscScalar *array; 612127b6a85dSStefano Zampini PetscInt nl; 612227b6a85dSStefano Zampini 612327b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 612427b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 612527b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 612627b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 612727b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 612827b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 612927b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 613022db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 613127b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 613227b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 613327b6a85dSStefano Zampini } 6134b0c7d250SStefano Zampini } else { 613527b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 613627b6a85dSStefano Zampini if (use_vwgt) { 613727b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 613827b6a85dSStefano Zampini v_wgt[0] = local_size; 613927b6a85dSStefano Zampini } 6140b0c7d250SStefano Zampini } 614122b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 6142e7931f94SStefano Zampini 6143e7931f94SStefano Zampini /* Partition */ 614427b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 6145e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 614627b6a85dSStefano Zampini if (v_wgt) { 6147e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 6148c8587f34SStefano Zampini } 614957de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 615057de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 6151e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 6152e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 615322b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 6154e7931f94SStefano Zampini 615552e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 61566583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 615752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 615852e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 615957de7509SStefano Zampini if (!aggregate) { 616057de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 616127b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 616227b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 616327b6a85dSStefano Zampini #endif 616457de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 616527b6a85dSStefano Zampini } else if (oldranks) { 6166b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 616727b6a85dSStefano Zampini } else { 616827b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 616957de7509SStefano Zampini } 617028143c3dSStefano Zampini } else { 6171b0c7d250SStefano Zampini PetscInt idxs[1]; 6172b0c7d250SStefano Zampini PetscMPIInt tag; 6173b0c7d250SStefano Zampini MPI_Request *reqs; 6174b0c7d250SStefano Zampini 6175b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 6176b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 6177b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 617827b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 617928143c3dSStefano Zampini } 618027b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 6181b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6182b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 618357de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 618427b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 618527b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 618627b6a85dSStefano Zampini #endif 618757de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 618827b6a85dSStefano Zampini } else if (oldranks) { 6189b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 619027b6a85dSStefano Zampini } else { 619127b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 6192e7931f94SStefano Zampini } 619357de7509SStefano Zampini } 619452e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6195e7931f94SStefano Zampini /* clean up */ 6196e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 619752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 6198e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 6199e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 6200e7931f94SStefano Zampini } 620127b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 620257de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 6203e7931f94SStefano Zampini 6204e7931f94SStefano Zampini /* assemble parallel IS for sends */ 6205e7931f94SStefano Zampini i = 1; 620627b6a85dSStefano Zampini if (!color) i=0; 620757de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 6208e7931f94SStefano Zampini PetscFunctionReturn(0); 6209e7931f94SStefano Zampini } 6210e7931f94SStefano Zampini 6211e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 6212e7931f94SStefano Zampini 6213e7931f94SStefano Zampini #undef __FUNCT__ 6214e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 62151ae86dd6SStefano Zampini PetscErrorCode MatISSubassemble(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[]) 6216e7931f94SStefano Zampini { 621770cf5478SStefano Zampini Mat local_mat; 6218e7931f94SStefano Zampini IS is_sends_internal; 62199d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 62201ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 62219d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 6222e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 6223e7931f94SStefano Zampini PetscInt* l2gmap_indices; 6224e7931f94SStefano Zampini const PetscInt* is_indices; 6225e7931f94SStefano Zampini MatType new_local_type; 6226e7931f94SStefano Zampini /* buffers */ 6227e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 622828143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 62299d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 6230e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 62311ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 6232e7931f94SStefano Zampini /* MPI */ 623328143c3dSStefano Zampini MPI_Comm comm,comm_n; 623428143c3dSStefano Zampini PetscSubcomm subcomm; 6235e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 623628143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 623728143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 62381ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 62391ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 62401ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 6241e7931f94SStefano Zampini PetscErrorCode ierr; 6242e7931f94SStefano Zampini 6243e7931f94SStefano Zampini PetscFunctionBegin; 624457de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6245e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 624628143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 624757de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 624857de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 624957de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 625057de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 625157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 62521ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 62531ae86dd6SStefano Zampini if (nvecs) { 62541ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 62551ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 62561ae86dd6SStefano Zampini } 625757de7509SStefano Zampini /* further checks */ 6258e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6259e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 6260e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 6261e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 6262e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 626357de7509SStefano Zampini if (reuse && *mat_n) { 626470cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 626557de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 626670cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 626728143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 626870cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 626970cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 627070cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 627170cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 627270cf5478SStefano Zampini } 6273e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 6274e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 627557de7509SStefano Zampini 6276e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 6277e7931f94SStefano Zampini if (!is_sends) { 627828143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 627957de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 6280c8587f34SStefano Zampini } else { 6281e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 6282e7931f94SStefano Zampini is_sends_internal = is_sends; 6283c8587f34SStefano Zampini } 6284e7931f94SStefano Zampini 6285e7931f94SStefano Zampini /* get comm */ 6286a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 6287e7931f94SStefano Zampini 6288e7931f94SStefano Zampini /* compute number of sends */ 6289e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 6290e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 6291e7931f94SStefano Zampini 6292e7931f94SStefano Zampini /* compute number of receives */ 6293e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 6294785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 6295e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 6296e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6297e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 6298e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 6299e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 6300e7931f94SStefano Zampini 630128143c3dSStefano Zampini /* restrict comm if requested */ 630228143c3dSStefano Zampini subcomm = 0; 630328143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 630428143c3dSStefano Zampini if (restrict_comm) { 6305779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 6306779c1cceSStefano Zampini 630728143c3dSStefano Zampini color = 0; 630853a05cb3SStefano Zampini if (restrict_full) { 630953a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 631053a05cb3SStefano Zampini } else { 631153a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 631253a05cb3SStefano Zampini } 6313b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 631428143c3dSStefano Zampini subcommsize = commsize - subcommsize; 631528143c3dSStefano Zampini /* check if reuse has been requested */ 631657de7509SStefano Zampini if (reuse) { 631728143c3dSStefano Zampini if (*mat_n) { 631828143c3dSStefano Zampini PetscMPIInt subcommsize2; 631928143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 632028143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 632128143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 632228143c3dSStefano Zampini } else { 632328143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 632428143c3dSStefano Zampini } 632528143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 6326779c1cceSStefano Zampini PetscMPIInt rank; 6327779c1cceSStefano Zampini 6328779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 632928143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 633028143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 633128143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 6332306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 633328143c3dSStefano Zampini } 633428143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 633528143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 633628143c3dSStefano Zampini } else { 633728143c3dSStefano Zampini comm_n = comm; 633828143c3dSStefano Zampini } 633928143c3dSStefano Zampini 6340e7931f94SStefano Zampini /* prepare send/receive buffers */ 6341785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 6342e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 6343785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 6344e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 634528143c3dSStefano Zampini if (nis) { 6346854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 634728143c3dSStefano Zampini } 6348e7931f94SStefano Zampini 634928143c3dSStefano Zampini /* Get data from local matrices */ 63506c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 6351e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 6352e7931f94SStefano Zampini /* 6353e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 6354e7931f94SStefano Zampini send_buffer_idxs should contain: 6355e7931f94SStefano Zampini - MatType_PRIVATE type 6356e7931f94SStefano Zampini - PetscInt size_of_l2gmap 6357e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 6358e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 6359e7931f94SStefano Zampini */ 63606c4ed002SBarry Smith else { 6361e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 63623bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 6363854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 6364e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 6365e7931f94SStefano Zampini send_buffer_idxs[1] = i; 63663bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6367e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 63683bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6369e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 6370e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6371e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 6372e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 6373c8587f34SStefano Zampini } 6374c8587f34SStefano Zampini } 6375e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 637628143c3dSStefano Zampini /* additional is (if any) */ 637728143c3dSStefano Zampini if (nis) { 637828143c3dSStefano Zampini PetscMPIInt psum; 637928143c3dSStefano Zampini PetscInt j; 638028143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 638128143c3dSStefano Zampini PetscInt plen; 638228143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 638328143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 638428143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 638528143c3dSStefano Zampini } 6386854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 638728143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 638828143c3dSStefano Zampini PetscInt plen; 638928143c3dSStefano Zampini const PetscInt *is_array_idxs; 639028143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 639128143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 639228143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 639328143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 639428143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 639528143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 639628143c3dSStefano Zampini } 639728143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 639828143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 639928143c3dSStefano Zampini } 640028143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 640128143c3dSStefano Zampini } 640228143c3dSStefano Zampini 6403e7931f94SStefano Zampini buf_size_idxs = 0; 6404e7931f94SStefano Zampini buf_size_vals = 0; 640528143c3dSStefano Zampini buf_size_idxs_is = 0; 64061ae86dd6SStefano Zampini buf_size_vecs = 0; 6407e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6408e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 6409e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 641028143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 64111ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 6412e7931f94SStefano Zampini } 6413785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 6414785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 641595ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 64161ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 6417e7931f94SStefano Zampini 6418e7931f94SStefano Zampini /* get new tags for clean communications */ 6419e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 6420e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 642128143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 64221ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 6423e7931f94SStefano Zampini 6424e7931f94SStefano Zampini /* allocate for requests */ 6425785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 6426785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 642795ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 64281ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 6429785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 6430785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 643195ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 64321ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 6433e7931f94SStefano Zampini 6434e7931f94SStefano Zampini /* communications */ 6435e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6436e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 643728143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 64381ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 6439e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6440e7931f94SStefano Zampini source_dest = onodes[i]; 6441e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 6442e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 6443e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6444e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 644528143c3dSStefano Zampini if (nis) { 644657de7509SStefano Zampini source_dest = onodes_is[i]; 644728143c3dSStefano 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); 644828143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 644928143c3dSStefano Zampini } 64501ae86dd6SStefano Zampini if (nvecs) { 64511ae86dd6SStefano Zampini source_dest = onodes[i]; 64521ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 64531ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 64541ae86dd6SStefano Zampini } 6455e7931f94SStefano Zampini } 6456e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6457e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 6458e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 6459e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 646028143c3dSStefano Zampini if (nis) { 646128143c3dSStefano 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); 646228143c3dSStefano Zampini } 64631ae86dd6SStefano Zampini if (nvecs) { 64641ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 64651ae86dd6SStefano 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); 64661ae86dd6SStefano Zampini } 6467e7931f94SStefano Zampini } 6468e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6469e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 6470e7931f94SStefano Zampini 6471e7931f94SStefano Zampini /* assemble new l2g map */ 6472e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6473e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 64749d30be91SStefano Zampini new_local_rows = 0; 6475e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 64769d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6477e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6478e7931f94SStefano Zampini } 64799d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 6480e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 64819d30be91SStefano Zampini new_local_rows = 0; 6482e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 64839d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 64849d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6485e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6486e7931f94SStefano Zampini } 64879d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 64889d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 6489e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 6490e7931f94SStefano Zampini 6491e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 6492e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 6493e7931f94SStefano 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) */ 6494e7931f94SStefano Zampini if (n_recvs) { 649528143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 6496e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6497e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6498e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 6499e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 6500e7931f94SStefano Zampini break; 6501e7931f94SStefano Zampini } 6502e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6503e7931f94SStefano Zampini } 6504e7931f94SStefano Zampini switch (new_local_type_private) { 650528143c3dSStefano Zampini case MATDENSE_PRIVATE: 650628143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 6507e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6508e7931f94SStefano Zampini bs = 1; 650928143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 651028143c3dSStefano Zampini new_local_type = MATSEQDENSE; 651128143c3dSStefano Zampini bs = 1; 651228143c3dSStefano Zampini } 6513e7931f94SStefano Zampini break; 6514e7931f94SStefano Zampini case MATAIJ_PRIVATE: 6515e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6516e7931f94SStefano Zampini bs = 1; 6517e7931f94SStefano Zampini break; 6518e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 6519e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 6520e7931f94SStefano Zampini break; 6521e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 6522e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 6523e7931f94SStefano Zampini break; 6524e7931f94SStefano Zampini default: 65259d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 6526e7931f94SStefano Zampini break; 6527e7931f94SStefano Zampini } 652828143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 652928143c3dSStefano Zampini new_local_type = MATSEQDENSE; 653028143c3dSStefano Zampini bs = 1; 6531e7931f94SStefano Zampini } 6532e7931f94SStefano Zampini 653370cf5478SStefano Zampini /* create MATIS object if needed */ 653457de7509SStefano Zampini if (!reuse) { 6535e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 6536e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 653770cf5478SStefano Zampini } else { 653870cf5478SStefano Zampini /* it also destroys the local matrices */ 653957de7509SStefano Zampini if (*mat_n) { 654070cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 654157de7509SStefano Zampini } else { /* this is a fake object */ 654257de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 654357de7509SStefano Zampini } 654470cf5478SStefano Zampini } 654570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 6546e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 65479d30be91SStefano Zampini 65489d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 65499d30be91SStefano Zampini 65509d30be91SStefano Zampini /* Global to local map of received indices */ 65519d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 65529d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 65539d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 65549d30be91SStefano Zampini 65559d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 65569d30be91SStefano Zampini buf_size_idxs = 0; 65579d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 65589d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 65599d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 65609d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 65619d30be91SStefano Zampini } 65629d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 65639d30be91SStefano Zampini 65649d30be91SStefano Zampini /* set preallocation */ 65659d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 65669d30be91SStefano Zampini if (!newisdense) { 65679d30be91SStefano Zampini PetscInt *new_local_nnz=0; 65689d30be91SStefano Zampini 65699d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 65709d30be91SStefano Zampini if (n_recvs) { 65719d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 65729d30be91SStefano Zampini } 65739d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 65749d30be91SStefano Zampini PetscInt j; 65759d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 65769d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 65779d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 65789d30be91SStefano Zampini } 65799d30be91SStefano Zampini } else { 65809d30be91SStefano Zampini /* TODO */ 65819d30be91SStefano Zampini } 65829d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 65839d30be91SStefano Zampini } 65849d30be91SStefano Zampini if (new_local_nnz) { 65859d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 65869d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 65879d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 65889d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 65899d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 65909d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 65919d30be91SStefano Zampini } else { 65929d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 65939d30be91SStefano Zampini } 65949d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 65959d30be91SStefano Zampini } else { 65969d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 65979d30be91SStefano Zampini } 6598e7931f94SStefano Zampini 6599e7931f94SStefano Zampini /* set values */ 6600e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 66019d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 6602e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6603e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 6604e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 66059d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 6606e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6607e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6608e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 660928143c3dSStefano Zampini } else { 661028143c3dSStefano Zampini /* TODO */ 6611e7931f94SStefano Zampini } 6612e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6613e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 6614e7931f94SStefano Zampini } 6615e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6616e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 661770cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 661870cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 66199d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 6620e7931f94SStefano Zampini 6621dfd14d43SStefano Zampini #if 0 662228143c3dSStefano Zampini if (!restrict_comm) { /* check */ 6623e7931f94SStefano Zampini Vec lvec,rvec; 6624e7931f94SStefano Zampini PetscReal infty_error; 6625e7931f94SStefano Zampini 66262a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 6627e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 6628e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 6629e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 663070cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 6631e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 6632e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 6633e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 6634e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 6635e7931f94SStefano Zampini } 663628143c3dSStefano Zampini #endif 6637e7931f94SStefano Zampini 663828143c3dSStefano Zampini /* assemble new additional is (if any) */ 663928143c3dSStefano Zampini if (nis) { 664028143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 664128143c3dSStefano Zampini 664228143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6643854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 664428143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 664528143c3dSStefano Zampini psum = 0; 664628143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 664728143c3dSStefano Zampini for (j=0;j<nis;j++) { 664828143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 664928143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 665028143c3dSStefano Zampini psum += plen; 665128143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 665228143c3dSStefano Zampini } 665328143c3dSStefano Zampini } 6654854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 6655854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 665628143c3dSStefano Zampini for (i=1;i<nis;i++) { 665728143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 665828143c3dSStefano Zampini } 665928143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 666028143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 666128143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 666228143c3dSStefano Zampini for (j=0;j<nis;j++) { 666328143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 666428143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 666528143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 666628143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 666728143c3dSStefano Zampini } 666828143c3dSStefano Zampini } 666928143c3dSStefano Zampini for (i=0;i<nis;i++) { 667028143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 667128143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 667228143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 667328143c3dSStefano Zampini } 667428143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 667528143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 667628143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 667728143c3dSStefano Zampini } 6678e7931f94SStefano Zampini /* free workspace */ 667928143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 6680e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6681e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 6682e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6683e7931f94SStefano Zampini if (isdense) { 6684e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6685e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 6686e7931f94SStefano Zampini } else { 6687e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 6688e7931f94SStefano Zampini } 668928143c3dSStefano Zampini if (nis) { 669028143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 669128143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 669228143c3dSStefano Zampini } 66931ae86dd6SStefano Zampini 66941ae86dd6SStefano Zampini if (nvecs) { 66951ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 66961ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 66971ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 66981ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 66991ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 67001ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 67011ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 67021ae86dd6SStefano Zampini /* set values */ 67031ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 67041ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 67051ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 67061ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 67071ae86dd6SStefano Zampini PetscInt j; 67081ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 67091ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 67101ae86dd6SStefano Zampini } 67111ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 67121ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 67131ae86dd6SStefano Zampini } 67141ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 67151ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 67161ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 67171ae86dd6SStefano Zampini } 67181ae86dd6SStefano Zampini 67191ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 67201ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 6721e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 6722e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 67231ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 672428143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 6725e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 6726e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 67271ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 672828143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 6729e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 6730e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 6731e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 6732e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 6733e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 673428143c3dSStefano Zampini if (nis) { 673528143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 673628143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 673728143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 673828143c3dSStefano Zampini } 673928143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 674028143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 674128143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 674228143c3dSStefano Zampini for (i=0;i<nis;i++) { 674328143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 674428143c3dSStefano Zampini } 67451ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 67461ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 67471ae86dd6SStefano Zampini } 674853a05cb3SStefano Zampini *mat_n = NULL; 674928143c3dSStefano Zampini } 6750e7931f94SStefano Zampini PetscFunctionReturn(0); 6751e7931f94SStefano Zampini } 6752a57a6d2fSStefano Zampini 675312edc857SStefano Zampini /* temporary hack into ksp private data structure */ 6754af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 675512edc857SStefano Zampini 6756c8587f34SStefano Zampini #undef __FUNCT__ 6757c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 6758c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 6759c8587f34SStefano Zampini { 6760c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6761c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 676220a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 67631ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 67649881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 676520a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 67666e683305SStefano Zampini IS coarse_is,*isarray; 67676e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 676830368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 6769f9eb5b7dSStefano Zampini PC pc_temp; 6770c8587f34SStefano Zampini PCType coarse_pc_type; 6771c8587f34SStefano Zampini KSPType coarse_ksp_type; 6772f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 67734f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 67746e683305SStefano Zampini Mat t_coarse_mat_is; 677557de7509SStefano Zampini PetscInt ncoarse; 677668457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 677722bc73bbSStefano Zampini PetscScalar *array; 677857de7509SStefano Zampini MatReuse coarse_mat_reuse; 677957de7509SStefano Zampini PetscBool restr, full_restr, have_void; 67809881197aSStefano Zampini PetscErrorCode ierr; 6781fdc09c96SStefano Zampini 6782c8587f34SStefano Zampini PetscFunctionBegin; 6783c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 678468457ee5SStefano 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 */ 6785fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 67865a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 6787fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 6788f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 6789f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 6790f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 6791fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 679251bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 679351bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 6794dc4bcba2SStefano Zampini PC pc; 6795dc4bcba2SStefano Zampini PetscBool isbddc; 6796dc4bcba2SStefano Zampini 6797dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 6798dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 6799dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 6800dc4bcba2SStefano Zampini if (isbddc) { 680163c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 680263c961adSStefano Zampini } else { 6803727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 680463c961adSStefano Zampini } 6805fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 6806fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 6807fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 6808f4ddd8eeSStefano Zampini } 6809fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 6810fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 6811f4ddd8eeSStefano Zampini } 681270cf5478SStefano Zampini /* reset any subassembling information */ 681357de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 681470cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 681557de7509SStefano Zampini } 68166e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 6817fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 6818f4ddd8eeSStefano Zampini } 681957de7509SStefano Zampini /* assemble coarse matrix */ 682057de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 682157de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 682257de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 682357de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 682418a45a71SStefano Zampini } else { 682557de7509SStefano Zampini coarse_mat = NULL; 682657de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 68276e683305SStefano Zampini } 6828e7931f94SStefano Zampini 6829abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 6830abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 6831abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 6832abbbba34SStefano Zampini 6833abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 683422bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 683522bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 683622bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 683722bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 6838e176bc59SStefano 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); 68396e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 68406e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 68416e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6842abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 6843abbbba34SStefano Zampini 684457de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 684557de7509SStefano Zampini im_active = !!(pcis->n); 684657de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 684757de7509SStefano Zampini 684814f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 684957de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 685057de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 685157de7509SStefano Zampini coarse_mat_is = NULL; 685257de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 685357de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 68541ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 685557de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 685657de7509SStefano Zampini if (multilevel_requested) { 685757de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 685857de7509SStefano Zampini restr = PETSC_FALSE; 685957de7509SStefano Zampini full_restr = PETSC_FALSE; 686057de7509SStefano Zampini } else { 686157de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 686257de7509SStefano Zampini restr = PETSC_TRUE; 686357de7509SStefano Zampini full_restr = PETSC_TRUE; 686457de7509SStefano Zampini } 68654b2aedd3SStefano Zampini if (!pcbddc->coarse_size) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 686657de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 686757de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 6868a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 686957de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 6870a198735bSStefano Zampini } else { 6871a198735bSStefano Zampini PetscMPIInt size,rank; 6872a198735bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 6873a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 6874a198735bSStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 6875a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 6876a198735bSStefano Zampini } 687757de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 687857de7509SStefano Zampini PetscInt psum; 687957de7509SStefano Zampini PetscMPIInt size; 688057de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 688157de7509SStefano Zampini else psum = 0; 688257de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 688357de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 688457de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 688557de7509SStefano Zampini } 688657de7509SStefano Zampini /* determine if we can go multilevel */ 688757de7509SStefano Zampini if (multilevel_requested) { 688857de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 688957de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 689057de7509SStefano Zampini } 689157de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 689257de7509SStefano Zampini 6893e4d548c7SStefano Zampini /* dump subassembling pattern */ 6894e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 6895e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 6896e4d548c7SStefano Zampini } 6897e4d548c7SStefano Zampini 68986e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 6899c703fcc7SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal)) { /* protects from unneded computations */ 69006e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 69016e683305SStefano Zampini const PetscInt *idxs; 69026e683305SStefano Zampini ISLocalToGlobalMapping tmap; 69036e683305SStefano Zampini 69046e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 69050be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 69066e683305SStefano Zampini /* allocate space for temporary storage */ 6907854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 6908854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 69096e683305SStefano Zampini /* allocate for IS array */ 69106e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 69116e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 691227b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 691330368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 6914854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 69156e683305SStefano Zampini /* dofs splitting */ 69166e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 69176e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 69186e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 69196e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 69206e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 69216e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 69226e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 692330368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 69246e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 69256e683305SStefano Zampini } 69266e683305SStefano Zampini /* neumann boundaries */ 69276e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 69286e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 69296e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 69306e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 69316e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 69326e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 69336e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 693430368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 69356e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 69366e683305SStefano Zampini } 69376e683305SStefano Zampini /* free memory */ 69386e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 69396e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 69406e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 69416e683305SStefano Zampini } else { 69426e683305SStefano Zampini nis = 0; 69436e683305SStefano Zampini nisdofs = 0; 69446e683305SStefano Zampini nisneu = 0; 694530368db7SStefano Zampini nisvert = 0; 69466e683305SStefano Zampini isarray = NULL; 69476e683305SStefano Zampini } 69486e683305SStefano Zampini /* destroy no longer needed map */ 69496e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 69506e683305SStefano Zampini 695157de7509SStefano Zampini /* subassemble */ 695257de7509SStefano Zampini if (multilevel_allowed) { 69531ae86dd6SStefano Zampini Vec vp[1]; 69541ae86dd6SStefano Zampini PetscInt nvecs = 0; 695557de7509SStefano Zampini PetscBool reuse,reuser; 69561ae86dd6SStefano Zampini 695757de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 695857de7509SStefano Zampini else reuse = PETSC_FALSE; 695957de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 69601ae86dd6SStefano Zampini vp[0] = NULL; 69611ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 69621ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 69631ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 69641ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 69651ae86dd6SStefano Zampini nvecs = 1; 69661ae86dd6SStefano Zampini 69671ae86dd6SStefano Zampini if (pcbddc->divudotp) { 6968a198735bSStefano Zampini Mat B,loc_divudotp; 69691ae86dd6SStefano Zampini Vec v,p; 69701ae86dd6SStefano Zampini IS dummy; 69711ae86dd6SStefano Zampini PetscInt np; 69721ae86dd6SStefano Zampini 6973a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 6974a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 69751ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 6976a198735bSStefano Zampini ierr = MatGetSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 69771ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 69781ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 69791ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 69801ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 69811ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 69821ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 69831ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 69841ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 69851ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 69861ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 69871ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 69881ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 698974e2c79eSStefano Zampini } 69901ae86dd6SStefano Zampini } 69911ae86dd6SStefano Zampini if (reuser) { 69921ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 699374e2c79eSStefano Zampini } else { 69941ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray,nvecs,vp);CHKERRQ(ierr); 69951ae86dd6SStefano Zampini } 69961ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 69971ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 69981ae86dd6SStefano Zampini PetscInt nl; 69991ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 70001ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 70011ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 70021ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 70031ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 70041ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 70051ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 70061ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 7007a198735bSStefano Zampini } else { 7008a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 70091ae86dd6SStefano Zampini } 70101ae86dd6SStefano Zampini } else { 70111ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray,0,NULL);CHKERRQ(ierr); 70126e683305SStefano Zampini } 701357de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 701457de7509SStefano Zampini PetscMPIInt size; 7015f913dca9SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size);CHKERRQ(ierr); 701657de7509SStefano Zampini if (!multilevel_allowed) { 701757de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 70186e683305SStefano Zampini } else { 701957de7509SStefano Zampini Mat A; 7020779c1cceSStefano Zampini 702157de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 702257de7509SStefano Zampini if (coarse_mat_is) { 702357de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 702457de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 702557de7509SStefano Zampini coarse_mat = coarse_mat_is; 702657de7509SStefano Zampini } 702757de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 702857de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 702957de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 7030779c1cceSStefano Zampini } 7031779c1cceSStefano Zampini } 703257de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 703357de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 70346e683305SStefano Zampini 70356e683305SStefano Zampini /* create local to global scatters for coarse problem */ 703668457ee5SStefano Zampini if (compute_vecs) { 70376e683305SStefano Zampini PetscInt lrows; 70386e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 703957de7509SStefano Zampini if (coarse_mat) { 704057de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 70416e683305SStefano Zampini } else { 70426e683305SStefano Zampini lrows = 0; 70436e683305SStefano Zampini } 70446e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 70456e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 70466e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 70476e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 70486e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 70496e683305SStefano Zampini } 70506e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 7051c8587f34SStefano Zampini 7052f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 7053f9eb5b7dSStefano Zampini if (multilevel_allowed) { 7054f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 7055f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 7056f9eb5b7dSStefano Zampini } else { 7057f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 7058f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 7059c8587f34SStefano Zampini } 7060c8587f34SStefano Zampini 70616e683305SStefano Zampini /* print some info if requested */ 70626e683305SStefano Zampini if (pcbddc->dbg_flag) { 70636e683305SStefano Zampini if (!multilevel_allowed) { 70646e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 70656e683305SStefano Zampini if (multilevel_requested) { 70666e683305SStefano 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); 70676e683305SStefano Zampini } else if (pcbddc->max_levels) { 70686e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 70696e683305SStefano Zampini } 70706e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 70716e683305SStefano Zampini } 70726e683305SStefano Zampini } 70736e683305SStefano Zampini 7074f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 707557de7509SStefano Zampini if (coarse_mat) { 70766a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 70776e683305SStefano Zampini if (pcbddc->dbg_flag) { 707857de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 70796e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 70806e683305SStefano Zampini } 7081f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 7082312be037SStefano Zampini char prefix[256],str_level[16]; 7083e604994aSStefano Zampini size_t len; 708457de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 7085422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 7086c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 7087f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 708857de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7089c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 70906e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 7091c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 7092c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7093e604994aSStefano Zampini /* prefix */ 7094e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 7095e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 7096e604994aSStefano Zampini if (!pcbddc->current_level) { 7097e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 7098e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 7099c8587f34SStefano Zampini } else { 7100e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 7101312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 7102312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 710334d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 7104312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 7105e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 7106e604994aSStefano Zampini } 7107e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 71083e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 71093e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 71103e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 71113e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 7112f9eb5b7dSStefano Zampini /* allow user customization */ 7113f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 71143e3c6dadSStefano Zampini } 71153e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 711651bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 71173e3c6dadSStefano Zampini if (nisdofs) { 71183e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 71193e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 71203e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 71213e3c6dadSStefano Zampini } 71223e3c6dadSStefano Zampini } 71233e3c6dadSStefano Zampini if (nisneu) { 71243e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 71253e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 7126312be037SStefano Zampini } 712730368db7SStefano Zampini if (nisvert) { 712830368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 712930368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 713030368db7SStefano Zampini } 7131f9eb5b7dSStefano Zampini 7132f9eb5b7dSStefano Zampini /* get some info after set from options */ 7133f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 7134f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 71354f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 71366e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 7137f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7138f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 7139f9eb5b7dSStefano Zampini } 714039f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 71414f3a063dSStefano Zampini if (isredundant) { 71424f3a063dSStefano Zampini KSP inner_ksp; 71434f3a063dSStefano Zampini PC inner_pc; 71444f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 71454f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 71464f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 71474f3a063dSStefano Zampini } 7148f9eb5b7dSStefano Zampini 714957de7509SStefano Zampini /* parameters which miss an API */ 715057de7509SStefano Zampini if (isbddc) { 7151720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 7152720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 715357de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 715427b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 715527b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 7156a198735bSStefano Zampini Mat coarsedivudotp_is; 7157a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 7158a198735bSStefano Zampini IS row,col; 7159a198735bSStefano Zampini const PetscInt *gidxs; 7160a198735bSStefano Zampini PetscInt n,st,M,N; 7161a198735bSStefano Zampini 7162a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 7163a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 7164a198735bSStefano Zampini st = st-n; 7165a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 7166a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 7167a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 7168a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7169a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 7170a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7171a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 7172a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 7173a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 7174a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 7175a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 7176a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 7177a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 7178a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 7179a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 7180a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 7181a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7182a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7183a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 7184a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 71858ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 7186a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 7187720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 718859e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 7189720d30f9SStefano Zampini } 7190d4d8cf7bSStefano Zampini } 71919881197aSStefano Zampini 71923301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 71935a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 71943301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 71953301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 71963301b35fSStefano Zampini } 71973301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 71983301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 71993301b35fSStefano Zampini } 72003301b35fSStefano Zampini if (pc->pmat->spd_set) { 72013301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 72023301b35fSStefano Zampini } 720327b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 720427b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 720527b6a85dSStefano Zampini } 72066e683305SStefano Zampini /* set operators */ 72075f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 72086e683305SStefano Zampini if (pcbddc->dbg_flag) { 72096e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 72106e683305SStefano Zampini } 72116e683305SStefano Zampini } 72126e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 7213b1ecc7b1SStefano Zampini #if 0 7214b9b85e73SStefano Zampini { 7215b9b85e73SStefano Zampini PetscViewer viewer; 7216b9b85e73SStefano Zampini char filename[256]; 7217b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 7218b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 72196a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 7220b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 7221f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 7222b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 7223b9b85e73SStefano Zampini } 7224b9b85e73SStefano Zampini #endif 7225f9eb5b7dSStefano Zampini 722698a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 722798a51de6SStefano Zampini Vec crhs,csol; 722804708bb6SStefano Zampini 7229f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 7230f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 7231f347579bSStefano Zampini if (!csol) { 72322a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 7233f9eb5b7dSStefano Zampini } 7234f347579bSStefano Zampini if (!crhs) { 72352a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 7236f347579bSStefano Zampini } 7237b0f5fe93SStefano Zampini } 72381ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 7239b0f5fe93SStefano Zampini 7240b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 7241b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 7242b0f5fe93SStefano Zampini 7243b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 72444f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 72454f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 72464f1b2e48SStefano Zampini } 7247b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 7248b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 7249b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7250b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7251b0f5fe93SStefano Zampini if (coarse_mat) { 7252b0f5fe93SStefano Zampini Vec nullv; 7253b0f5fe93SStefano Zampini PetscScalar *array,*array2; 7254b0f5fe93SStefano Zampini PetscInt nl; 7255b0f5fe93SStefano Zampini 7256b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 7257b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 7258b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7259b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 7260b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 7261b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 7262b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7263b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 7264b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 7265b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 7266b0f5fe93SStefano Zampini } 7267b0f5fe93SStefano Zampini } 7268b0f5fe93SStefano Zampini 7269b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 7270b0f5fe93SStefano Zampini PetscBool ispreonly; 7271b0f5fe93SStefano Zampini 7272b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7273b0f5fe93SStefano Zampini PetscBool isnull; 7274b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 7275bef83e63SStefano Zampini if (isnull) { 7276b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 7277b0f5fe93SStefano Zampini } 7278bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 7279b0f5fe93SStefano Zampini } 7280b0f5fe93SStefano Zampini /* setup coarse ksp */ 7281b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 7282cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 7283cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 72846e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 7285c8587f34SStefano Zampini KSP check_ksp; 72862b510759SStefano Zampini KSPType check_ksp_type; 7287c8587f34SStefano Zampini PC check_pc; 72886e683305SStefano Zampini Vec check_vec,coarse_vec; 72896a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 72902b510759SStefano Zampini PetscInt its; 72916e683305SStefano Zampini PetscBool compute_eigs; 72926e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 72936e683305SStefano Zampini PetscInt neigs; 72948e185a42SStefano Zampini const char *prefix; 7295c8587f34SStefano Zampini 72962b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 72976e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 7298422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 729923ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7300f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 7301e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 7302e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 7303e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 73042b510759SStefano Zampini if (ispreonly) { 73052b510759SStefano Zampini check_ksp_type = KSPPREONLY; 73066e683305SStefano Zampini compute_eigs = PETSC_FALSE; 73072b510759SStefano Zampini } else { 7308cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 73096e683305SStefano Zampini compute_eigs = PETSC_TRUE; 7310c8587f34SStefano Zampini } 7311c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 73126e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 73136e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 73146e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 7315a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 7316a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 7317a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 7318a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 7319c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 7320c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 7321c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 7322c8587f34SStefano Zampini /* create random vec */ 73232701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 7324c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 73256e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 7326c8587f34SStefano Zampini /* solve coarse problem */ 73276e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 7328cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 73296e683305SStefano Zampini if (compute_eigs) { 7330854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 7331854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 73326e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 73331ae86dd6SStefano Zampini if (neigs) { 73346e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 73356e683305SStefano Zampini lambda_min = eigs_r[0]; 73366e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 73372701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 73382701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 7339cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 7340cbcc2c2aSStefano Zampini } 7341c8587f34SStefano Zampini } 7342c8587f34SStefano Zampini } 73431ae86dd6SStefano Zampini } 7344cbcc2c2aSStefano Zampini 7345c8587f34SStefano Zampini /* check coarse problem residual error */ 73466e683305SStefano Zampini if (pcbddc->dbg_flag) { 73476e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 73486e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 73496e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 7350c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 73516e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 73526e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 7353779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 73546e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 73556e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 73566e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 73576e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 7358b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7359b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 7360b0f5fe93SStefano Zampini } 73616e683305SStefano Zampini if (compute_eigs) { 73626e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 7363deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 7364c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 73656e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 73666e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem eigenvalues (estimated with %d iterations of %s): %1.6e %1.6e (%1.6e %1.6e)\n",its,check_ksp_type,lambda_min,lambda_max,lambda_min_s,lambda_max_s);CHKERRQ(ierr); 73676e683305SStefano Zampini for (i=0;i<neigs;i++) { 73686e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 7369c8587f34SStefano Zampini } 73706e683305SStefano Zampini } 73716e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 73726e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 73736e683305SStefano Zampini } 7374e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 73752701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 7376c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 73776e683305SStefano Zampini if (compute_eigs) { 73786e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 73796e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 7380c8587f34SStefano Zampini } 73816e683305SStefano Zampini } 73826e683305SStefano Zampini } 7383bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 7384cbcc2c2aSStefano Zampini /* print additional info */ 7385cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 73866e683305SStefano Zampini /* waits until all processes reaches this point */ 73876e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 7388cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 7389cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7390cbcc2c2aSStefano Zampini } 7391cbcc2c2aSStefano Zampini 73922b510759SStefano Zampini /* free memory */ 7393fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 7394c8587f34SStefano Zampini PetscFunctionReturn(0); 7395c8587f34SStefano Zampini } 7396674ae819SStefano Zampini 7397f34684f1SStefano Zampini #undef __FUNCT__ 7398f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 7399f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 7400f34684f1SStefano Zampini { 7401f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7402f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 7403f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 7404dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 7405dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 740673be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 7407dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 7408f34684f1SStefano Zampini PetscErrorCode ierr; 7409f34684f1SStefano Zampini 7410f34684f1SStefano Zampini PetscFunctionBegin; 7411f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 74126c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 7413dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 74143bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 7415dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7416dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 74176583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 7418dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 7419dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 7420dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 74216c4ed002SBarry 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); 7422dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 7423dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7424dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 7425dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7426dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7427f34684f1SStefano Zampini 7428f34684f1SStefano Zampini /* check numbering */ 7429f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 7430019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 7431dc456d91SStefano Zampini PetscInt i; 7432b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 7433f34684f1SStefano Zampini 7434f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7435f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 7436f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 74371575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7438019a44ceSStefano Zampini /* counter */ 7439019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7440019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 7441019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7442019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7443019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7444019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7445f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 7446f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 7447727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 7448f34684f1SStefano Zampini } 7449f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7450f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7451f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7452e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7453e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7454e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7455e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7456f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7457019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7458f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7459019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 74602c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 746175c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 7462b9b85e73SStefano Zampini set_error = PETSC_TRUE; 74632c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 74642c66d082SStefano 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); 7465f34684f1SStefano Zampini } 7466f34684f1SStefano Zampini } 7467019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7468b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 7469f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7470f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7471f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 7472f34684f1SStefano Zampini } 7473f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7474f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7475e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7476e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7477f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 7478f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 7479b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 7480ca8b9ea9SStefano Zampini PetscInt *gidxs; 7481ca8b9ea9SStefano Zampini 7482ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 74833bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 7484f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 7485f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7486f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 7487f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 74884bc2dc4bSStefano 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); 7489f34684f1SStefano Zampini } 7490f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7491ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 7492f34684f1SStefano Zampini } 7493f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 74941575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7495302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 7496f34684f1SStefano Zampini } 74978bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 7498f34684f1SStefano Zampini /* get back data */ 7499f34684f1SStefano Zampini *coarse_size_n = coarse_size; 7500f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 7501674ae819SStefano Zampini PetscFunctionReturn(0); 7502674ae819SStefano Zampini } 7503674ae819SStefano Zampini 7504e456f2a8SStefano Zampini #undef __FUNCT__ 7505e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 7506a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 7507e456f2a8SStefano Zampini { 7508e456f2a8SStefano Zampini IS localis_t; 7509a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 7510e456f2a8SStefano Zampini PetscScalar *vals; 7511e456f2a8SStefano Zampini PetscErrorCode ierr; 7512e456f2a8SStefano Zampini 7513e456f2a8SStefano Zampini PetscFunctionBegin; 7514a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 7515e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 7516854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 7517e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 7518e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7519a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 7520a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 75211035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 7522a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 75231035eff8SStefano Zampini } 7524a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 7525e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7526e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 7527a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 7528a7dc3881SStefano Zampini /* now compute set in local ordering */ 7529a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7530a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7531a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7532a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 7533a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7534ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7535e456f2a8SStefano Zampini lsize++; 7536e456f2a8SStefano Zampini } 7537e456f2a8SStefano Zampini } 7538854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 7539a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7540ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7541e456f2a8SStefano Zampini idxs[lsize++] = i; 7542e456f2a8SStefano Zampini } 7543e456f2a8SStefano Zampini } 7544a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7545a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 7546e456f2a8SStefano Zampini *localis = localis_t; 7547e456f2a8SStefano Zampini PetscFunctionReturn(0); 7548e456f2a8SStefano Zampini } 7549906d46d4SStefano Zampini 7550b96c3477SStefano Zampini #undef __FUNCT__ 7551b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 755208122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 7553b96c3477SStefano Zampini { 7554a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7555b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7556b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 7557a64f4aa4SStefano Zampini Mat S_j; 7558b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 7559b96c3477SStefano Zampini PetscBool free_used_adj; 7560b96c3477SStefano Zampini PetscErrorCode ierr; 7561b96c3477SStefano Zampini 7562b96c3477SStefano Zampini PetscFunctionBegin; 7563b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 7564b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 756508122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 7566b96c3477SStefano Zampini used_xadj = NULL; 7567b96c3477SStefano Zampini used_adjncy = NULL; 7568b96c3477SStefano Zampini } else { 756908122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 757008122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 757108122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 757208122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 7573b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 7574b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 7575b96c3477SStefano Zampini } else { 75762fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 7577b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 7578b96c3477SStefano Zampini PetscInt nvtxs; 7579b96c3477SStefano Zampini 75802fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 75812fffb893SStefano Zampini if (flg_row) { 7582b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 7583b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 7584b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 7585b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 75862fffb893SStefano Zampini } else { 75872fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 75882fffb893SStefano Zampini used_xadj = NULL; 75892fffb893SStefano Zampini used_adjncy = NULL; 75902fffb893SStefano Zampini } 75912fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 7592b96c3477SStefano Zampini } 7593b96c3477SStefano Zampini } 7594d5574798SStefano Zampini 7595d5574798SStefano Zampini /* setup sub_schurs data */ 7596a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 7597df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 7598df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 7599a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 760091af6908SStefano 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); 7601a64f4aa4SStefano Zampini } else { 76026816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 76034d7f8f00SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE; 7604a3df083aSStefano Zampini PetscInt benign_n; 760572b8c272SStefano Zampini Mat change = NULL; 76069d54b7f4SStefano Zampini Vec scaling = NULL; 760772b8c272SStefano Zampini IS change_primal = NULL; 7608a3df083aSStefano Zampini 76095feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 76105feab87aSStefano Zampini PetscInt n_vertices; 76115feab87aSStefano Zampini 76125feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 76132034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 76145feab87aSStefano Zampini } 761504708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 761604708bb6SStefano Zampini if (!isseqaij) { 761704708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 761804708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 761904708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 762004708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 762104708bb6SStefano Zampini } else { 7622511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 762304708bb6SStefano Zampini } 762404708bb6SStefano Zampini } 7625a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 7626a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 7627ca92afb2SStefano Zampini } else { 7628a3df083aSStefano Zampini benign_n = 0; 7629ca92afb2SStefano Zampini } 7630b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 7631b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 7632b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 763372b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 763422db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 7635b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 763622db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 7637b7ab4a40SStefano Zampini } 7638b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 7639b7ab4a40SStefano 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 */ 7640b7ab4a40SStefano Zampini if (need_change) { 764188c03ad3SStefano Zampini PC_IS *pcisf; 764288c03ad3SStefano Zampini PC_BDDC *pcbddcf; 764388c03ad3SStefano Zampini PC pcf; 764488c03ad3SStefano Zampini 7645e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 764688c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 764788c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 764888c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 764988c03ad3SStefano Zampini /* hacks */ 765088c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 765172b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 765272b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 765372b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 765472b8c272SStefano Zampini pcisf->n = pcis->n; 765572b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 765688c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 765788c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 765888c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 765988c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 766088c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 766188c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 766272b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 766388c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 766488c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 766572b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 766672b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 766772b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 766872b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 766972b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 767088c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 767172b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 767288c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 767388c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 767488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 767588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 767688c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 767788c03ad3SStefano Zampini pcf->ops->destroy = NULL; 767888c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 767988c03ad3SStefano Zampini } 76809d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 768191af6908SStefano 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); 768272b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 768372b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 7684ca92afb2SStefano Zampini } 7685d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 7686b96c3477SStefano Zampini 7687b96c3477SStefano Zampini /* free adjacency */ 7688b96c3477SStefano Zampini if (free_used_adj) { 7689b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 7690b96c3477SStefano Zampini } 7691b96c3477SStefano Zampini PetscFunctionReturn(0); 7692b96c3477SStefano Zampini } 7693b96c3477SStefano Zampini 7694b96c3477SStefano Zampini #undef __FUNCT__ 7695b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 769608122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 7697b96c3477SStefano Zampini { 7698b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7699b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7700b96c3477SStefano Zampini PCBDDCGraph graph; 7701b96c3477SStefano Zampini PetscErrorCode ierr; 7702b96c3477SStefano Zampini 7703b96c3477SStefano Zampini PetscFunctionBegin; 7704b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 770508122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 77063301b35fSStefano Zampini IS verticesIS,verticescomm; 77073301b35fSStefano Zampini PetscInt vsize,*idxs; 7708b96c3477SStefano Zampini 7709b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 77103301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 77113301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 77123301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 77133301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 7714c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 7715b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 7716be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 7717441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 77183301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 7719b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 7720b96c3477SStefano Zampini } else { 7721b96c3477SStefano Zampini graph = pcbddc->mat_graph; 7722b96c3477SStefano Zampini } 7723e4d548c7SStefano Zampini /* print some info */ 7724e4d548c7SStefano Zampini if (pcbddc->dbg_flag) { 7725e4d548c7SStefano Zampini IS vertices; 7726e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 7727c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 7728e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 7729e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 7730e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7731e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 7732e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 7733e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 7734e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 7735e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7736e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7737c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 7738e4d548c7SStefano Zampini } 7739b96c3477SStefano Zampini 7740b96c3477SStefano Zampini /* sub_schurs init */ 7741b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 7742b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 7743b334f244SStefano Zampini } 7744*8b6046baSStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 7745a64f4aa4SStefano Zampini 7746b96c3477SStefano Zampini /* free graph struct */ 774708122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 7748b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 7749b96c3477SStefano Zampini } 7750b96c3477SStefano Zampini PetscFunctionReturn(0); 7751b96c3477SStefano Zampini } 7752fa34dd3eSStefano Zampini 7753fa34dd3eSStefano Zampini #undef __FUNCT__ 7754fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 7755fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 7756fa34dd3eSStefano Zampini { 7757fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7758fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7759fa34dd3eSStefano Zampini PetscErrorCode ierr; 7760fa34dd3eSStefano Zampini 7761fa34dd3eSStefano Zampini PetscFunctionBegin; 7762fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 7763fa34dd3eSStefano Zampini IS zerodiag = NULL; 77644f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 7765fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 77664f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 776775c01103SStefano Zampini PetscReal norm; 7768fa34dd3eSStefano Zampini PetscInt i; 7769fa34dd3eSStefano Zampini 7770fa34dd3eSStefano Zampini /* B0 and B0_B */ 7771fa34dd3eSStefano Zampini if (zerodiag) { 7772fa34dd3eSStefano Zampini IS dummy; 7773fa34dd3eSStefano Zampini 77744f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 77754f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 7776fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 7777fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 7778fa34dd3eSStefano Zampini } 7779fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 7780fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 7781fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 7782fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7783fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7784fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7785fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7786fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 7787fa34dd3eSStefano Zampini /* S_j */ 7788fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 7789fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 7790fa34dd3eSStefano Zampini 7791fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 7792fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 7793fa34dd3eSStefano Zampini /* continuous in primal space */ 7794fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 7795fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7796fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7797fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 77984f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 77994f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 7800fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 7801fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7802fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7803fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7804fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7805fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7806fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 7807fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 7808fa34dd3eSStefano Zampini 7809fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 7810fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 7811fa34dd3eSStefano Zampini /* local with Schur */ 7812fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 7813fa34dd3eSStefano Zampini if (zerodiag) { 7814fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 78154f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 7816fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 7817fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 7818fa34dd3eSStefano Zampini } 7819fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 7820fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7821fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7822fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7823fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 7824fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 7825fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 7826fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7827fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 7828fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7829fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7830fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7831fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7832fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7833fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 7834fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 7835fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 7836fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7837fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7838fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7839fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7840fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7841fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 7842fa34dd3eSStefano Zampini if (zerodiag) { 7843fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 7844fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 78454f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 7846fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 7847fa34dd3eSStefano Zampini } 7848fa34dd3eSStefano Zampini /* BDDC */ 7849fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 7850fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 7851fa34dd3eSStefano Zampini 7852fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 7853fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 7854fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 7855fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 78564f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 78574f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 7858fa34dd3eSStefano Zampini } 78594f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 7860fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 7861fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 7862fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 7863fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 7864fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 7865fa34dd3eSStefano Zampini } 7866fa34dd3eSStefano Zampini PetscFunctionReturn(0); 7867fa34dd3eSStefano Zampini } 7868