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)); 29a13144ffSStefano Zampini ierr = PetscMalloc1(ulw,&uwork); 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; 1114e64d54eSstefano_zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe; 112a13144ffSStefano Zampini MatNullSpace nnsp; 113a13144ffSStefano Zampini Vec tvec,*quads; 114a13144ffSStefano Zampini PetscSF sfv; 115*c2151214SStefano Zampini ISLocalToGlobalMapping el2g,vl2g,fl2g; 116a13144ffSStefano Zampini MPI_Comm comm; 117*c2151214SStefano Zampini IS lned,primals,allprimals,nedfieldlocal; 118*c2151214SStefano Zampini IS *eedges,*extrows,*extcols,*alleedges; 119*c2151214SStefano 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; 123*c2151214SStefano 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; 128*c2151214SStefano 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); 140*c2151214SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(el2g,&n);CHKERRQ(ierr); 141a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 142a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 143*c2151214SStefano 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 153*c2151214SStefano Zampini /* Get discrete gradient 154*c2151214SStefano 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; 158*c2151214SStefano Zampini field = pcbddc->nedfield; 159*c2151214SStefano 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); 160*c2151214SStefano Zampini if (pcbddc->n_ISForDofsLocal && field > -1) { 161*c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 162*c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 163*c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 164*c2151214SStefano Zampini } else { 165*c2151214SStefano Zampini PetscBool testnedfield = PETSC_FALSE; 166*c2151214SStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_nedelec_field",&testnedfield,NULL);CHKERRQ(ierr); 167*c2151214SStefano Zampini if (!testnedfield) { 168*c2151214SStefano Zampini ne = n; 169*c2151214SStefano Zampini nedfieldlocal = NULL; 170*c2151214SStefano Zampini } else { 171*c2151214SStefano Zampini /* ierr = ISCreateStride(comm,n,0,1,&nedfieldlocal);CHKERRQ(ierr); */ 172*c2151214SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 173*c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 174*c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 175*c2151214SStefano Zampini for (i=0;i<n;i++) matis->sf_leafdata[i] = 1; 176*c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 177*c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 178*c2151214SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 179*c2151214SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 180*c2151214SStefano Zampini for (i=0,cum=0;i<n;i++) { 181*c2151214SStefano Zampini if (matis->sf_leafdata[i] > 1) { 182*c2151214SStefano Zampini matis->sf_leafdata[cum++] = i; 183*c2151214SStefano Zampini } 184*c2151214SStefano Zampini } 185*c2151214SStefano Zampini ierr = ISCreateGeneral(comm,cum,matis->sf_leafdata,PETSC_COPY_VALUES,&nedfieldlocal);CHKERRQ(ierr); 186*c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 187*c2151214SStefano Zampini } 188*c2151214SStefano Zampini } 189a13144ffSStefano Zampini 190*c2151214SStefano Zampini if (nedfieldlocal) { /* merge with previous code when testing is done */ 191*c2151214SStefano Zampini IS is; 192*c2151214SStefano Zampini 193*c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 194*c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 195*c2151214SStefano Zampini /* need to map from the local Nedelec field to global numbering */ 196*c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,nedfieldlocal,&is);CHKERRQ(ierr); 197*c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&el2g);CHKERRQ(ierr); 198*c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 199*c2151214SStefano Zampini } else { 200*c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)el2g);CHKERRQ(ierr); 201*c2151214SStefano Zampini fl2g = NULL; 202*c2151214SStefano 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) */ 210*c2151214SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 211*c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 212*c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 213*c2151214SStefano Zampini if (nedfieldlocal) { 214*c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 215*c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 216*c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 217*c2151214SStefano Zampini } else { 218*c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 219*c2151214SStefano Zampini } 220*c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 221*c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 222*c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 223*c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 224*c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 225*c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 226*c2151214SStefano Zampini } 227*c2151214SStefano 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); 230*c2151214SStefano 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 */ 248*c2151214SStefano 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 261a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 2624e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 2634e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 264a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 265a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 266a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 267*c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 268a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 269a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 270a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 271*c2151214SStefano Zampini IS is; 272*c2151214SStefano Zampini 273*c2151214SStefano Zampini if (fl2g) { 274*c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 275*c2151214SStefano Zampini } else { 276*c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 277*c2151214SStefano Zampini } 278*c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 279*c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 280a13144ffSStefano Zampini for (i=0;i<cum;i++) { 281a13144ffSStefano Zampini if (idxs[i] >= 0) { 282a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 283a13144ffSStefano Zampini } 284a13144ffSStefano Zampini } 285*c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 286*c2151214SStefano Zampini if (fl2g) { 287*c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 288*c2151214SStefano Zampini } 289a13144ffSStefano Zampini } 290a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 291*c2151214SStefano Zampini IS is; 292*c2151214SStefano Zampini 293*c2151214SStefano Zampini if (fl2g) { 294*c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 295*c2151214SStefano Zampini } else { 296*c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 297*c2151214SStefano Zampini } 298*c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 299*c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 300a13144ffSStefano Zampini for (i=0;i<cum;i++) { 301a13144ffSStefano Zampini if (idxs[i] >= 0) { 302a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 303a13144ffSStefano Zampini } 304a13144ffSStefano Zampini } 305*c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 306*c2151214SStefano Zampini if (fl2g) { 307*c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 308a13144ffSStefano Zampini } 309*c2151214SStefano Zampini } 310*c2151214SStefano Zampini 311a13144ffSStefano Zampini /* need to remove coarse faces' dofs to ensure the 312a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 313a13144ffSStefano Zampini ierr = PetscCalloc1(ne,&marks);CHKERRQ(ierr); 314a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 315a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 316a13144ffSStefano Zampini PetscInt j; 317a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) marks[shared[i][j]]++; 318a13144ffSStefano Zampini } 319a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 320a13144ffSStefano Zampini cum = 0; 3214e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 322dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 323a13144ffSStefano Zampini for (i=0;i<ne;i++) { 324dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 325dec27d64SStefano Zampini if (!marks[i] || (marks[i] == 1 && !PetscBTLookup(btb,i))) { 326a13144ffSStefano Zampini marks[cum++] = i; 327dec27d64SStefano Zampini continue; 328dec27d64SStefano Zampini } 329dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 330dec27d64SStefano Zampini if (!conforming && ii[i+1]-ii[i] != order + 1) { 331a13144ffSStefano Zampini marks[cum++] = i; 332a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 333a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 334a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 335a13144ffSStefano Zampini } 336a13144ffSStefano Zampini } 337dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 338dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 339dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 340dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 341a13144ffSStefano Zampini } 342dec27d64SStefano Zampini } 343dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 3444e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 3454e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 346a13144ffSStefano Zampini /* identify splitpoints and corner candidates: TODO variable order */ 3474e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 348a13144ffSStefano Zampini if (print) { 3494e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 3504e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 3514e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 352a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 353a13144ffSStefano Zampini } 354a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 355dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 356a13144ffSStefano Zampini for (i=0;i<nv;i++) { 357dec27d64SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i]; 358dec27d64SStefano Zampini if (!order) { 359dec27d64SStefano Zampini PetscReal vorder = 0.; 360dec27d64SStefano Zampini 361dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 362dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 363dec27d64SStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%d)",vorder,test); 364dec27d64SStefano Zampini ord = 1; 365dec27d64SStefano Zampini } 366a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 367dec27d64SStefano 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); 368a13144ffSStefano Zampini #endif 369dec27d64SStefano Zampini if (test >= 3*ord) { /* splitpoints */ 370a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d\n",i); 371a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 372dec27d64SStefano Zampini } else if (test == ord) { 373a13144ffSStefano Zampini if (order == 1) { 374a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 375a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 376a13144ffSStefano Zampini } else { 377a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 378a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 379a13144ffSStefano Zampini } 380a13144ffSStefano Zampini } 381a13144ffSStefano Zampini } 382dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 383a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 384a13144ffSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 385a13144ffSStefano Zampini 386a13144ffSStefano Zampini /* Get the local G^T explicitly */ 387a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 3884e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 389a13144ffSStefano Zampini if (print) { 390a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"initial_lGt");CHKERRQ(ierr); 391a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 392a13144ffSStefano Zampini } 393a13144ffSStefano Zampini 3944e64d54eSstefano_zampini /* Mark interior nodal dofs */ 395a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 3964e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 397a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 398a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 3994e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 400a13144ffSStefano Zampini } 401a13144ffSStefano Zampini } 402a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 403a13144ffSStefano Zampini 404a13144ffSStefano Zampini /* communicate corners and splitpoints */ 405a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 406a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 407a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 408a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 409a13144ffSStefano Zampini 410a13144ffSStefano Zampini if (print) { 411a13144ffSStefano Zampini IS tbz; 412a13144ffSStefano Zampini 413a13144ffSStefano Zampini cum = 0; 414a13144ffSStefano Zampini for (i=0;i<nv;i++) 415a13144ffSStefano Zampini if (sfvleaves[i]) 416a13144ffSStefano Zampini vmarks[cum++] = i; 417a13144ffSStefano Zampini 418a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 419a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 420a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 421a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 422a13144ffSStefano Zampini } 423a13144ffSStefano Zampini 424a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 425a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 426a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 427a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 428a13144ffSStefano Zampini 4294e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 4304e64d54eSstefano_zampini and interior nodal dofs */ 431a13144ffSStefano Zampini cum = 0; 432a13144ffSStefano Zampini for (i=0;i<nv;i++) { 433a13144ffSStefano Zampini if (sfvleaves[i]) { 434a13144ffSStefano Zampini vmarks[cum++] = i; 435a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 436a13144ffSStefano Zampini } 4374e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 438a13144ffSStefano Zampini } 4394e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 440a13144ffSStefano Zampini if (print) { 441a13144ffSStefano Zampini IS tbz; 442a13144ffSStefano Zampini 443a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 4444e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 445a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 446a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 447a13144ffSStefano Zampini } 448a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 449a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 450a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 451a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 452a13144ffSStefano Zampini 453a13144ffSStefano Zampini /* Recompute G */ 454a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 455a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 456a13144ffSStefano Zampini if (print) { 457a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 458a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 459a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 460a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 461a13144ffSStefano Zampini } 462a13144ffSStefano Zampini 463a13144ffSStefano Zampini /* Get primal dofs (if any) */ 464a13144ffSStefano Zampini cum = 0; 465a13144ffSStefano Zampini for (i=0;i<ne;i++) { 466a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 467a13144ffSStefano Zampini } 468*c2151214SStefano Zampini if (fl2g) { 469*c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 470*c2151214SStefano Zampini } 471a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 472a13144ffSStefano Zampini if (print) { 473a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 474a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 475a13144ffSStefano Zampini } 476a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 477*c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 478a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 479a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 480a13144ffSStefano Zampini 481a13144ffSStefano Zampini /* Compute edge connectivity */ 482a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 483a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 484a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 485d904f53bSStefano Zampini if (done && i && ii && jj) { /* when lG is empty, don't pass pointers */ 486*c2151214SStefano Zampini if (fl2g) { 487*c2151214SStefano Zampini PetscBT btf; 488*c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 489*c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 490*c2151214SStefano Zampini 491*c2151214SStefano Zampini /* create CSR for all local dofs */ 492*c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 493*c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 494*c2151214SStefano 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); 495*c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 496*c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 497*c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 498*c2151214SStefano Zampini rest = PETSC_TRUE; 499*c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 500*c2151214SStefano Zampini } else { 501*c2151214SStefano Zampini free = PETSC_TRUE; 502*c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 503*c2151214SStefano Zampini iiu[0] = 0; 504*c2151214SStefano Zampini for (i=0;i<n;i++) { 505*c2151214SStefano Zampini iiu[i+1] = i+1; 506*c2151214SStefano Zampini jju[i] = -1; 507d904f53bSStefano Zampini } 508*c2151214SStefano Zampini } 509*c2151214SStefano Zampini 510*c2151214SStefano Zampini /* import sizes of CSR */ 511*c2151214SStefano Zampini iia[0] = 0; 512*c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 513*c2151214SStefano Zampini 514*c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 515*c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 516*c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 517*c2151214SStefano Zampini for (i=0;i<ne;i++) { 518*c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 519*c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 520*c2151214SStefano Zampini } 521*c2151214SStefano Zampini 522*c2151214SStefano Zampini /* iia in CSR */ 523*c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 524*c2151214SStefano Zampini 525*c2151214SStefano Zampini /* jja in CSR */ 526*c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 527*c2151214SStefano Zampini for (i=0;i<n;i++) 528*c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 529*c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 530*c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 531*c2151214SStefano Zampini 532*c2151214SStefano Zampini /* map edge dofs connectivity */ 533*c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 534*c2151214SStefano Zampini for (i=0;i<ne;i++) { 535*c2151214SStefano Zampini PetscInt e = idxs[i]; 536*c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 537*c2151214SStefano Zampini } 538*c2151214SStefano Zampini 539*c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 540*c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 541*c2151214SStefano Zampini if (rest) { 542*c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 543*c2151214SStefano Zampini } 544*c2151214SStefano Zampini if (free) { 545*c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 546*c2151214SStefano Zampini } 547*c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 548*c2151214SStefano Zampini } else { 549*c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 550*c2151214SStefano Zampini } 551*c2151214SStefano Zampini } 552*c2151214SStefano Zampini 553a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 554a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 555a13144ffSStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 556a13144ffSStefano Zampini 557a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 558a13144ffSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 559*c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 560a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 561a13144ffSStefano Zampini 562*c2151214SStefano Zampini if (fl2g) { 563*c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 564*c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 565*c2151214SStefano Zampini for (i=0;i<nee;i++) { 566*c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 567*c2151214SStefano Zampini } 568*c2151214SStefano Zampini } else { 569*c2151214SStefano Zampini eedges = alleedges; 570*c2151214SStefano Zampini primals = allprimals; 571*c2151214SStefano Zampini } 572*c2151214SStefano Zampini 573a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 574a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 575*c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 576*c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 577*c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 578*c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 579*c2151214SStefano Zampini if (print) { 580*c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 581*c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 582*c2151214SStefano Zampini } 583*c2151214SStefano Zampini 584*c2151214SStefano Zampini maxsize = 0; 585a13144ffSStefano Zampini for (i=0;i<nee;i++) { 586a13144ffSStefano Zampini PetscInt size,mark = i+1; 587a13144ffSStefano Zampini 588a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 589a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 590a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 591a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 592a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 593a13144ffSStefano Zampini } 594a13144ffSStefano Zampini 595a13144ffSStefano Zampini /* Find coarse edge endpoints */ 596a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 597a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 598a13144ffSStefano Zampini for (i=0;i<nee;i++) { 599a13144ffSStefano Zampini PetscInt mark = i+1,size; 600a13144ffSStefano Zampini 601a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 602a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 603a13144ffSStefano Zampini if (print) { 604a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 605a13144ffSStefano Zampini ISView(eedges[i],NULL); 606a13144ffSStefano Zampini } 607a13144ffSStefano Zampini for (j=0;j<size;j++) { 608a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 609a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 610a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 611a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 612a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 613a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 614a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 615a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," candidate? %d\n",(PetscBool)(PetscBTLookup(btvcand,jj[k]))); 616a13144ffSStefano Zampini PetscInt k2; 617a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 618a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 619*c2151214SStefano 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])); 620*c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 621*c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 622*c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 623a13144ffSStefano Zampini corner = PETSC_TRUE; 624a13144ffSStefano Zampini break; 625a13144ffSStefano Zampini } 626a13144ffSStefano Zampini } 627a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 628a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 629a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 630a13144ffSStefano Zampini } else { 631a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 632a13144ffSStefano Zampini } 633a13144ffSStefano Zampini } 634a13144ffSStefano Zampini } 635a13144ffSStefano Zampini } 636a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 637a13144ffSStefano Zampini } 638a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 639a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 640*c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 641a13144ffSStefano Zampini 642a13144ffSStefano Zampini /* Reset marked primal dofs */ 643a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 644a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 645a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 646a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 647a13144ffSStefano Zampini 648a13144ffSStefano Zampini /* Compute extended cols indices */ 649a13144ffSStefano Zampini ierr = MatGetRowIJ(lG ,0,PETSC_FALSE,PETSC_FALSE,&i, &ii, &jj,&done);CHKERRQ(ierr); 650a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 651a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 652a13144ffSStefano Zampini i *= maxsize; 653a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extcols);CHKERRQ(ierr); 654a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&emarks);CHKERRQ(ierr); 655a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 656a13144ffSStefano Zampini eerr = PETSC_FALSE; 657a13144ffSStefano Zampini for (i=0;i<nee;i++) { 658a13144ffSStefano Zampini PetscInt size; 659a13144ffSStefano Zampini 660a13144ffSStefano Zampini cum = 0; 661a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 662a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 663a13144ffSStefano Zampini for (j=0;j<size;j++) { 664a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 665a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 666a13144ffSStefano Zampini } 667a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 668a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 669a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 670a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 671a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 672a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 673a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 674a13144ffSStefano Zampini if (cum != size -1) { 675a13144ffSStefano Zampini emarks[i] = 1; 676a13144ffSStefano Zampini if (print) { 677a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 678a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 679a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 680a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 681a13144ffSStefano Zampini } 682a13144ffSStefano Zampini eerr = PETSC_TRUE; 683a13144ffSStefano Zampini } 684a13144ffSStefano Zampini } 6854e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 686a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 687a13144ffSStefano Zampini if (done) { 688a13144ffSStefano Zampini PetscInt *newprimals; 689a13144ffSStefano Zampini 690a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 691a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 692a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 693a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 694a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 695a13144ffSStefano Zampini for (i=0;i<nee;i++) { 696a13144ffSStefano Zampini if (emarks[i]) { 697a13144ffSStefano Zampini PetscInt size,mark = i+1; 698a13144ffSStefano Zampini 699a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 700a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 701*c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 702a13144ffSStefano Zampini for (j=0;j<size;j++) { 703a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 704a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 705a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 706a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 707a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 708a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 709a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 710a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 711a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 712a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 713a13144ffSStefano Zampini newprimals[cum++] = ee2; 714a13144ffSStefano Zampini /* finally set the new corners */ 715a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 716a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 717a13144ffSStefano Zampini } 718a13144ffSStefano Zampini } 719a13144ffSStefano Zampini } 720a13144ffSStefano Zampini } 721a13144ffSStefano Zampini } 722a13144ffSStefano Zampini } 723a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 724a13144ffSStefano Zampini } 725a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 726a13144ffSStefano Zampini } 727a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 728*c2151214SStefano Zampini if (fl2g) { 729*c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 730*c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 731*c2151214SStefano Zampini for (i=0;i<nee;i++) { 732*c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 733*c2151214SStefano Zampini } 734*c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 735*c2151214SStefano Zampini } 736*c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 737a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 738a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 739a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 740a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 741a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 742*c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 743*c2151214SStefano Zampini if (fl2g) { 744*c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 745*c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 746*c2151214SStefano Zampini for (i=0;i<nee;i++) { 747*c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 748*c2151214SStefano Zampini } 749*c2151214SStefano Zampini } else { 750*c2151214SStefano Zampini eedges = alleedges; 751*c2151214SStefano Zampini primals = allprimals; 752*c2151214SStefano Zampini } 753a13144ffSStefano Zampini 754a13144ffSStefano Zampini /* Mark again */ 755a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 756a13144ffSStefano Zampini for (i=0;i<nee;i++) { 757a13144ffSStefano Zampini PetscInt size,mark = i+1; 758a13144ffSStefano Zampini 759a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 760a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 761a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 762a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 763a13144ffSStefano Zampini } 764a13144ffSStefano Zampini if (print) { 765a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 766a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 767a13144ffSStefano Zampini } 768a13144ffSStefano Zampini 769a13144ffSStefano Zampini /* Recompute extended cols */ 770a13144ffSStefano Zampini eerr = PETSC_FALSE; 771a13144ffSStefano Zampini for (i=0;i<nee;i++) { 772a13144ffSStefano Zampini PetscInt size; 773a13144ffSStefano Zampini 774a13144ffSStefano Zampini cum = 0; 775a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 776a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 777a13144ffSStefano Zampini for (j=0;j<size;j++) { 778a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 779a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 780a13144ffSStefano Zampini if (!PetscBTLookup(btv,jj[k])) { 781a13144ffSStefano Zampini extrow[cum++] = jj[k]; 782a13144ffSStefano Zampini } 783a13144ffSStefano Zampini } 784a13144ffSStefano Zampini } 785a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 786a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 787a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 788a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 789a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 790a13144ffSStefano Zampini if (cum != size -1) { 791a13144ffSStefano Zampini if (print) { 792a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 793a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 794a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 795a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 796a13144ffSStefano Zampini } 797a13144ffSStefano Zampini eerr = PETSC_TRUE; 798a13144ffSStefano Zampini } 799a13144ffSStefano Zampini } 800a13144ffSStefano Zampini } 801a13144ffSStefano Zampini ierr = MatRestoreRowIJ( lG,0,PETSC_FALSE,PETSC_FALSE,&i, &ii, &jj,&done);CHKERRQ(ierr); 802a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 803a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 804a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 805a13144ffSStefano Zampini /* an error should not occur at this point */ 806a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 807a13144ffSStefano Zampini 8084e64d54eSstefano_zampini /* Check the number of endpoints */ 809*c2151214SStefano Zampini /* TODO: fix case for circular edge */ 8104e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 8114e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 8124e64d54eSstefano_zampini for (i=0;i<nee;i++) { 8134e64d54eSstefano_zampini PetscInt size, found = 0; 8144e64d54eSstefano_zampini 8154e64d54eSstefano_zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 8164e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8174e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 8184e64d54eSstefano_zampini for (j=0;j<size;j++) { 8194e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 8204e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 8214e64d54eSstefano_zampini PetscInt vv = jj[k]; 8224e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 8234e64d54eSstefano_zampini found++; 8244e64d54eSstefano_zampini } 8254e64d54eSstefano_zampini } 8264e64d54eSstefano_zampini } 8274e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 8284e64d54eSstefano_zampini if (found != 2) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %d corners for edge %d\n",found,i); 8294e64d54eSstefano_zampini } 8304e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 8314e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 8324e64d54eSstefano_zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 8334e64d54eSstefano_zampini 834a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 835a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 836a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 837a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 838a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 839a13144ffSStefano Zampini for (i=0;i<nv;i++) { 840a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 841a13144ffSStefano Zampini 842a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 843a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 844a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 845a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 846a13144ffSStefano Zampini if (emax < emarks[j]) { 847a13144ffSStefano Zampini emax = emarks[j]; 848a13144ffSStefano Zampini eemax = j; 849a13144ffSStefano Zampini } 850a13144ffSStefano Zampini } 851a13144ffSStefano Zampini /* not relevant for edges */ 852a13144ffSStefano Zampini if (!eemax) continue; 853a13144ffSStefano Zampini 854a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 855a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 856*c2151214SStefano 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]); 857a13144ffSStefano Zampini } 858a13144ffSStefano Zampini } 859a13144ffSStefano Zampini } 860a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 861a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 862a13144ffSStefano Zampini #endif 863a13144ffSStefano Zampini 864a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 865a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 866a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 867a13144ffSStefano Zampini extmem *= maxsize; 868a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 869a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 870a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 871a13144ffSStefano Zampini for (i=0;i<nv;i++) { 872a13144ffSStefano Zampini PetscInt mark = 0,size,start; 873a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 874a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 875a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 876a13144ffSStefano Zampini mark = marks[jj[j]]; 877a13144ffSStefano Zampini 878a13144ffSStefano Zampini /* not relevant */ 879a13144ffSStefano Zampini if (!mark) continue; 880a13144ffSStefano Zampini 881a13144ffSStefano Zampini /* import extended row */ 882a13144ffSStefano Zampini mark--; 883a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 884a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 885a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 886a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 887a13144ffSStefano Zampini extrowcum[mark] += size; 888a13144ffSStefano Zampini } 889a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 890a13144ffSStefano Zampini cum = 0; 891a13144ffSStefano Zampini for (i=0;i<nee;i++) { 892a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 893a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 894a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 895a13144ffSStefano Zampini cum = PetscMax(cum,size); 896a13144ffSStefano Zampini } 897a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 898a13144ffSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 899a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 900a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 901a13144ffSStefano Zampini 902a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 903a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 904a13144ffSStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 905a13144ffSStefano Zampini for (i=0;i<maxsize;i++) vals[i] = 1.; 906a13144ffSStefano Zampini 907a13144ffSStefano Zampini /* Create vectors for quadrature rules */ 908*c2151214SStefano Zampini /* TODO preserve other quadratures */ 909a13144ffSStefano Zampini ierr = PetscMalloc1(nquads,&quads);CHKERRQ(ierr); 910a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 911a13144ffSStefano Zampini ierr = MatCreateVecs(pc->pmat,&quads[i],NULL);CHKERRQ(ierr); 912a13144ffSStefano Zampini ierr = VecSetLocalToGlobalMapping(quads[i],el2g);CHKERRQ(ierr); 913a13144ffSStefano Zampini } 914a13144ffSStefano Zampini ierr = PCBDDCNullSpaceCreate(comm,PETSC_FALSE,nquads,quads,&nnsp);CHKERRQ(ierr); 915a13144ffSStefano Zampini 916a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 917a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 918*c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 919*c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 920a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 921a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 922a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 923a13144ffSStefano Zampini ierr = MatSetLocalToGlobalMapping(T,el2g,el2g);CHKERRQ(ierr); 924a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 925a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 926a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 927a13144ffSStefano Zampini 928a13144ffSStefano Zampini /* Defaults to identity */ 929*c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 930a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 931a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 932a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 933a13144ffSStefano Zampini 934a13144ffSStefano Zampini for (i=0;i<nee;i++) { 935a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 936a13144ffSStefano Zampini 937a13144ffSStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],&Gins,&GKins,work,rwork);CHKERRQ(ierr); 938a13144ffSStefano Zampini if (Gins && GKins) { 939a13144ffSStefano Zampini PetscScalar *data; 940a13144ffSStefano Zampini const PetscInt *rows,*cols; 941a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 942a13144ffSStefano Zampini 943a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 944a13144ffSStefano Zampini /* H1 */ 945a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 946a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 947a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 948a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 949a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 950a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 951a13144ffSStefano Zampini /* complement */ 952a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 953a13144ffSStefano Zampini if (ncc > nquads-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet supported ncc %d nquads %d",ncc,nquads); 954a13144ffSStefano 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); 955a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 956a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 957a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 958a13144ffSStefano Zampini /* Gins kernel quadratures */ 959a13144ffSStefano Zampini for (j=0;j<ncc;j++) { 960a13144ffSStefano Zampini ierr = VecSetValueLocal(quads[j],cols[nch+j],1.,INSERT_VALUES);CHKERRQ(ierr); 961a13144ffSStefano Zampini } 962a13144ffSStefano Zampini /* H1 average */ 963a13144ffSStefano Zampini ierr = VecSetValuesLocal(quads[nquads-1],nch,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 964a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 965a13144ffSStefano Zampini } 966a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 967a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 968a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 969a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 970a13144ffSStefano Zampini } 971a13144ffSStefano Zampini 972a13144ffSStefano Zampini /* Start assembling */ 973a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 974a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 975a13144ffSStefano Zampini ierr = VecAssemblyBegin(quads[i]);CHKERRQ(ierr); 976a13144ffSStefano Zampini } 977a13144ffSStefano Zampini 978a13144ffSStefano Zampini /* Free */ 979*c2151214SStefano Zampini if (fl2g) { 980*c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 981*c2151214SStefano Zampini for (i=0;i<nee;i++) { 982*c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 983*c2151214SStefano Zampini } 984*c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 985*c2151214SStefano Zampini } 986*c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 987*c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 988*c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 989a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 990a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 991*c2151214SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 992*c2151214SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 993a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 994a13144ffSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 995a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 996a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 997a13144ffSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 998a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 999a13144ffSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1000a13144ffSStefano Zampini 1001a13144ffSStefano Zampini /* Complete assembling */ 1002a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1003a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 1004a13144ffSStefano Zampini ierr = VecAssemblyEnd(quads[i]);CHKERRQ(ierr); 1005a13144ffSStefano Zampini } 1006a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 1007a13144ffSStefano Zampini ierr = VecDestroy(&quads[i]);CHKERRQ(ierr); 1008a13144ffSStefano Zampini } 1009a13144ffSStefano Zampini ierr = PetscFree(quads);CHKERRQ(ierr); 1010a13144ffSStefano Zampini 1011a13144ffSStefano Zampini /* tell PCBDDC the topography has been analyzed */ 1012a13144ffSStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 1013a13144ffSStefano Zampini 1014a13144ffSStefano Zampini /* set change of basis */ 1015a13144ffSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,PETSC_FALSE);CHKERRQ(ierr); 1016a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1017a13144ffSStefano Zampini 1018a13144ffSStefano Zampini /* set quadratures */ 1019a13144ffSStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnsp);CHKERRQ(ierr); 1020a13144ffSStefano Zampini ierr = MatNullSpaceDestroy(&nnsp);CHKERRQ(ierr); 1021a13144ffSStefano Zampini 1022a13144ffSStefano Zampini PetscFunctionReturn(0); 1023a13144ffSStefano Zampini } 1024a13144ffSStefano Zampini 1025d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1026d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1027d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1028d8203eabSStefano Zampini #undef __FUNCT__ 1029d8203eabSStefano Zampini #define __FUNCT__ "PCBDDCNullSpaceCreate" 1030d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1031d8203eabSStefano Zampini { 1032d8203eabSStefano Zampini PetscErrorCode ierr; 1033d8203eabSStefano Zampini PetscInt i; 1034d8203eabSStefano Zampini 1035d8203eabSStefano Zampini PetscFunctionBegin; 1036d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1037d8203eabSStefano Zampini PetscInt first,last; 1038d8203eabSStefano Zampini 1039d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 104086fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1041d8203eabSStefano Zampini if (i>=first && i < last) { 1042d8203eabSStefano Zampini PetscScalar *data; 1043d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1044d8203eabSStefano Zampini if (!has_const) { 1045d8203eabSStefano Zampini data[i-first] = 1.; 1046d8203eabSStefano Zampini } else { 104786fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 104886fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1049d8203eabSStefano Zampini } 1050d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1051d8203eabSStefano Zampini } 1052d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1053d8203eabSStefano Zampini } 1054d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1055d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1056d8203eabSStefano Zampini PetscInt first,last; 1057d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1058d8203eabSStefano Zampini if (i>=first && i < last) { 1059d8203eabSStefano Zampini PetscScalar *data; 1060d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1061d8203eabSStefano Zampini if (!has_const) { 1062d8203eabSStefano Zampini data[i-first] = 0.; 1063d8203eabSStefano Zampini } else { 106486fa73c5SStefano Zampini data[2*i-first] = 0.; 106586fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1066d8203eabSStefano Zampini } 1067d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1068d8203eabSStefano Zampini } 1069d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1070d8203eabSStefano Zampini } 1071d8203eabSStefano Zampini PetscFunctionReturn(0); 1072d8203eabSStefano Zampini } 1073d8203eabSStefano Zampini 1074669cc0f4SStefano Zampini #undef __FUNCT__ 1075669cc0f4SStefano Zampini #define __FUNCT__ "PCBDDCComputeNoNetFlux" 10768ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1077669cc0f4SStefano Zampini { 1078a198735bSStefano Zampini Mat loc_divudotp; 1079fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 10808ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1081669cc0f4SStefano Zampini IS *faces,*edges; 1082669cc0f4SStefano Zampini PetscScalar *vals; 1083669cc0f4SStefano Zampini const PetscScalar *array; 1084669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 10851ae86dd6SStefano Zampini PetscMPIInt rank; 1086a198735bSStefano Zampini PetscErrorCode ierr; 1087669cc0f4SStefano Zampini 1088669cc0f4SStefano Zampini PetscFunctionBegin; 1089669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1090669cc0f4SStefano Zampini if (graph->twodim) { 1091669cc0f4SStefano Zampini lmaxneighs = 2; 1092669cc0f4SStefano Zampini } else { 1093669cc0f4SStefano Zampini lmaxneighs = 1; 1094669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1095669cc0f4SStefano Zampini const PetscInt *idxs; 1096669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1097669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 1098669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1099669cc0f4SStefano Zampini } 1100669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 1101669cc0f4SStefano Zampini } 1102669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 1103669cc0f4SStefano Zampini maxsize = 0; 1104669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1105669cc0f4SStefano Zampini PetscInt nn; 1106669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1107669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1108669cc0f4SStefano Zampini } 1109669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1110669cc0f4SStefano Zampini PetscInt nn; 1111669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1112669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1113669cc0f4SStefano Zampini } 1114669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1115669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1116669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 11178ae0ca82SStefano Zampini if (!transpose) { 11188ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 11198ae0ca82SStefano Zampini } else { 11208ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 11218ae0ca82SStefano Zampini } 1122669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 11231ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1124d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1125669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 11268ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1127669cc0f4SStefano Zampini } 1128d8203eabSStefano Zampini 1129669cc0f4SStefano Zampini /* compute local quad vec */ 1130a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 11318ae0ca82SStefano Zampini if (!transpose) { 1132a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 11338ae0ca82SStefano Zampini } else { 11348ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 11358ae0ca82SStefano Zampini } 1136669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 11378ae0ca82SStefano Zampini if (!transpose) { 1138a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 11398ae0ca82SStefano Zampini } else { 11408ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 11418ae0ca82SStefano Zampini } 1142fa23a32eSStefano Zampini if (vl2l) { 1143fa23a32eSStefano Zampini ierr = VecGetSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1144fa23a32eSStefano Zampini } else { 1145fa23a32eSStefano Zampini vins = v; 1146fa23a32eSStefano Zampini } 1147fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1148669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 11499a962809SStefano Zampini 11501ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 11511ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1152669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1153669cc0f4SStefano Zampini const PetscInt *idxs; 1154669cc0f4SStefano Zampini PetscInt idx,nn,j; 1155669cc0f4SStefano Zampini 1156669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 1157669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1158669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 11591ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1160669cc0f4SStefano Zampini idx = -(idx+1); 1161669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1162669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 1163669cc0f4SStefano Zampini } 1164669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1165669cc0f4SStefano Zampini const PetscInt *idxs; 1166669cc0f4SStefano Zampini PetscInt idx,nn,j; 1167669cc0f4SStefano Zampini 1168669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1169669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1170669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 11711ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1172669cc0f4SStefano Zampini idx = -(idx+1); 1173669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1174669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1175669cc0f4SStefano Zampini } 1176c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1177fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1178fa23a32eSStefano Zampini if (vl2l) { 1179fa23a32eSStefano Zampini ierr = VecRestoreSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1180fa23a32eSStefano Zampini } 1181669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1182669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1183669cc0f4SStefano Zampini 1184669cc0f4SStefano Zampini /* assemble near null space */ 1185669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1186669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1187669cc0f4SStefano Zampini } 1188669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1189669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 1190669cc0f4SStefano Zampini } 1191669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1192669cc0f4SStefano Zampini PetscFunctionReturn(0); 1193669cc0f4SStefano Zampini } 1194669cc0f4SStefano Zampini 1195669cc0f4SStefano Zampini 1196a3df083aSStefano Zampini #undef __FUNCT__ 11971f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 11981f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 11991f4df5f7SStefano Zampini { 12001f4df5f7SStefano Zampini PetscErrorCode ierr; 12011f4df5f7SStefano Zampini Vec local,global; 12021f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12031f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 12041f4df5f7SStefano Zampini 12051f4df5f7SStefano Zampini PetscFunctionBegin; 12061f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 12071f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 12081f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 12091f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 12101f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 12111f4df5f7SStefano Zampini PetscInt i; 12121f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 12131f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 12141f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 12151f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 12161f4df5f7SStefano Zampini } 12171f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 12181f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 12191f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 12201f4df5f7SStefano Zampini } 12211f4df5f7SStefano Zampini } else { 1222986cdee1SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering if bs > 1 */ 12231f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1224986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 1225986cdee1SStefano Zampini if (i > 1) { 1226986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 12271f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 12281f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 12291f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 12301f4df5f7SStefano Zampini } 12311f4df5f7SStefano Zampini } 12321f4df5f7SStefano Zampini } 1233986cdee1SStefano Zampini } 12341f4df5f7SStefano Zampini 12351f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 12361f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 12371f4df5f7SStefano Zampini } 12381f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 12391f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 12401f4df5f7SStefano Zampini } 12411f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 12421f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 12431f4df5f7SStefano Zampini } 12441f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 12451f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 12461f4df5f7SStefano Zampini PetscFunctionReturn(0); 12471f4df5f7SStefano Zampini } 12481f4df5f7SStefano Zampini 12491f4df5f7SStefano Zampini #undef __FUNCT__ 12503e589ea0SStefano Zampini #define __FUNCT__ "PCBDDCBenignRemoveInterior" 12513e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 12523e589ea0SStefano Zampini { 12533e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 12543e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 12553e589ea0SStefano Zampini PetscErrorCode ierr; 12563e589ea0SStefano Zampini 12573e589ea0SStefano Zampini PetscFunctionBegin; 12583e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 12593e589ea0SStefano Zampini PetscFunctionReturn(0); 12603e589ea0SStefano Zampini } 12613e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 12623e589ea0SStefano Zampini Vec swap; 12633e589ea0SStefano Zampini 12643e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 12653e589ea0SStefano Zampini swap = pcbddc->work_change; 12663e589ea0SStefano Zampini pcbddc->work_change = r; 12673e589ea0SStefano Zampini r = swap; 12683e589ea0SStefano Zampini } 12693e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12703e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12713e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 12723e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 12733e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12743e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12753e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 12763e589ea0SStefano Zampini Vec swap; 12773e589ea0SStefano Zampini 12783e589ea0SStefano Zampini swap = r; 12793e589ea0SStefano Zampini r = pcbddc->work_change; 12803e589ea0SStefano Zampini pcbddc->work_change = swap; 12813e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 12823e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 12833e589ea0SStefano Zampini } 12843e589ea0SStefano Zampini PetscFunctionReturn(0); 12853e589ea0SStefano Zampini } 12863e589ea0SStefano Zampini 12873e589ea0SStefano Zampini #undef __FUNCT__ 1288a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 1289a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1290a3df083aSStefano Zampini { 1291a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1292a3df083aSStefano Zampini PetscErrorCode ierr; 1293a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1294a3df083aSStefano Zampini 1295a3df083aSStefano Zampini PetscFunctionBegin; 1296a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1297a3df083aSStefano Zampini if (transpose) { 1298a3df083aSStefano Zampini apply_right = ctx->apply_left; 1299a3df083aSStefano Zampini apply_left = ctx->apply_right; 1300a3df083aSStefano Zampini } else { 1301a3df083aSStefano Zampini apply_right = ctx->apply_right; 1302a3df083aSStefano Zampini apply_left = ctx->apply_left; 1303a3df083aSStefano Zampini } 1304a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1305a3df083aSStefano Zampini if (apply_right) { 1306a3df083aSStefano Zampini const PetscScalar *ax; 1307a3df083aSStefano Zampini PetscInt nl,i; 1308a3df083aSStefano Zampini 1309a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1310a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1311a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1312a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1313a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1314a3df083aSStefano Zampini PetscScalar sum,val; 1315a3df083aSStefano Zampini const PetscInt *idxs; 1316a3df083aSStefano Zampini PetscInt nz,j; 1317a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1318a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1319a3df083aSStefano Zampini sum = 0.; 1320a3df083aSStefano Zampini if (ctx->apply_p0) { 1321a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1322a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1323a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1324a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1325a3df083aSStefano Zampini } 1326a3df083aSStefano Zampini } else { 1327a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1328a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1329a3df083aSStefano Zampini } 1330a3df083aSStefano Zampini } 1331a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1332a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1333a3df083aSStefano Zampini } 1334a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1335a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1336a3df083aSStefano Zampini } 1337a3df083aSStefano Zampini if (transpose) { 1338a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1339a3df083aSStefano Zampini } else { 1340a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1341a3df083aSStefano Zampini } 1342a3df083aSStefano Zampini if (reset_x) { 1343a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1344a3df083aSStefano Zampini } 1345a3df083aSStefano Zampini if (apply_left) { 1346a3df083aSStefano Zampini PetscScalar *ay; 1347a3df083aSStefano Zampini PetscInt i; 1348a3df083aSStefano Zampini 1349a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);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 val = -ay[idxs[nz-1]]; 1357a3df083aSStefano Zampini if (ctx->apply_p0) { 1358a3df083aSStefano Zampini sum = 0.; 1359a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1360a3df083aSStefano Zampini sum += ay[idxs[j]]; 1361a3df083aSStefano Zampini ay[idxs[j]] += val; 1362a3df083aSStefano Zampini } 1363a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1364a3df083aSStefano Zampini } else { 1365a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1366a3df083aSStefano Zampini ay[idxs[j]] += val; 1367a3df083aSStefano Zampini } 1368a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1369a3df083aSStefano Zampini } 1370a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1371a3df083aSStefano Zampini } 1372a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1373a3df083aSStefano Zampini } 1374a3df083aSStefano Zampini PetscFunctionReturn(0); 1375a3df083aSStefano Zampini } 1376a3df083aSStefano Zampini 1377a3df083aSStefano Zampini #undef __FUNCT__ 1378a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 1379a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1380a3df083aSStefano Zampini { 1381a3df083aSStefano Zampini PetscErrorCode ierr; 1382a3df083aSStefano Zampini 1383a3df083aSStefano Zampini PetscFunctionBegin; 1384a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1385a3df083aSStefano Zampini PetscFunctionReturn(0); 1386a3df083aSStefano Zampini } 1387a3df083aSStefano Zampini 1388a3df083aSStefano Zampini #undef __FUNCT__ 1389a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 1390a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1391a3df083aSStefano Zampini { 1392a3df083aSStefano Zampini PetscErrorCode ierr; 1393a3df083aSStefano Zampini 1394a3df083aSStefano Zampini PetscFunctionBegin; 1395a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1396a3df083aSStefano Zampini PetscFunctionReturn(0); 1397a3df083aSStefano Zampini } 1398a3df083aSStefano Zampini 1399a3df083aSStefano Zampini #undef __FUNCT__ 1400a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 1401a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1402a3df083aSStefano Zampini { 1403a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1404a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1405a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1406a3df083aSStefano Zampini PetscErrorCode ierr; 1407a3df083aSStefano Zampini 1408a3df083aSStefano Zampini PetscFunctionBegin; 1409a3df083aSStefano Zampini if (!restore) { 14101dd7afcfSStefano Zampini Mat A_IB,A_BI; 1411a3df083aSStefano Zampini PetscScalar *work; 1412b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1413a3df083aSStefano Zampini 14149a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 14159a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1416a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1417a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1418a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1419a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1420a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1421a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1422a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 1423a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 1424a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 1425a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 1426a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 1427a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 1428059032f7SStefano Zampini if (reuse) { 1429a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 14301dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 1431059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 1432059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 1433059032f7SStefano Zampini PetscInt i; 1434059032f7SStefano Zampini 1435059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 1436059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1437059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1438059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1439059032f7SStefano Zampini } 1440059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 14411dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 1442059032f7SStefano Zampini } 1443a3df083aSStefano Zampini ctx->A = pcis->A_IB; 1444a3df083aSStefano Zampini ctx->work = work; 1445a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 1446a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1447a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1448a3df083aSStefano Zampini pcis->A_IB = A_IB; 1449a3df083aSStefano Zampini 1450a3df083aSStefano Zampini /* A_BI as A_IB^T */ 1451a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 1452a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 1453a3df083aSStefano Zampini pcis->A_BI = A_BI; 1454a3df083aSStefano Zampini } else { 14551dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 14561dd7afcfSStefano Zampini PetscFunctionReturn(0); 14571dd7afcfSStefano Zampini } 1458a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 1459a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1460a3df083aSStefano Zampini pcis->A_IB = ctx->A; 14611dd7afcfSStefano Zampini ctx->A = NULL; 14621dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 14631dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 14641dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 14651dd7afcfSStefano Zampini if (ctx->free) { 1466059032f7SStefano Zampini PetscInt i; 14671dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1468059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1469059032f7SStefano Zampini } 1470059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1471059032f7SStefano Zampini } 1472a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 1473a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 1474a3df083aSStefano Zampini } 1475a3df083aSStefano Zampini PetscFunctionReturn(0); 1476a3df083aSStefano Zampini } 1477a3df083aSStefano Zampini 1478a3df083aSStefano Zampini /* used just in bddc debug mode */ 1479a3df083aSStefano Zampini #undef __FUNCT__ 1480a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 1481a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 1482a3df083aSStefano Zampini { 1483a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1484a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1485a3df083aSStefano Zampini Mat An; 1486a3df083aSStefano Zampini PetscErrorCode ierr; 1487a3df083aSStefano Zampini 1488a3df083aSStefano Zampini PetscFunctionBegin; 1489a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 1490a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 1491a3df083aSStefano Zampini if (is1) { 1492a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 1493a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 1494a3df083aSStefano Zampini } else { 1495a3df083aSStefano Zampini *B = An; 1496a3df083aSStefano Zampini } 1497a3df083aSStefano Zampini PetscFunctionReturn(0); 1498a3df083aSStefano Zampini } 1499a3df083aSStefano Zampini 15001cf9b237SStefano Zampini /* TODO: add reuse flag */ 15011cf9b237SStefano Zampini #undef __FUNCT__ 15021cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 15031cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 15041cf9b237SStefano Zampini { 15051cf9b237SStefano Zampini Mat Bt; 15061cf9b237SStefano Zampini PetscScalar *a,*bdata; 15071cf9b237SStefano Zampini const PetscInt *ii,*ij; 15081cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 15091cf9b237SStefano Zampini PetscBool flg_row; 15101cf9b237SStefano Zampini PetscErrorCode ierr; 15111cf9b237SStefano Zampini 15121cf9b237SStefano Zampini PetscFunctionBegin; 15131cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 15141cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 15151cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 15161cf9b237SStefano Zampini nnz = n; 15171cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 15181cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 15191cf9b237SStefano Zampini } 15201cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 15211cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 15221cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 15231cf9b237SStefano Zampini nnz = 0; 15241cf9b237SStefano Zampini bii[0] = 0; 15251cf9b237SStefano Zampini for (i=0;i<n;i++) { 15261cf9b237SStefano Zampini PetscInt j; 15271cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 15281cf9b237SStefano Zampini PetscScalar entry = a[j]; 15291cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 15301cf9b237SStefano Zampini bij[nnz] = ij[j]; 15311cf9b237SStefano Zampini bdata[nnz] = entry; 15321cf9b237SStefano Zampini nnz++; 15331cf9b237SStefano Zampini } 15341cf9b237SStefano Zampini } 15351cf9b237SStefano Zampini bii[i+1] = nnz; 15361cf9b237SStefano Zampini } 15371cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 15381cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 15391cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 15401cf9b237SStefano Zampini { 15411cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 15421cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 15431cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 15441cf9b237SStefano Zampini } 15451cf9b237SStefano Zampini *B = Bt; 15461cf9b237SStefano Zampini PetscFunctionReturn(0); 15471cf9b237SStefano Zampini } 15481cf9b237SStefano Zampini 1549674ae819SStefano Zampini #undef __FUNCT__ 15504f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 15514f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 15524f1b2e48SStefano Zampini { 15534f1b2e48SStefano Zampini Mat B; 15544f1b2e48SStefano Zampini IS is_dummy,*cc_n; 15554f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 15564f1b2e48SStefano Zampini PCBDDCGraph graph; 15574f1b2e48SStefano Zampini PetscInt i,n; 15584f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 15594f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 15604f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 15614f1b2e48SStefano Zampini PetscErrorCode ierr; 15624f1b2e48SStefano Zampini 15634f1b2e48SStefano Zampini PetscFunctionBegin; 156463c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 156563c961adSStefano Zampini *ncc = 0; 156663c961adSStefano Zampini *cc = NULL; 156763c961adSStefano Zampini PetscFunctionReturn(0); 156863c961adSStefano Zampini } 15694f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 15704f1b2e48SStefano Zampini if (!isseqaij && filter) { 15711cf9b237SStefano Zampini PetscBool isseqdense; 15721cf9b237SStefano Zampini 15731cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 15741cf9b237SStefano Zampini if (!isseqdense) { 15754f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 15761cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 15771cf9b237SStefano Zampini PetscScalar *array; 15781cf9b237SStefano Zampini PetscReal chop=1.e-6; 15791cf9b237SStefano Zampini 15801cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 15811cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 15821cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 15831cf9b237SStefano Zampini for (i=0;i<n;i++) { 15841cf9b237SStefano Zampini PetscInt j; 15851cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 15861cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 15871cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 15881cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 15891cf9b237SStefano Zampini } 15901cf9b237SStefano Zampini } 15911cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 15929d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 15931cf9b237SStefano Zampini } 15944f1b2e48SStefano Zampini } else { 15954f1b2e48SStefano Zampini B = A; 15964f1b2e48SStefano Zampini } 15974f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 15984f1b2e48SStefano Zampini 15994f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 16004f1b2e48SStefano Zampini if (filter) { 16014f1b2e48SStefano Zampini PetscScalar *data; 16024f1b2e48SStefano Zampini PetscInt j,cum; 16034f1b2e48SStefano Zampini 16044f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 16054f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 16064f1b2e48SStefano Zampini cum = 0; 16074f1b2e48SStefano Zampini for (i=0;i<n;i++) { 16084f1b2e48SStefano Zampini PetscInt t; 16094f1b2e48SStefano Zampini 16104f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 16114f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 16124f1b2e48SStefano Zampini continue; 16134f1b2e48SStefano Zampini } 16144f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 16154f1b2e48SStefano Zampini } 16164f1b2e48SStefano Zampini t = xadj_filtered[i]; 16174f1b2e48SStefano Zampini xadj_filtered[i] = cum; 16184f1b2e48SStefano Zampini cum += t; 16194f1b2e48SStefano Zampini } 16204f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 16214f1b2e48SStefano Zampini } else { 16224f1b2e48SStefano Zampini xadj_filtered = NULL; 16234f1b2e48SStefano Zampini adjncy_filtered = NULL; 16244f1b2e48SStefano Zampini } 16254f1b2e48SStefano Zampini 16264f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 16274f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 16284f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 16294f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 16304f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 1631be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 16324f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 16334f1b2e48SStefano Zampini if (xadj_filtered) { 16344f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 16354f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 16364f1b2e48SStefano Zampini } else { 16374f1b2e48SStefano Zampini graph->xadj = xadj; 16384f1b2e48SStefano Zampini graph->adjncy = adjncy; 16394f1b2e48SStefano Zampini } 16404f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 16414f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 16424f1b2e48SStefano Zampini /* partial clean up */ 16434f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 16444f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 16451cf9b237SStefano Zampini if (A != B) { 16464f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 16474f1b2e48SStefano Zampini } 16484f1b2e48SStefano Zampini 16494f1b2e48SStefano Zampini /* get back data */ 16501cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 16511cf9b237SStefano Zampini if (cc) { 16524f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 16534f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 16544f1b2e48SStefano 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); 16554f1b2e48SStefano Zampini } 16564f1b2e48SStefano Zampini *cc = cc_n; 16571cf9b237SStefano Zampini } 16584f1b2e48SStefano Zampini /* clean up graph */ 16594f1b2e48SStefano Zampini graph->xadj = 0; 16604f1b2e48SStefano Zampini graph->adjncy = 0; 16614f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 16624f1b2e48SStefano Zampini PetscFunctionReturn(0); 16634f1b2e48SStefano Zampini } 16644f1b2e48SStefano Zampini 16654f1b2e48SStefano Zampini #undef __FUNCT__ 16665408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 16675408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 16685408967cSStefano Zampini { 16695408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 16705408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1671dee84bffSStefano Zampini IS dirIS = NULL; 16724f1b2e48SStefano Zampini PetscInt i; 16735408967cSStefano Zampini PetscErrorCode ierr; 16745408967cSStefano Zampini 16755408967cSStefano Zampini PetscFunctionBegin; 1676dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 16775408967cSStefano Zampini if (zerodiag) { 16785408967cSStefano Zampini Mat A; 16795408967cSStefano Zampini Vec vec3_N; 16805408967cSStefano Zampini PetscScalar *vals; 16815408967cSStefano Zampini const PetscInt *idxs; 1682d12d3064SStefano Zampini PetscInt nz,*count; 16835408967cSStefano Zampini 16845408967cSStefano Zampini /* p0 */ 16855408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 16865408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 16875408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 16885408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 16894f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 16905408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 16915408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 16925408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 16935408967cSStefano Zampini /* v_I */ 16945408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 16955408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 16965408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 16975408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 16985408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 16995408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 17005408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 17015408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 17025408967cSStefano Zampini if (dirIS) { 17035408967cSStefano Zampini PetscInt n; 17045408967cSStefano Zampini 17055408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 17065408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 17075408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 17085408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 17095408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 17105408967cSStefano Zampini } 17115408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 17125408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 17135408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 17145408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 1715669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 17165408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 17175408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 17189a962809SStefano 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])); 17195408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 17205408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 1721d12d3064SStefano Zampini 1722d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 1723d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 1724d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 1725d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 1726d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 1727d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 17289a962809SStefano 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]); 1729d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 1730d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 17315408967cSStefano Zampini } 1732dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 17335408967cSStefano Zampini 17345408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 17355408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 17364f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 17375408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 17384f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 17395408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 1740f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1741f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 1742f2a566d8SStefano 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); 1743f2a566d8SStefano Zampini } 17445408967cSStefano Zampini PetscFunctionReturn(0); 17455408967cSStefano Zampini } 17465408967cSStefano Zampini 17475408967cSStefano Zampini #undef __FUNCT__ 1748339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 1749339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 1750339f8db1SStefano Zampini { 1751339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 17524f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 1753b0f5fe93SStefano Zampini PetscInt nz,n; 17541f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 17554f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 1756339f8db1SStefano Zampini PetscErrorCode ierr; 1757339f8db1SStefano Zampini 1758339f8db1SStefano Zampini PetscFunctionBegin; 17599f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 17609f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1761a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 1762a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 1763a3df083aSStefano Zampini } 1764a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1765a3df083aSStefano Zampini pcbddc->benign_n = 0; 17661ae86dd6SStefano Zampini /* if a local info on dofs is present, assumes that the last field represents "pressures" 17674f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 17684f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 17694f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 17701ae86dd6SStefano Zampini since the local Schur complements are already SPD 17714f1b2e48SStefano Zampini */ 17724f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 17734f1b2e48SStefano Zampini have_null = PETSC_TRUE; 177440fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 17754f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 17764f1b2e48SStefano Zampini 17774f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 17784f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 17794f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 17804f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 1781ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 178240fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 178340fa8d13SStefano Zampini if (!sorted) { 178440fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 178540fa8d13SStefano Zampini } 178640fa8d13SStefano Zampini } else { 178740fa8d13SStefano Zampini pressures = NULL; 178840fa8d13SStefano Zampini } 178997d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 179097d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 179127b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 179297d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 1793339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 1794339f8db1SStefano Zampini if (!sorted) { 1795339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 1796339f8db1SStefano Zampini } 1797339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 17984f1b2e48SStefano Zampini if (!nz) { 17994f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 18004f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 180140fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 180240fa8d13SStefano Zampini } 18034f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 18044f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 18054f1b2e48SStefano Zampini zerodiag_subs = NULL; 18064f1b2e48SStefano Zampini pcbddc->benign_n = 0; 18071f4df5f7SStefano Zampini n_interior_dofs = 0; 18081f4df5f7SStefano Zampini interior_dofs = NULL; 18091f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 18101f4df5f7SStefano Zampini PetscInt n,i,j; 18111f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 18121f4df5f7SStefano Zampini PetscInt *iwork; 18131f4df5f7SStefano Zampini 18141f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 18151f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 18161f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 18171f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 181890648384SStefano Zampini for (i=1;i<n_neigh;i++) 18191f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 18201f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 18211f4df5f7SStefano Zampini for (i=0;i<n;i++) 18221f4df5f7SStefano Zampini if (!iwork[i]) 18231f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 18241f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 18251f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 18261f4df5f7SStefano Zampini } 18274f1b2e48SStefano Zampini if (has_null_pressures) { 18284f1b2e48SStefano Zampini IS *subs; 18291f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 18301f4df5f7SStefano Zampini const PetscInt *idxs; 18311f4df5f7SStefano Zampini PetscScalar *array; 18321f4df5f7SStefano Zampini Vec *work; 18331f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 18344f1b2e48SStefano Zampini 18354f1b2e48SStefano Zampini subs = pcbddc->local_subs; 18364f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 18371f4df5f7SStefano 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) */ 18381f4df5f7SStefano Zampini if (pcbddc->current_level) { 18391f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 18401f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 18411f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 18421f4df5f7SStefano Zampini /* work[0] = 1_p */ 18431f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 18441f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 18451f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 18461f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 18471f4df5f7SStefano Zampini /* work[0] = 1_v */ 18481f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 18491f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 18501f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 18511f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 18521f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 18531f4df5f7SStefano Zampini } 18544f1b2e48SStefano Zampini if (nsubs > 1) { 18554f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 18564f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 18574f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 18584f1b2e48SStefano Zampini IS t_zerodiag_subs; 18594f1b2e48SStefano Zampini PetscInt nl; 18604f1b2e48SStefano Zampini 18614f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 18624f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 18634f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 18644f1b2e48SStefano Zampini if (nl) { 18654f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 18664f1b2e48SStefano Zampini 18671f4df5f7SStefano Zampini if (pcbddc->current_level) { 18681f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 18691f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 18701f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 18711f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 18721f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 18731f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 18741f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 18751f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 18761f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 18771f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 18781f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 18791f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 18801f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 18811f4df5f7SStefano Zampini valid = PETSC_FALSE; 18821f4df5f7SStefano Zampini break; 18831f4df5f7SStefano Zampini } 18841f4df5f7SStefano Zampini } 18851f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 18861f4df5f7SStefano Zampini } 18871f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 18881f4df5f7SStefano Zampini IS t_bc; 18891f4df5f7SStefano Zampini PetscInt nzb; 18901f4df5f7SStefano Zampini 18911f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 18921f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 18931f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 18941f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 18951f4df5f7SStefano Zampini } 18961f4df5f7SStefano Zampini if (valid && pressures) { 18974f1b2e48SStefano Zampini IS t_pressure_subs; 18984f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 18994f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 19004f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 19014f1b2e48SStefano Zampini } 19024f1b2e48SStefano Zampini if (valid) { 19034f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 19044f1b2e48SStefano Zampini pcbddc->benign_n++; 19054f1b2e48SStefano Zampini } else { 19064f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 19074f1b2e48SStefano Zampini } 19084f1b2e48SStefano Zampini } 19094f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 19104f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 19114f1b2e48SStefano Zampini } 19124f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 19134f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 19141f4df5f7SStefano Zampini 19151f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 19161f4df5f7SStefano Zampini PetscInt nzb; 19171f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 19181f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 19191f4df5f7SStefano Zampini } 19201f4df5f7SStefano Zampini if (valid && pressures) { 19214f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 19224f1b2e48SStefano Zampini } 19231f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 19241f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 19251f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 19261f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 19271f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 19281f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 19291f4df5f7SStefano Zampini valid = PETSC_FALSE; 19301f4df5f7SStefano Zampini break; 19311f4df5f7SStefano Zampini } 19321f4df5f7SStefano Zampini } 19331f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 19341f4df5f7SStefano Zampini } 19354f1b2e48SStefano Zampini if (valid) { 19364f1b2e48SStefano Zampini pcbddc->benign_n = 1; 1937ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 19384f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 19394f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 19404f1b2e48SStefano Zampini } 19414f1b2e48SStefano Zampini } 19421f4df5f7SStefano Zampini if (pcbddc->current_level) { 19431f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 19444f1b2e48SStefano Zampini } 19451f4df5f7SStefano Zampini } 19461f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 19474f1b2e48SStefano Zampini 19484f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 1949b9b0e38cSStefano Zampini PetscInt n; 1950b9b0e38cSStefano Zampini 19514f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 19524f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 1953b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 1954b9b0e38cSStefano Zampini if (n) { 19554f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 19564f1b2e48SStefano Zampini have_null = PETSC_FALSE; 19574f1b2e48SStefano Zampini } 1958b9b0e38cSStefano Zampini } 19594f1b2e48SStefano Zampini 19604f1b2e48SStefano Zampini /* final check for null pressures */ 19614f1b2e48SStefano Zampini if (zerodiag && pressures) { 19624f1b2e48SStefano Zampini PetscInt nz,np; 19634f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 19644f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 19654f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 19664f1b2e48SStefano Zampini } 19674f1b2e48SStefano Zampini 19684f1b2e48SStefano Zampini if (recompute_zerodiag) { 19694f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 19704f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 19714f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 19724f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 19734f1b2e48SStefano Zampini } else { 19744f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 19754f1b2e48SStefano Zampini 19764f1b2e48SStefano Zampini nzn = 0; 19774f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 19784f1b2e48SStefano Zampini PetscInt ns; 19794f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 19804f1b2e48SStefano Zampini nzn += ns; 19814f1b2e48SStefano Zampini } 19824f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 19834f1b2e48SStefano Zampini nzn = 0; 19844f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 19854f1b2e48SStefano Zampini PetscInt ns,*idxs; 19864f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 19874f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 19884f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 19894f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 19904f1b2e48SStefano Zampini nzn += ns; 19914f1b2e48SStefano Zampini } 19924f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 19934f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 19944f1b2e48SStefano Zampini } 19954f1b2e48SStefano Zampini have_null = PETSC_FALSE; 19964f1b2e48SStefano Zampini } 19974f1b2e48SStefano Zampini 1998669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 1999a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2000a198735bSStefano Zampini Mat A,loc_divudotp; 2001a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2002a198735bSStefano Zampini IS row,col,isused = NULL; 2003a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2004a198735bSStefano Zampini 20051f4df5f7SStefano Zampini if (pressures) { 20061f4df5f7SStefano Zampini isused = pressures; 20071f4df5f7SStefano Zampini } else { 20081f4df5f7SStefano Zampini isused = zerodiag; 20091f4df5f7SStefano Zampini } 2010a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2011669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 20121ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 20131ae86dd6SStefano 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"); 2014a198735bSStefano Zampini n_isused = 0; 2015a198735bSStefano Zampini if (isused) { 2016a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2017a198735bSStefano Zampini } 2018a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2019a198735bSStefano Zampini st = st-n_isused; 20201ae86dd6SStefano Zampini if (n) { 2021a198735bSStefano Zampini const PetscInt *gidxs; 2022a198735bSStefano Zampini 2023a198735bSStefano Zampini ierr = MatGetSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2024a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2025a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2026a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2027a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2028a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 20291ae86dd6SStefano Zampini } else { 2030a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2031a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2032a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2033a198735bSStefano Zampini } 2034a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2035a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2036a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2037a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2038a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2039a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2040a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2041a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2042a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2043a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2044a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2045a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2046a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2047a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 20481ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20491ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20501ae86dd6SStefano Zampini } 2051b3afcdbeSStefano Zampini 2052b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 20534f1b2e48SStefano Zampini if (has_null_pressures) { 20544f1b2e48SStefano Zampini IS zerodiagc; 20554f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 20564f1b2e48SStefano Zampini PetscInt i,s,*nnz; 20574f1b2e48SStefano Zampini 20584f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2059339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 2060339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 2061339f8db1SStefano Zampini /* local change of basis for pressures */ 2062339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 206397d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2064339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2065339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2066339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 20674f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 20684f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 20694f1b2e48SStefano Zampini PetscInt nzs,j; 20704f1b2e48SStefano Zampini 20714f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 20724f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 20734f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 20744f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 20754f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 20764f1b2e48SStefano Zampini } 2077339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2078339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2079339f8db1SStefano Zampini /* set identity on velocities */ 2080339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 2081339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 2082339f8db1SStefano Zampini } 20834f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 20844f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 20859f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 20864f1b2e48SStefano 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); 2087339f8db1SStefano Zampini /* set change on pressures */ 20884f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 20894f1b2e48SStefano Zampini PetscScalar *array; 20904f1b2e48SStefano Zampini PetscInt nzs; 20914f1b2e48SStefano Zampini 20924f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 20934f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 20944f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2095339f8db1SStefano Zampini PetscScalar vals[2]; 2096339f8db1SStefano Zampini PetscInt cols[2]; 2097339f8db1SStefano Zampini 2098339f8db1SStefano Zampini cols[0] = idxs[i]; 20994f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2100339f8db1SStefano Zampini vals[0] = 1.; 2101b0f5fe93SStefano Zampini vals[1] = 1.; 21024f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2103339f8db1SStefano Zampini } 21044f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 21054f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 21064f1b2e48SStefano Zampini array[nzs-1] = 1.; 21074f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 21084f1b2e48SStefano Zampini /* store local idxs for p0 */ 21094f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 21104f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2111339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 21124f1b2e48SStefano Zampini } 2113339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2114339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2115a3df083aSStefano Zampini /* project if needed */ 2116a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 21171dd7afcfSStefano Zampini Mat M; 21181dd7afcfSStefano Zampini 21191dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2120339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 21211dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 21221dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2123a3df083aSStefano Zampini } 21244f1b2e48SStefano Zampini /* store global idxs for p0 */ 21254f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2126339f8db1SStefano Zampini } 2127ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 21284f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 2129b0f5fe93SStefano Zampini 2130b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 2131b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 213227b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 213327b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2134339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2135339f8db1SStefano Zampini PetscFunctionReturn(0); 2136339f8db1SStefano Zampini } 2137339f8db1SStefano Zampini 2138339f8db1SStefano Zampini #undef __FUNCT__ 2139015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 2140015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2141efc2fbd9SStefano Zampini { 2142efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2143de9d7bd0SStefano Zampini PetscScalar *array; 2144efc2fbd9SStefano Zampini PetscErrorCode ierr; 2145efc2fbd9SStefano Zampini 2146efc2fbd9SStefano Zampini PetscFunctionBegin; 2147efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2148efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 21494f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2150efc2fbd9SStefano Zampini } 2151de9d7bd0SStefano Zampini if (get) { 2152efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 21534f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 21544f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2155efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2156de9d7bd0SStefano Zampini } else { 2157de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2158de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2159de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2160de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2161efc2fbd9SStefano Zampini } 2162efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2163efc2fbd9SStefano Zampini } 2164efc2fbd9SStefano Zampini 2165efc2fbd9SStefano Zampini #undef __FUNCT__ 2166c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 2167c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2168c263805aSStefano Zampini { 2169c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2170c263805aSStefano Zampini PetscErrorCode ierr; 2171c263805aSStefano Zampini 2172c263805aSStefano Zampini PetscFunctionBegin; 2173c263805aSStefano Zampini /* TODO: add error checking 2174c263805aSStefano Zampini - avoid nested pop (or push) calls. 2175c263805aSStefano Zampini - cannot push before pop. 21761c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2177c263805aSStefano Zampini */ 21784f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2179efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2180efc2fbd9SStefano Zampini } 2181c263805aSStefano Zampini if (pop) { 2182a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 21834f1b2e48SStefano Zampini IS is_p0; 21844f1b2e48SStefano Zampini MatReuse reuse; 2185c263805aSStefano Zampini 2186c263805aSStefano Zampini /* extract B_0 */ 21874f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 21884f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 21894f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 21904f1b2e48SStefano Zampini } 21914f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 21924f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2193c263805aSStefano Zampini /* remove rows and cols from local problem */ 2194c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 219597d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 21964f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 21974f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2198a3df083aSStefano Zampini } else { 2199a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2200a3df083aSStefano Zampini PetscScalar *vals; 2201a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2202a3df083aSStefano Zampini 2203a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2204a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2205a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 22060b5adadeSStefano Zampini PetscInt *nnz; 2207a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2208a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2209a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2210331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2211331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2212331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2213331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2214331e053bSStefano Zampini } 2215331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2216331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2217331e053bSStefano Zampini } 2218a3df083aSStefano Zampini 2219a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2220a3df083aSStefano Zampini PetscScalar *array; 2221a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2222a3df083aSStefano Zampini 2223a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2224a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2225a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2226a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2227a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2228a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2229a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2230a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2231a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2232a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2233a3df083aSStefano Zampini cum = 0; 2234a3df083aSStefano Zampini for (j=0;j<n;j++) { 223522db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2236a3df083aSStefano Zampini vals[cum] = array[j]; 2237a3df083aSStefano Zampini idxs_ins[cum] = j; 2238a3df083aSStefano Zampini cum++; 2239a3df083aSStefano Zampini } 2240a3df083aSStefano Zampini } 2241a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2242a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2243a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2244a3df083aSStefano Zampini } 2245a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2246a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2247a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2248a3df083aSStefano Zampini } 2249c263805aSStefano Zampini } else { /* push */ 2250a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 22514f1b2e48SStefano Zampini PetscInt i; 22524f1b2e48SStefano Zampini 22534f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 22544f1b2e48SStefano Zampini PetscScalar *B0_vals; 22554f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 22564f1b2e48SStefano Zampini 22574f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 22584f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 22597b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 22604f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 22614f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 22624f1b2e48SStefano Zampini } 2263c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2264c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2265a3df083aSStefano Zampini } else { 2266a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2267a3df083aSStefano Zampini } 2268c263805aSStefano Zampini } 2269c263805aSStefano Zampini PetscFunctionReturn(0); 2270c263805aSStefano Zampini } 2271c263805aSStefano Zampini 2272c263805aSStefano Zampini #undef __FUNCT__ 2273b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 227408122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2275b1b3d7a2SStefano Zampini { 2276b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 227708122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 227808122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 227908122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 228008122e43SStefano Zampini PetscScalar *work,lwork; 228108122e43SStefano Zampini PetscScalar *St,*S,*eigv; 228208122e43SStefano Zampini PetscScalar *Sarray,*Starray; 228308122e43SStefano Zampini PetscReal *eigs,thresh; 22841b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2285f6f667cfSStefano Zampini PetscBool allocated_S_St; 228608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 228708122e43SStefano Zampini PetscReal *rwork; 228808122e43SStefano Zampini #endif 2289b1b3d7a2SStefano Zampini PetscErrorCode ierr; 2290b1b3d7a2SStefano Zampini 2291b1b3d7a2SStefano Zampini PetscFunctionBegin; 2292b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 2293af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 2294af25d912SStefano 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); 229506a4e24aSStefano Zampini 2296fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2297fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2298fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2299fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 23001575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2301fd14bc51SStefano Zampini } 2302fd14bc51SStefano Zampini 2303e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 2304e496cd5dSStefano 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); 2305e496cd5dSStefano Zampini } 2306e496cd5dSStefano Zampini 230708122e43SStefano Zampini /* max size of subsets */ 230808122e43SStefano Zampini mss = 0; 230908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 231008122e43SStefano Zampini PetscInt subset_size; 2311862806e4SStefano Zampini 231208122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 231308122e43SStefano Zampini mss = PetscMax(mss,subset_size); 231408122e43SStefano Zampini } 231508122e43SStefano Zampini 231608122e43SStefano Zampini /* min/max and threshold */ 231708122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 2318f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 231908122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 2320f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 2321f6f667cfSStefano Zampini if (nmin) { 2322f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 2323f6f667cfSStefano Zampini } 232408122e43SStefano Zampini 232508122e43SStefano Zampini /* allocate lapack workspace */ 232608122e43SStefano Zampini cum = cum2 = 0; 232708122e43SStefano Zampini maxneigs = 0; 232808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 232908122e43SStefano Zampini PetscInt n,subset_size; 2330f6f667cfSStefano Zampini 233108122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 233208122e43SStefano Zampini n = PetscMin(subset_size,nmax); 23339162d606SStefano Zampini cum += subset_size; 23349162d606SStefano Zampini cum2 += subset_size*n; 233508122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 233608122e43SStefano Zampini } 233708122e43SStefano Zampini if (mss) { 23389ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 233908122e43SStefano Zampini PetscBLASInt B_itype = 1; 234008122e43SStefano Zampini PetscBLASInt B_N = mss; 23414c6709b3SStefano Zampini PetscReal zero = 0.0; 23424c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 234308122e43SStefano Zampini 234408122e43SStefano Zampini B_lwork = -1; 234508122e43SStefano Zampini S = NULL; 234608122e43SStefano Zampini St = NULL; 2347a58a30b4SStefano Zampini eigs = NULL; 2348a58a30b4SStefano Zampini eigv = NULL; 2349a58a30b4SStefano Zampini B_iwork = NULL; 2350a58a30b4SStefano Zampini B_ifail = NULL; 2351d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2352d1710679SStefano Zampini rwork = NULL; 2353d1710679SStefano Zampini #endif 23548bec7fa6SStefano Zampini thresh = 1.0; 235508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 235608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 235708122e43SStefano 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)); 235808122e43SStefano Zampini #else 235908122e43SStefano 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)); 236008122e43SStefano Zampini #endif 236108122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 236208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 236308122e43SStefano Zampini } else { 236408122e43SStefano Zampini /* TODO */ 236508122e43SStefano Zampini } 236608122e43SStefano Zampini } else { 236708122e43SStefano Zampini lwork = 0; 236808122e43SStefano Zampini } 236908122e43SStefano Zampini 237008122e43SStefano Zampini nv = 0; 2371d62866d3SStefano 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) */ 2372d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 237308122e43SStefano Zampini } 23744c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 2375f6f667cfSStefano Zampini if (allocated_S_St) { 2376f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 2377f6f667cfSStefano Zampini } 2378f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 237908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 238008122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 238108122e43SStefano Zampini #endif 23829162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 23839162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 23849162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 238508122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 23869162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 238708122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 238808122e43SStefano Zampini 238908122e43SStefano Zampini maxneigs = 0; 239072b8c272SStefano Zampini cum = cumarray = 0; 23919162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 23929162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 2393d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 239408122e43SStefano Zampini const PetscInt *idxs; 239508122e43SStefano Zampini 2396d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 239708122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 239808122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 239908122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 240008122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 24019162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 24029162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 240308122e43SStefano Zampini } 2404d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 240508122e43SStefano Zampini } 240608122e43SStefano Zampini 240708122e43SStefano Zampini if (mss) { /* multilevel */ 240808122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 240908122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 241008122e43SStefano Zampini } 241108122e43SStefano Zampini 2412ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 241308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 241408122e43SStefano Zampini const PetscInt *idxs; 24159d54b7f4SStefano Zampini PetscReal upper,lower; 2416862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 241708122e43SStefano Zampini PetscBLASInt B_N; 2418aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 241908122e43SStefano Zampini 24209d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 24219d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 24229d54b7f4SStefano Zampini lower = thresh; 24239d54b7f4SStefano Zampini } else { 24249d54b7f4SStefano Zampini upper = 1./thresh; 24259d54b7f4SStefano Zampini lower = 0.; 24269d54b7f4SStefano Zampini } 2427862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 2428ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 2429f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 2430f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 24319ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 2432aff50787SStefano Zampini PetscInt j,k; 2433aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 2434aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 2435aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 243608122e43SStefano Zampini } 243708122e43SStefano Zampini for (j=0;j<subset_size;j++) { 2438aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 2439aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 2440aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 2441aff50787SStefano Zampini } 244208122e43SStefano Zampini } 244308122e43SStefano Zampini } else { 244408122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 244508122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 244608122e43SStefano Zampini } 24478bec7fa6SStefano Zampini } else { 2448f6f667cfSStefano Zampini S = Sarray + cumarray; 2449f6f667cfSStefano Zampini St = Starray + cumarray; 24508bec7fa6SStefano Zampini } 2451aff50787SStefano Zampini /* see if we can save some work */ 2452b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 2453aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 2454aff50787SStefano Zampini } 2455aff50787SStefano Zampini 2456b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 2457aff50787SStefano Zampini B_neigs = 0; 2458aff50787SStefano Zampini } else { 24599ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 246008122e43SStefano Zampini PetscBLASInt B_itype = 1; 2461f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 24624c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 24639552c7c7SStefano Zampini PetscInt nmin_s; 2464b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 246508122e43SStefano Zampini 2466fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 24678bec7fa6SStefano 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]]); 2468fd14bc51SStefano Zampini } 2469d16cbb6bSStefano Zampini 2470b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 2471b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 2472b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 2473b7ab4a40SStefano Zampini } 2474b7ab4a40SStefano Zampini 247508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2476b7ab4a40SStefano Zampini if (compute_range) { 2477d16cbb6bSStefano Zampini 2478d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 247908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 24809d54b7f4SStefano 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)); 248108122e43SStefano Zampini #else 24829d54b7f4SStefano 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)); 248308122e43SStefano Zampini #endif 2484b7ab4a40SStefano Zampini } else if (!same_data) { 2485d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 2486d16cbb6bSStefano Zampini B_IL = 1; 2487d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 24889d54b7f4SStefano 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)); 2489d16cbb6bSStefano Zampini #else 24909d54b7f4SStefano 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)); 2491d16cbb6bSStefano Zampini #endif 2492b7ab4a40SStefano Zampini } else { /* same_data is true, so get the adaptive function requested by the user */ 2493b7ab4a40SStefano Zampini PetscInt k; 2494b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 2495b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 2496b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 2497b7ab4a40SStefano Zampini nmin = nmax; 2498b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 2499b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 2500b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 2501b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 2502b7ab4a40SStefano Zampini } 2503d16cbb6bSStefano Zampini } 250408122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 250508122e43SStefano Zampini if (B_ierr) { 25066c4ed002SBarry 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); 25076c4ed002SBarry 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); 25086c4ed002SBarry 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); 250908122e43SStefano Zampini } 251008122e43SStefano Zampini 251108122e43SStefano Zampini if (B_neigs > nmax) { 2512fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2513fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 2514fd14bc51SStefano Zampini } 25159d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 251608122e43SStefano Zampini B_neigs = nmax; 251708122e43SStefano Zampini } 251808122e43SStefano Zampini 25199552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 25209552c7c7SStefano Zampini if (B_neigs < nmin_s) { 252108122e43SStefano Zampini PetscBLASInt B_neigs2; 252208122e43SStefano Zampini 25239d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2524f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 25259d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 25269d54b7f4SStefano Zampini } else { 25279d54b7f4SStefano Zampini B_IL = B_neigs + 1; 25289d54b7f4SStefano Zampini B_IU = nmin_s; 25299d54b7f4SStefano Zampini } 2530fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2531fd14bc51SStefano 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); 2532fd14bc51SStefano Zampini } 25339ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 25341ae86dd6SStefano Zampini PetscInt j,k; 253508122e43SStefano Zampini for (j=0;j<subset_size;j++) { 25361ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 25371ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 25381ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 253908122e43SStefano Zampini } 254008122e43SStefano Zampini } 254108122e43SStefano Zampini } else { 254208122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 254308122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 254408122e43SStefano Zampini } 254508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 254608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 25479d54b7f4SStefano 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)); 254808122e43SStefano Zampini #else 25499d54b7f4SStefano 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)); 255008122e43SStefano Zampini #endif 255108122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 255208122e43SStefano Zampini B_neigs += B_neigs2; 255308122e43SStefano Zampini } 255408122e43SStefano Zampini if (B_ierr) { 25556c4ed002SBarry 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); 25566c4ed002SBarry 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); 25576c4ed002SBarry 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); 255808122e43SStefano Zampini } 2559fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2560ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 256108122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 256208122e43SStefano Zampini if (eigs[j] == 0.0) { 2563ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 256408122e43SStefano Zampini } else { 25659d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2566ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 25679d54b7f4SStefano Zampini } else { 25689d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 25699d54b7f4SStefano Zampini } 2570fd14bc51SStefano Zampini } 257108122e43SStefano Zampini } 257208122e43SStefano Zampini } 257308122e43SStefano Zampini } else { 257408122e43SStefano Zampini /* TODO */ 257508122e43SStefano Zampini } 2576aff50787SStefano Zampini } 25776c3e6151SStefano Zampini /* change the basis back to the original one */ 25786c3e6151SStefano Zampini if (sub_schurs->change) { 257972b8c272SStefano Zampini Mat change,phi,phit; 25806c3e6151SStefano Zampini 25816c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 25826c3e6151SStefano Zampini PetscInt ii; 25836c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 25846c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 25856c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 2586684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2587684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 2588684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 2589684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2590684229deSStefano Zampini #else 25916c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 2592684229deSStefano Zampini #endif 25936c3e6151SStefano Zampini } 25946c3e6151SStefano Zampini } 25956c3e6151SStefano Zampini } 259672b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 25976c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 259872b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 25996c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 26006c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 26016c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 26026c3e6151SStefano Zampini } 26038bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 26048bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 26059162d606SStefano Zampini if (B_neigs) { 26069162d606SStefano 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); 2607fd14bc51SStefano Zampini 2608fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 26099552c7c7SStefano Zampini PetscInt ii; 26109552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 2611ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 26129552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 2613ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2614ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2615ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2616ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2617ac47001eSStefano Zampini #else 2618ac47001eSStefano 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); 2619ac47001eSStefano Zampini #endif 26209552c7c7SStefano Zampini } 26219552c7c7SStefano Zampini } 2622fd14bc51SStefano Zampini } 26239162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 26249162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 26259162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 26269162d606SStefano Zampini cum++; 262708122e43SStefano Zampini } 262808122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 262908122e43SStefano Zampini /* shift for next computation */ 263008122e43SStefano Zampini cumarray += subset_size*subset_size; 263108122e43SStefano Zampini } 2632fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2633fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2634fd14bc51SStefano Zampini } 263508122e43SStefano Zampini 263608122e43SStefano Zampini if (mss) { 263708122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 263808122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 2639f6f667cfSStefano Zampini /* destroy matrices (junk) */ 2640f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 2641f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 264208122e43SStefano Zampini } 2643f6f667cfSStefano Zampini if (allocated_S_St) { 2644f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 2645f6f667cfSStefano Zampini } 2646f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 264708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 264808122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 264908122e43SStefano Zampini #endif 265008122e43SStefano Zampini if (pcbddc->dbg_flag) { 26511b968477SStefano Zampini PetscInt maxneigs_r; 2652b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 26539b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 265408122e43SStefano Zampini } 265508122e43SStefano Zampini PetscFunctionReturn(0); 265608122e43SStefano Zampini } 2657b1b3d7a2SStefano Zampini 2658674ae819SStefano Zampini #undef __FUNCT__ 2659c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 2660c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 2661c8587f34SStefano Zampini { 26628629588bSStefano Zampini PetscScalar *coarse_submat_vals; 2663c8587f34SStefano Zampini PetscErrorCode ierr; 2664c8587f34SStefano Zampini 2665c8587f34SStefano Zampini PetscFunctionBegin; 2666f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 26675e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 2668c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 2669c8587f34SStefano Zampini 2670684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 26710fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 2672684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 2673c8587f34SStefano Zampini 26748629588bSStefano Zampini /* 26758629588bSStefano Zampini Setup local correction and local part of coarse basis. 26768629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 26778629588bSStefano Zampini */ 267847f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 26798629588bSStefano Zampini 26808629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 26818629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 26828629588bSStefano Zampini 26838629588bSStefano Zampini /* free */ 26848629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 2685c8587f34SStefano Zampini PetscFunctionReturn(0); 2686c8587f34SStefano Zampini } 2687c8587f34SStefano Zampini 2688c8587f34SStefano Zampini #undef __FUNCT__ 2689674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 2690674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 2691674ae819SStefano Zampini { 2692674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2693674ae819SStefano Zampini PetscErrorCode ierr; 2694674ae819SStefano Zampini 2695674ae819SStefano Zampini PetscFunctionBegin; 2696674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 269730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 2698674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 2699785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 2700674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 2701f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2702f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2703785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 270463602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 270563602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 2706674ae819SStefano Zampini PetscFunctionReturn(0); 2707674ae819SStefano Zampini } 2708674ae819SStefano Zampini 2709674ae819SStefano Zampini #undef __FUNCT__ 2710674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 2711674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 2712674ae819SStefano Zampini { 2713674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 27144f1b2e48SStefano Zampini PetscInt i; 2715674ae819SStefano Zampini PetscErrorCode ierr; 2716674ae819SStefano Zampini 2717674ae819SStefano Zampini PetscFunctionBegin; 2718a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 2719b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2720674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 272116909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 27221dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 2723674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2724669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 2725fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 2726a13144ffSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 2727674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 272871582508SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 27294f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 27304f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 27314f1b2e48SStefano Zampini } 27324f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 2733b334f244SStefano Zampini if (pcbddc->sub_schurs) { 2734b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 2735b334f244SStefano Zampini } 2736674ae819SStefano Zampini PetscFunctionReturn(0); 2737674ae819SStefano Zampini } 2738674ae819SStefano Zampini 2739674ae819SStefano Zampini #undef __FUNCT__ 2740674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 2741674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 2742674ae819SStefano Zampini { 2743674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2744674ae819SStefano Zampini PetscErrorCode ierr; 2745674ae819SStefano Zampini 2746674ae819SStefano Zampini PetscFunctionBegin; 2747674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 274858da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 2749ca92afb2SStefano Zampini PetscScalar *array; 275006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 275106656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 275258da7f69SStefano Zampini } 2753674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 2754674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 275515aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 275615aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 2757674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 2758674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 2759674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 276006656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 2761674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 2762674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 27638ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2764674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2765674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2766674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 2767f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 2768f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 2769f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2770f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2771727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 27720e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2773f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 277470cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 277581d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 27760369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 27771dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 27784f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 27798b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 2780ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 2781ca92afb2SStefano Zampini PetscInt i; 2782ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2783ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2784ca92afb2SStefano Zampini } 2785ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2786ca92afb2SStefano Zampini } 27874f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 2788674ae819SStefano Zampini PetscFunctionReturn(0); 2789674ae819SStefano Zampini } 2790674ae819SStefano Zampini 2791674ae819SStefano Zampini #undef __FUNCT__ 2792f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 2793f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 27946bfb1811SStefano Zampini { 27956bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 27966bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 27976bfb1811SStefano Zampini VecType impVecType; 27984f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 27996bfb1811SStefano Zampini PetscErrorCode ierr; 28006bfb1811SStefano Zampini 28016bfb1811SStefano Zampini PetscFunctionBegin; 28026c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 2803e7b262bdSStefano Zampini /* get sizes */ 28044f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 2805b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 28066bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 2807e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 2808e7b262bdSStefano Zampini /* R nodes */ 2809e7b262bdSStefano Zampini old_size = -1; 2810e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 2811e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 2812e7b262bdSStefano Zampini } 2813e7b262bdSStefano Zampini if (n_R != old_size) { 2814e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 2815e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 28166bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 28176bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 28186bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 28196bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 2820e7b262bdSStefano Zampini } 2821e7b262bdSStefano Zampini /* local primal dofs */ 2822e7b262bdSStefano Zampini old_size = -1; 2823e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 2824e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 2825e7b262bdSStefano Zampini } 2826e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 2827e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 282883b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 2829e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 28306bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 2831e7b262bdSStefano Zampini } 2832e7b262bdSStefano Zampini /* local explicit constraints */ 2833e7b262bdSStefano Zampini old_size = -1; 2834e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 2835e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 2836e7b262bdSStefano Zampini } 2837e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 2838e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 283983b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 284083b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 284183b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 284283b7ccabSStefano Zampini } 28436bfb1811SStefano Zampini PetscFunctionReturn(0); 28446bfb1811SStefano Zampini } 28456bfb1811SStefano Zampini 28466bfb1811SStefano Zampini #undef __FUNCT__ 284747f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 284847f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 284988ebb749SStefano Zampini { 285025084f0cSStefano Zampini PetscErrorCode ierr; 285125084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 285288ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 285388ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2854d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 285525084f0cSStefano Zampini /* submatrices of local problem */ 285680677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 285706656605SStefano Zampini /* submatrices of local coarse problem */ 285806656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 285925084f0cSStefano Zampini /* working matrices */ 286006656605SStefano Zampini Mat C_CR; 286125084f0cSStefano Zampini /* additional working stuff */ 286206656605SStefano Zampini PC pc_R; 28634f1b2e48SStefano Zampini Mat F; 28645cbda25cSStefano Zampini Vec dummy_vec; 2865a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 286625084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 286706656605SStefano Zampini PetscScalar *work; 286806656605SStefano Zampini PetscInt *idx_V_B; 2869ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 287006656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 2871ffd830a3SStefano Zampini 287225084f0cSStefano Zampini /* some shortcuts to scalars */ 287306656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 287488ebb749SStefano Zampini 287588ebb749SStefano Zampini PetscFunctionBegin; 28769a962809SStefano 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"); 2877ffd830a3SStefano Zampini 2878ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 2879b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 28804f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 2881b371cd4fSStefano Zampini n_B = pcis->n_B; 2882b371cd4fSStefano Zampini n_D = pcis->n - n_B; 288388ebb749SStefano Zampini n_R = pcis->n - n_vertices; 288488ebb749SStefano Zampini 288588ebb749SStefano Zampini /* vertices in boundary numbering */ 2886785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 28870e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 28886c4ed002SBarry 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); 288988ebb749SStefano Zampini 289006656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 2891019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 289206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 289306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 289406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 289506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 289606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 289706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 289806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 289906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 290006656605SStefano Zampini 290106656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 290206656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 290306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 290406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 290506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 2906ffd830a3SStefano Zampini lda_rhs = n_R; 2907a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 290806656605SStefano Zampini if (isLU || isILU || isCHOL) { 290906656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 2910b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 2911df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2912d62866d3SStefano Zampini MatFactorType type; 2913d62866d3SStefano Zampini 2914df4d28bfSStefano Zampini F = reuse_solver->F; 29156816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 2916d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 2917ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 291822db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 291906656605SStefano Zampini } else { 292006656605SStefano Zampini F = NULL; 292106656605SStefano Zampini } 292206656605SStefano Zampini 2923ffd830a3SStefano Zampini /* allocate workspace */ 2924ffd830a3SStefano Zampini n = 0; 2925ffd830a3SStefano Zampini if (n_constraints) { 2926ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 2927ffd830a3SStefano Zampini } 2928ffd830a3SStefano Zampini if (n_vertices) { 2929ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 2930ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 2931ffd830a3SStefano Zampini } 2932ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 2933ffd830a3SStefano Zampini 29345cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 29355cbda25cSStefano Zampini dummy_vec = NULL; 29365cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 29375cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 29385cbda25cSStefano Zampini } 29395cbda25cSStefano Zampini 294088ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 294188ebb749SStefano Zampini if (n_constraints) { 294272b8c272SStefano Zampini Mat M1,M2,M3,C_B; 294306656605SStefano Zampini IS is_aux; 294480677318SStefano Zampini PetscScalar *array,*array2; 294506656605SStefano Zampini 2946f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 294780677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 294888ebb749SStefano Zampini 294925084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 295025084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 29518ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 295272b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 295388ebb749SStefano Zampini 295480677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 295580677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 2956ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 295788ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 295806656605SStefano Zampini const PetscScalar *row_cmat_values; 295906656605SStefano Zampini const PetscInt *row_cmat_indices; 296006656605SStefano Zampini PetscInt size_of_constraint,j; 296188ebb749SStefano Zampini 296206656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 296306656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 2964ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 296506656605SStefano Zampini } 296606656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 296706656605SStefano Zampini } 2968ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 296906656605SStefano Zampini if (F) { 297006656605SStefano Zampini Mat B; 297106656605SStefano Zampini 2972ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 2973a3df083aSStefano Zampini if (need_benign_correction) { 2974df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2975a3df083aSStefano Zampini 297672b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 297772b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2978a3df083aSStefano Zampini } 297980677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 2980a3df083aSStefano Zampini if (need_benign_correction) { 2981a3df083aSStefano Zampini PetscScalar *marr; 2982df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2983a3df083aSStefano Zampini 2984a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 29855cbda25cSStefano Zampini if (lda_rhs != n_R) { 29865cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 29875cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 29885cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 29895cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 29905cbda25cSStefano Zampini } 29915cbda25cSStefano Zampini } else { 2992a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 2993a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 29945cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 2995a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2996a3df083aSStefano Zampini } 29975cbda25cSStefano Zampini } 2998a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 2999a3df083aSStefano Zampini } 300006656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 300106656605SStefano Zampini } else { 300280677318SStefano Zampini PetscScalar *marr; 300380677318SStefano Zampini 300480677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 300506656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3006ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3007ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 300806656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 300906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 301006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 301106656605SStefano Zampini } 301280677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 301306656605SStefano Zampini } 301480677318SStefano Zampini if (!pcbddc->switch_static) { 301580677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 301680677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 301780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 301880677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3019ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 302080677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 302180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 302280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 302380677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 302480677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 302580677318SStefano Zampini } 302680677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 302780677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 302872b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 302980677318SStefano Zampini } else { 3030ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3031ffd830a3SStefano Zampini IS dummy; 3032ffd830a3SStefano Zampini 3033ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 303472b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3035ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3036ffd830a3SStefano Zampini } else { 303780677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 303880677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3039ffd830a3SStefano Zampini } 304025084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 304180677318SStefano Zampini } 304280677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 304380677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 304480677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 304506656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 304606656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 304780677318SStefano Zampini if (isCHOL) { 304880677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 304980677318SStefano Zampini } else { 305025084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 305180677318SStefano Zampini } 305280677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 305306656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 305425084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 305525084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 305625084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 305780677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 305872b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 305972b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 306006656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 306106656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 3062f4ddd8eeSStefano Zampini } 3063fc227af8SStefano Zampini 3064fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 306588ebb749SStefano Zampini if (n_vertices) { 306606656605SStefano Zampini IS is_aux; 30673a50541eSStefano Zampini 3068b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 30696816873aSStefano Zampini IS tis; 30706816873aSStefano Zampini 30716816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 30726816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 30736816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 30746816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 30756816873aSStefano Zampini } else { 30763a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 30776816873aSStefano Zampini } 30789577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 30799577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 308004708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 308125084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 308288ebb749SStefano Zampini } 308388ebb749SStefano Zampini 308488ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 3085f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 308606656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 308706656605SStefano Zampini if (pcbddc->coarse_phi_D) { 308806656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 308906656605SStefano Zampini } 3090f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 309106656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 309206656605SStefano Zampini PetscScalar *marray; 309306656605SStefano Zampini 309406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 309506656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 3096f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3097f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3098f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3099f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3100f4ddd8eeSStefano Zampini } 3101f4ddd8eeSStefano Zampini } 310206656605SStefano Zampini 3103f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 310406656605SStefano Zampini PetscScalar *marray; 310588ebb749SStefano Zampini 310606656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 31078eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 310806656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 310988ebb749SStefano Zampini } 31103301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 311106656605SStefano Zampini n *= 2; 311288ebb749SStefano Zampini } 311306656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 311406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 311506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 31168eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 311706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 311806656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 311988ebb749SStefano Zampini } 31203301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 312106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 31228eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 312306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 312406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 312588ebb749SStefano Zampini } 312688ebb749SStefano Zampini } else { 3127c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 3128c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 31291b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3130c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 3131c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 3132c0553b1fSStefano Zampini } 313388ebb749SStefano Zampini } 313406656605SStefano Zampini } 3135019a44ceSStefano Zampini 313606656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 31374f1b2e48SStefano Zampini p0_lidx_I = NULL; 31384f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 3139d12edf2fSStefano Zampini const PetscInt *idxs; 3140d12edf2fSStefano Zampini 3141d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 31424f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 31434f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 31444f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 31454f1b2e48SStefano Zampini } 3146d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 3147d12edf2fSStefano Zampini } 3148d16cbb6bSStefano Zampini 314906656605SStefano Zampini /* vertices */ 315006656605SStefano Zampini if (n_vertices) { 315116f15bc4SStefano Zampini 3152af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 315304708bb6SStefano Zampini 315416f15bc4SStefano Zampini if (n_R) { 315514393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 315606656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 315716f15bc4SStefano Zampini PetscScalar *x,*y; 315804708bb6SStefano Zampini PetscBool isseqaij; 315906656605SStefano Zampini 316021eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 316114393ed6SStefano Zampini if (need_benign_correction) { 316214393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 316314393ed6SStefano Zampini IS is_p0; 316414393ed6SStefano Zampini PetscInt *idxs_p0,n; 316514393ed6SStefano Zampini 316614393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 316714393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 316814393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 3169af25d912SStefano 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); 317014393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 317114393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 317214393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 317314393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 317414393ed6SStefano Zampini } 317514393ed6SStefano Zampini 3176ffd830a3SStefano Zampini if (lda_rhs == n_R) { 3177af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3178ffd830a3SStefano Zampini } else { 3179ca92afb2SStefano Zampini PetscScalar *av,*array; 3180ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 3181ca92afb2SStefano Zampini PetscInt n; 3182ca92afb2SStefano Zampini PetscBool flg_row; 3183ffd830a3SStefano Zampini 3184ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 3185ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 31869d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3187ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3188ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 3189ca92afb2SStefano Zampini for (i=0;i<n;i++) { 3190ca92afb2SStefano Zampini PetscInt j; 3191ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 3192ffd830a3SStefano Zampini } 3193ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3194ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3195ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 3196ffd830a3SStefano Zampini } 3197ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3198a3df083aSStefano Zampini if (need_benign_correction) { 3199df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3200a3df083aSStefano Zampini PetscScalar *marr; 3201a3df083aSStefano Zampini 3202a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 320314393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 320414393ed6SStefano Zampini 320514393ed6SStefano Zampini | 0 0 0 | (V) 320614393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 320714393ed6SStefano Zampini | 0 0 -1 | (p0) 320814393ed6SStefano Zampini 320914393ed6SStefano Zampini */ 3210df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 321114393ed6SStefano Zampini const PetscScalar *vals; 321214393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 321314393ed6SStefano Zampini PetscInt n,j,nz; 321414393ed6SStefano Zampini 3215df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3216df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 321714393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 321814393ed6SStefano Zampini for (j=0;j<n;j++) { 321914393ed6SStefano Zampini PetscScalar val = vals[j]; 322014393ed6SStefano Zampini PetscInt k,col = idxs[j]; 322114393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 322214393ed6SStefano Zampini } 322314393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3224df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 322514393ed6SStefano Zampini } 322672b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 322772b8c272SStefano Zampini } 322872b8c272SStefano Zampini if (F) { 322914393ed6SStefano Zampini /* need to correct the rhs */ 323072b8c272SStefano Zampini if (need_benign_correction) { 323172b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 323272b8c272SStefano Zampini PetscScalar *marr; 323372b8c272SStefano Zampini 323472b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 32355cbda25cSStefano Zampini if (lda_rhs != n_R) { 32365cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 32375cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 32385cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 32395cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 32405cbda25cSStefano Zampini } 32415cbda25cSStefano Zampini } else { 3242a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3243a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 32445cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3245a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3246a3df083aSStefano Zampini } 32475cbda25cSStefano Zampini } 3248a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 3249a3df083aSStefano Zampini } 325006656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 325114393ed6SStefano Zampini /* need to correct the solution */ 3252a3df083aSStefano Zampini if (need_benign_correction) { 3253df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3254a3df083aSStefano Zampini PetscScalar *marr; 3255a3df083aSStefano Zampini 3256a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 32575cbda25cSStefano Zampini if (lda_rhs != n_R) { 32585cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 32595cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 32605cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 32615cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 32625cbda25cSStefano Zampini } 32635cbda25cSStefano Zampini } else { 3264a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3265a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 32665cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3267a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3268a3df083aSStefano Zampini } 32695cbda25cSStefano Zampini } 3270a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 3271a3df083aSStefano Zampini } 327206656605SStefano Zampini } else { 327306656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 327406656605SStefano Zampini for (i=0;i<n_vertices;i++) { 3275ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 3276ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 327706656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 327806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 327906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 328006656605SStefano Zampini } 328106656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 328206656605SStefano Zampini } 328380677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3284ffd830a3SStefano Zampini /* S_VV and S_CV */ 328506656605SStefano Zampini if (n_constraints) { 328606656605SStefano Zampini Mat B; 328780677318SStefano Zampini 3288ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 328980677318SStefano Zampini for (i=0;i<n_vertices;i++) { 3290ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3291ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 329280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 329380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 329480677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 329580677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 329680677318SStefano Zampini } 3297ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 329880677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 329980677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 3300ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 330180677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 330206656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 3303ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 3304ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 330506656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 330606656605SStefano Zampini } 330704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 330804708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 3309511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 331004708bb6SStefano Zampini } 3311ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3312ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 3313ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3314ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 3315ffd830a3SStefano Zampini } 331606656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 331714393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 331814393ed6SStefano Zampini if (need_benign_correction) { 3319df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 332014393ed6SStefano Zampini PetscScalar *marr,*sums; 332114393ed6SStefano Zampini 332214393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 332314393ed6SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr); 3324df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 332514393ed6SStefano Zampini const PetscScalar *vals; 332614393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 332714393ed6SStefano Zampini PetscInt n,j,nz; 332814393ed6SStefano Zampini 3329df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3330df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 333114393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 333214393ed6SStefano Zampini PetscInt k; 333314393ed6SStefano Zampini sums[j] = 0.; 333414393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 333514393ed6SStefano Zampini } 333614393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 333714393ed6SStefano Zampini for (j=0;j<n;j++) { 333814393ed6SStefano Zampini PetscScalar val = vals[j]; 333914393ed6SStefano Zampini PetscInt k; 334014393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 334114393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 334214393ed6SStefano Zampini } 334314393ed6SStefano Zampini } 334414393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3345df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 334614393ed6SStefano Zampini } 334714393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 334814393ed6SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr); 334914393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 335014393ed6SStefano Zampini } 335180677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 335206656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 335306656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 335406656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 335506656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 335606656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 335706656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 335806656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3359d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 3360019a44ceSStefano Zampini } else { 3361d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3362d16cbb6bSStefano Zampini } 336321eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 3364d16cbb6bSStefano Zampini 336506656605SStefano Zampini /* coarse basis functions */ 336606656605SStefano Zampini for (i=0;i<n_vertices;i++) { 336716f15bc4SStefano Zampini PetscScalar *y; 336816f15bc4SStefano Zampini 3369ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 337006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 337106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 337206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 337306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 337406656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 337506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 337606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 337706656605SStefano Zampini 337806656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 33794f1b2e48SStefano Zampini PetscInt j; 33804f1b2e48SStefano Zampini 338106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 338206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 338306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 338406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 338506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 33864f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 338706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 338806656605SStefano Zampini } 338906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 339006656605SStefano Zampini } 339104708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 339204708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 339306656605SStefano Zampini } 33945cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 339506656605SStefano Zampini 339606656605SStefano Zampini if (n_constraints) { 339706656605SStefano Zampini Mat B; 339806656605SStefano Zampini 3399ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 340006656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 340180677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 340206656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 340306656605SStefano Zampini if (n_vertices) { 340480677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 340580677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 340680677318SStefano Zampini } else { 340780677318SStefano Zampini Mat S_VCt; 340880677318SStefano Zampini 3409ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3410ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 341172b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 3412ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 3413ffd830a3SStefano Zampini } 341480677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 341580677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 341680677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 341780677318SStefano Zampini } 341806656605SStefano Zampini } 341906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 342006656605SStefano Zampini /* coarse basis functions */ 342106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 342206656605SStefano Zampini PetscScalar *y; 342306656605SStefano Zampini 3424ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 342506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 342606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 342706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 342806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 342906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 343006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 343106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 34324f1b2e48SStefano Zampini PetscInt j; 34334f1b2e48SStefano Zampini 343406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 343506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 343606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 343706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 343806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 34394f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 344006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 344106656605SStefano Zampini } 344206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 344306656605SStefano Zampini } 344406656605SStefano Zampini } 344580677318SStefano Zampini if (n_constraints) { 344680677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 344780677318SStefano Zampini } 34484f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 344972b8c272SStefano Zampini 345072b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 345172b8c272SStefano Zampini if (pcbddc->benign_n) { 345272b8c272SStefano Zampini Mat B0_B,B0_BPHI; 345372b8c272SStefano Zampini IS is_dummy; 345472b8c272SStefano Zampini PetscScalar *data; 345572b8c272SStefano Zampini PetscInt j; 345672b8c272SStefano Zampini 345772b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 345872b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 345972b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 346072b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 346186c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 346272b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 346372b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 346472b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 346572b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 346672b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 346772b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 346872b8c272SStefano Zampini } 346972b8c272SStefano Zampini } 347072b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 347172b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 347272b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 347372b8c272SStefano Zampini } 3474019a44ceSStefano Zampini 347506656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 34763301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3477ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 3478ffd830a3SStefano Zampini PetscScalar *marray; 347906656605SStefano Zampini 348006656605SStefano Zampini if (n_constraints) { 3481ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 348206656605SStefano Zampini 3483af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 348406656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 3485ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 348616f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 348706656605SStefano Zampini if (n_vertices) { 3488ffd830a3SStefano Zampini Mat S_VCT; 348906656605SStefano Zampini 349006656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 3491ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 349216f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 349306656605SStefano Zampini } 3494ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 34955b782168SStefano Zampini } else { 34965b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 349706656605SStefano Zampini } 349816f15bc4SStefano Zampini if (n_vertices && n_R) { 3499ffd830a3SStefano Zampini PetscScalar *av,*marray; 3500ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 3501ffd830a3SStefano Zampini PetscInt n; 3502ffd830a3SStefano Zampini PetscBool flg_row; 350306656605SStefano Zampini 3504ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 3505af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3506ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3507ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 3508ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3509ffd830a3SStefano Zampini for (i=0;i<n;i++) { 3510ffd830a3SStefano Zampini PetscInt j; 3511ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 3512ffd830a3SStefano Zampini } 3513ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 3514ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3515ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 351606656605SStefano Zampini } 351706656605SStefano Zampini 3518ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 3519ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3520ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 3521ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 3522ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 352306656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 352406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 352506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 352606656605SStefano Zampini } 3527ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 35285b782168SStefano Zampini if (B_C) { 3529ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 3530ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 3531ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 3532ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 3533ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 3534ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3535ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 353606656605SStefano Zampini } 3537ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 35385b782168SStefano Zampini } 353906656605SStefano Zampini /* coarse basis functions */ 354006656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 354106656605SStefano Zampini PetscScalar *y; 354206656605SStefano Zampini 3543ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 354406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 354506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 354606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 354706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 354806656605SStefano Zampini if (i<n_vertices) { 354906656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 355006656605SStefano Zampini } 355106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 355206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 355306656605SStefano Zampini 355406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 355506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 355606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 355706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 355806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 355906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 356006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 356106656605SStefano Zampini } 356206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 356306656605SStefano Zampini } 3564ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 3565ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 356606656605SStefano Zampini } 3567d62866d3SStefano Zampini /* free memory */ 356888ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 356906656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 357006656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 357106656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 357206656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 3573d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3574d62866d3SStefano Zampini if (n_vertices) { 3575d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 3576d62866d3SStefano Zampini } 3577d62866d3SStefano Zampini if (n_constraints) { 3578d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 3579d62866d3SStefano Zampini } 358088ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 358188ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 358288ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 3583d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 358488ebb749SStefano Zampini Mat coarse_sub_mat; 358525084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 358688ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 358788ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 358888ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 35898bec7fa6SStefano Zampini Mat C_B,CPHI; 35908bec7fa6SStefano Zampini IS is_dummy; 35918bec7fa6SStefano Zampini Vec mones; 359288ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 359388ebb749SStefano Zampini PetscReal real_value; 359488ebb749SStefano Zampini 3595a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 3596a3df083aSStefano Zampini Mat A; 3597a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 3598a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 3599a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 3600a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 3601a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3602a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 3603a3df083aSStefano Zampini } else { 360488ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 360588ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 360688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 360788ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3608a3df083aSStefano Zampini } 360988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 361088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 3611ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 361288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 361388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 361488ebb749SStefano Zampini } 361588ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 361688ebb749SStefano Zampini 361725084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 36183301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 361925084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3620ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 362188ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 362288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 362388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 362488ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 362588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 362688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 362788ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 362888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 362988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 363088ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 363188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 363288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 363388ebb749SStefano Zampini } else { 363488ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 363588ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 363688ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 363788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 363888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 363988ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 364088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 364188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 364288ebb749SStefano Zampini } 364388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 364488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 364588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 3646511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 36474f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3648fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 3649d12edf2fSStefano Zampini PetscScalar *data,*data2; 36504f1b2e48SStefano Zampini PetscInt j; 3651d12edf2fSStefano Zampini 36524f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 3653fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 3654d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 365586c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 3656d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 3657d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 36584f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 36594f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 3660d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 36614f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 36624f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 36634f1b2e48SStefano Zampini } 3664d12edf2fSStefano Zampini } 3665d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 3666d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 3667d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 3668d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 3669d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 3670d12edf2fSStefano Zampini } 3671d12edf2fSStefano Zampini #if 0 3672d12edf2fSStefano Zampini { 3673d12edf2fSStefano Zampini PetscViewer viewer; 3674d12edf2fSStefano Zampini char filename[256]; 3675ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 3676d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 3677d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3678ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 3679ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 3680ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 3681d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 368272b8c272SStefano Zampini if (save_change) { 368372b8c272SStefano Zampini Mat phi_B; 368472b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 368572b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 368672b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 368772b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 368872b8c272SStefano Zampini } else { 3689ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 3690ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 369172b8c272SStefano Zampini } 3692ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 3693ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 3694ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 3695ffd830a3SStefano Zampini } 3696ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 3697ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 3698ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 3699ffd830a3SStefano Zampini } 370072b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 3701ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 3702ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 3703ffd830a3SStefano Zampini } 3704d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3705d12edf2fSStefano Zampini } 3706d12edf2fSStefano Zampini #endif 370781d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 37088bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 37091575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 371006656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 37118bec7fa6SStefano Zampini 37128bec7fa6SStefano Zampini /* check constraints */ 3713a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 3714a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 37154f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 37168bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3717a00504b5SStefano Zampini } else { 3718a00504b5SStefano Zampini PetscScalar *data; 3719a00504b5SStefano Zampini Mat tmat; 3720a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 3721a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 3722a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 3723a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3724a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3725a00504b5SStefano Zampini } 37268bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 37278bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 37288bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 37298bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 3730bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 3731ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 3732bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3733bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 3734bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 3735bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 3736bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 373788ebb749SStefano Zampini } 37388bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 37398bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 37408bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 37418bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 374225084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 374388ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 374488ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 374588ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 374688ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 374788ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 374888ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 374988ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 375088ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 375188ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 375288ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 3753ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 375488ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 375588ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 375688ebb749SStefano Zampini } 375788ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 375888ebb749SStefano Zampini } 37598629588bSStefano Zampini /* get back data */ 37608629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 376188ebb749SStefano Zampini PetscFunctionReturn(0); 376288ebb749SStefano Zampini } 376388ebb749SStefano Zampini 376488ebb749SStefano Zampini #undef __FUNCT__ 3765d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 3766d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 3767aa0d41d4SStefano Zampini { 3768d65f70fdSStefano Zampini Mat *work_mat; 3769d65f70fdSStefano Zampini IS isrow_s,iscol_s; 3770d65f70fdSStefano Zampini PetscBool rsorted,csorted; 3771c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 3772aa0d41d4SStefano Zampini PetscErrorCode ierr; 3773aa0d41d4SStefano Zampini 3774aa0d41d4SStefano Zampini PetscFunctionBegin; 3775d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 3776d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 3777d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 3778d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 3779aa0d41d4SStefano Zampini 3780d65f70fdSStefano Zampini if (!rsorted) { 3781906d46d4SStefano Zampini const PetscInt *idxs; 3782906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 3783aa0d41d4SStefano Zampini 3784d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 3785d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 3786d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3787d65f70fdSStefano Zampini idxs_perm_r[i] = i; 3788aa0d41d4SStefano Zampini } 3789d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 3790d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 3791d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3792d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 3793aa0d41d4SStefano Zampini } 3794d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 3795d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 3796d65f70fdSStefano Zampini } else { 3797d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 3798d65f70fdSStefano Zampini isrow_s = isrow; 3799aa0d41d4SStefano Zampini } 3800906d46d4SStefano Zampini 3801d65f70fdSStefano Zampini if (!csorted) { 3802d65f70fdSStefano Zampini if (isrow == iscol) { 3803d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 3804d65f70fdSStefano Zampini iscol_s = isrow_s; 3805d65f70fdSStefano Zampini } else { 3806d65f70fdSStefano Zampini const PetscInt *idxs; 3807d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 3808906d46d4SStefano Zampini 3809d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 3810d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 3811d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3812d65f70fdSStefano Zampini idxs_perm_c[i] = i; 3813d65f70fdSStefano Zampini } 3814d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 3815d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 3816d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3817d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 3818d65f70fdSStefano Zampini } 3819d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 3820d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 3821d65f70fdSStefano Zampini } 3822d65f70fdSStefano Zampini } else { 3823d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 3824d65f70fdSStefano Zampini iscol_s = iscol; 3825d65f70fdSStefano Zampini } 3826d65f70fdSStefano Zampini 3827d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 3828d65f70fdSStefano Zampini 3829d65f70fdSStefano Zampini if (!rsorted || !csorted) { 3830906d46d4SStefano Zampini Mat new_mat; 3831d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 3832906d46d4SStefano Zampini 3833d65f70fdSStefano Zampini if (!rsorted) { 3834d65f70fdSStefano Zampini PetscInt *idxs_r,i; 3835d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 3836d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3837d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 3838906d46d4SStefano Zampini } 3839d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 3840d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 3841d65f70fdSStefano Zampini } else { 3842d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 3843906d46d4SStefano Zampini } 3844d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 3845d65f70fdSStefano Zampini 3846d65f70fdSStefano Zampini if (!csorted) { 3847d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 3848d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 3849d65f70fdSStefano Zampini is_perm_c = is_perm_r; 3850d65f70fdSStefano Zampini } else { 3851d65f70fdSStefano Zampini PetscInt *idxs_c,i; 3852d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 3853d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3854d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 3855d65f70fdSStefano Zampini } 3856d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 3857d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 3858d65f70fdSStefano Zampini } 3859d65f70fdSStefano Zampini } else { 3860d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 3861d65f70fdSStefano Zampini } 3862d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 3863d65f70fdSStefano Zampini 3864d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 3865d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 3866d65f70fdSStefano Zampini work_mat[0] = new_mat; 3867d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 3868d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 3869d65f70fdSStefano Zampini } 3870d65f70fdSStefano Zampini 3871d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 3872d65f70fdSStefano Zampini *B = work_mat[0]; 3873d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 3874d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 3875d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 3876d65f70fdSStefano Zampini PetscFunctionReturn(0); 3877d65f70fdSStefano Zampini } 3878d65f70fdSStefano Zampini 3879d65f70fdSStefano Zampini #undef __FUNCT__ 38805e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 38815e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 3882aa0d41d4SStefano Zampini { 3883aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 38845e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3885d65f70fdSStefano Zampini Mat new_mat; 38865e8657edSStefano Zampini IS is_local,is_global; 3887d65f70fdSStefano Zampini PetscInt local_size; 3888d65f70fdSStefano Zampini PetscBool isseqaij; 3889aa0d41d4SStefano Zampini PetscErrorCode ierr; 3890aa0d41d4SStefano Zampini 3891aa0d41d4SStefano Zampini PetscFunctionBegin; 3892aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 38935e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 38945e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 3895b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 3896aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 3897d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 3898aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 3899906d46d4SStefano Zampini 3900906d46d4SStefano Zampini /* check */ 3901906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3902906d46d4SStefano Zampini Vec x,x_change; 3903906d46d4SStefano Zampini PetscReal error; 3904906d46d4SStefano Zampini 39055e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 3906906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 39075e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 3908e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3909e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3910d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 3911e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3912e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3913906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3914906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3915906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3916906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 3917906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3918906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3919906d46d4SStefano Zampini } 3920906d46d4SStefano Zampini 392122d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 39229b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 392322d5777bSStefano Zampini if (isseqaij) { 3924a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3925a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 3926aa0d41d4SStefano Zampini } else { 3927a00504b5SStefano Zampini Mat work_mat; 39281cf9b237SStefano Zampini 3929a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3930aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 3931a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 39321d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 3933aa0d41d4SStefano Zampini } 39343301b35fSStefano Zampini if (matis->A->symmetric_set) { 39353301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 3936e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 39373301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 3938e496cd5dSStefano Zampini #endif 39393301b35fSStefano Zampini } 3940d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 3941aa0d41d4SStefano Zampini PetscFunctionReturn(0); 3942aa0d41d4SStefano Zampini } 3943aa0d41d4SStefano Zampini 3944aa0d41d4SStefano Zampini #undef __FUNCT__ 3945a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 39468ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 3947a64d13efSStefano Zampini { 3948a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3949a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3950d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 395153892102SStefano Zampini PetscInt *idx_R_local=NULL; 39523a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 39533a50541eSStefano Zampini PetscInt vbs,bs; 39546816873aSStefano Zampini PetscBT bitmask=NULL; 3955a64d13efSStefano Zampini PetscErrorCode ierr; 3956a64d13efSStefano Zampini 3957a64d13efSStefano Zampini PetscFunctionBegin; 3958b23d619eSStefano Zampini /* 3959b23d619eSStefano Zampini No need to setup local scatters if 3960b23d619eSStefano Zampini - primal space is unchanged 3961b23d619eSStefano Zampini AND 3962b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 3963b23d619eSStefano Zampini AND 3964b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 3965b23d619eSStefano Zampini */ 3966b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 3967f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 3968f4ddd8eeSStefano Zampini } 3969f4ddd8eeSStefano Zampini /* destroy old objects */ 3970f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3971f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3972f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3973a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 3974b371cd4fSStefano Zampini n_B = pcis->n_B; 3975b371cd4fSStefano Zampini n_D = pcis->n - n_B; 3976b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 39773a50541eSStefano Zampini 3978a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 39796816873aSStefano Zampini 398053892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 3981b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 3982854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 3983a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 3984a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 39850e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 3986a64d13efSStefano Zampini } 3987a64d13efSStefano Zampini 3988a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 39894641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 39906816873aSStefano Zampini idx_R_local[n_R++] = i; 3991a64d13efSStefano Zampini } 3992a64d13efSStefano Zampini } 3993df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 3994df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 39956816873aSStefano Zampini 3996df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3997df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 39986816873aSStefano Zampini } 39993a50541eSStefano Zampini 40003a50541eSStefano Zampini /* Block code */ 40013a50541eSStefano Zampini vbs = 1; 40023a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 40033a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 40043a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 40053a50541eSStefano Zampini PetscInt *vary; 4006b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4007785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 40083a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 4009d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 4010d3df7717SStefano 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 */ 40110e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 4012d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 40133a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 40143a50541eSStefano Zampini is_blocked = PETSC_FALSE; 40153a50541eSStefano Zampini break; 40163a50541eSStefano Zampini } 40173a50541eSStefano Zampini } 4018d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 4019d3df7717SStefano Zampini } else { 4020d3df7717SStefano Zampini /* Verify directly the R set */ 4021d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 4022d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 4023d3df7717SStefano Zampini for (j=1; j<bs; j++) { 4024d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 4025d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 4026d3df7717SStefano Zampini break; 4027d3df7717SStefano Zampini } 4028d3df7717SStefano Zampini } 4029d3df7717SStefano Zampini } 4030d3df7717SStefano Zampini } 40313a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 40323a50541eSStefano Zampini vbs = bs; 40333a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 40343a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 40353a50541eSStefano Zampini } 40363a50541eSStefano Zampini } 40373a50541eSStefano Zampini } 40383a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 4039b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4040df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 404153892102SStefano Zampini 4042df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4043df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 404453892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 4045df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 404653892102SStefano Zampini } else { 40473a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 404853892102SStefano Zampini } 4049a64d13efSStefano Zampini 4050a64d13efSStefano Zampini /* print some info if requested */ 4051a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 4052a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4053a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 40541575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4055a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 4056a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 40574f1b2e48SStefano 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); 4058a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4059a64d13efSStefano Zampini } 4060a64d13efSStefano Zampini 4061a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 4062b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 40636816873aSStefano Zampini IS is_aux1,is_aux2; 40646816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 40656816873aSStefano Zampini 40663a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4067854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 4068854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 4069a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 40704641a718SStefano Zampini for (i=0; i<n_D; i++) { 40714641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 40724641a718SStefano Zampini } 4073a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4074a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 40754641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 40764641a718SStefano Zampini aux_array1[j++] = i; 4077a64d13efSStefano Zampini } 4078a64d13efSStefano Zampini } 4079a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4080a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4081a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 40824641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 40834641a718SStefano Zampini aux_array2[j++] = i; 4084a64d13efSStefano Zampini } 4085a64d13efSStefano Zampini } 4086a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4087a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 4088a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 4089a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4090a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 4091a64d13efSStefano Zampini 40928eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4093785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 4094a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 40954641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 40964641a718SStefano Zampini aux_array1[j++] = i; 4097a64d13efSStefano Zampini } 4098a64d13efSStefano Zampini } 4099a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4100a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 4101a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4102a64d13efSStefano Zampini } 41034641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 41043a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4105d62866d3SStefano Zampini } else { 4106df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 41076816873aSStefano Zampini IS tis; 41086816873aSStefano Zampini PetscInt schur_size; 41096816873aSStefano Zampini 4110df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 41116816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 4112df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 41136816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 41146816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 41156816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 41166816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 41176816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 4118d62866d3SStefano Zampini } 4119d62866d3SStefano Zampini } 4120a64d13efSStefano Zampini PetscFunctionReturn(0); 4121a64d13efSStefano Zampini } 4122a64d13efSStefano Zampini 4123304d26faSStefano Zampini 4124304d26faSStefano Zampini #undef __FUNCT__ 4125304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 4126684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 4127304d26faSStefano Zampini { 4128304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4129304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4130304d26faSStefano Zampini PC pc_temp; 4131304d26faSStefano Zampini Mat A_RR; 4132f4ddd8eeSStefano Zampini MatReuse reuse; 4133304d26faSStefano Zampini PetscScalar m_one = -1.0; 4134304d26faSStefano Zampini PetscReal value; 413504708bb6SStefano Zampini PetscInt n_D,n_R; 4136c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 4137304d26faSStefano Zampini PetscErrorCode ierr; 4138e604994aSStefano Zampini /* prefixes stuff */ 4139312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 4140e604994aSStefano Zampini size_t len; 4141304d26faSStefano Zampini 4142304d26faSStefano Zampini PetscFunctionBegin; 4143304d26faSStefano Zampini 4144e604994aSStefano Zampini /* compute prefixes */ 4145e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 4146e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 4147e604994aSStefano Zampini if (!pcbddc->current_level) { 4148e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4149e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4150e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4151e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4152e604994aSStefano Zampini } else { 4153e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4154312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4155e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4156e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 4157312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4158312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 415934d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 416034d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4161e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4162e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4163e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 4164e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 4165e604994aSStefano Zampini } 4166e604994aSStefano Zampini 4167304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 4168684f6988SStefano Zampini if (dirichlet) { 4169d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4170450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 41719a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 4172450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 4173a3df083aSStefano Zampini Mat A_IIn; 4174a3df083aSStefano Zampini 4175a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 4176a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 4177a3df083aSStefano Zampini pcis->A_II = A_IIn; 4178a3df083aSStefano Zampini } 4179450f8f5eSStefano Zampini } 41803301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 41813301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 4182964fefecSStefano Zampini } 4183ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 4184964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 4185304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 4186304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 4187304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 4188304d26faSStefano Zampini /* default */ 4189304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 4190e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 41919577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 4192304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 41939577ea80SStefano Zampini if (issbaij) { 41949577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 41959577ea80SStefano Zampini } else { 4196304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 41979577ea80SStefano Zampini } 4198304d26faSStefano Zampini /* Allow user's customization */ 4199304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 4200304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4201304d26faSStefano Zampini } 4202d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 4203b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4204df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4205d62866d3SStefano Zampini 4206df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 4207d5574798SStefano Zampini } 4208304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4209304d26faSStefano Zampini if (!n_D) { 4210304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 4211304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4212304d26faSStefano Zampini } 4213304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 4214304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 4215304d26faSStefano Zampini /* set ksp_D into pcis data */ 4216304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 4217304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 4218304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 4219684f6988SStefano Zampini } 4220304d26faSStefano Zampini 4221304d26faSStefano Zampini /* NEUMANN PROBLEM */ 4222684f6988SStefano Zampini A_RR = 0; 4223684f6988SStefano Zampini if (neumann) { 4224d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 422504708bb6SStefano Zampini PetscInt ibs,mbs; 422604708bb6SStefano Zampini PetscBool issbaij; 422704708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4228f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 42298ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 4230f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 4231f4ddd8eeSStefano Zampini PetscInt nn_R; 423281d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 4233f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4234f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 4235f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 4236f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 4237f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4238f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4239f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 4240727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 4241f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4242f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4243f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 4244f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 4245f4ddd8eeSStefano Zampini } 4246f4ddd8eeSStefano Zampini } 4247f4ddd8eeSStefano Zampini /* last check */ 4248d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 4249f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4250f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4251f4ddd8eeSStefano Zampini } 4252f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 4253f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4254f4ddd8eeSStefano Zampini } 4255a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 4256af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 4257af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 425804708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 425904708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 426004708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 426104708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 426204708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 4263af732b37SStefano Zampini } else { 4264511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 42656816873aSStefano Zampini } 426604708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 426704708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 426804708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 426904708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 427004708bb6SStefano Zampini } else { 4271511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 427204708bb6SStefano Zampini } 427304708bb6SStefano Zampini } 4274a00504b5SStefano Zampini /* extract A_RR */ 4275b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4276a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4277a00504b5SStefano Zampini 4278a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 427916e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4280a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 428116e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 428216e386b8SStefano Zampini } else { 4283a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 4284a00504b5SStefano Zampini } 4285a00504b5SStefano Zampini } else { 4286a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4287a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 4288a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4289a00504b5SStefano Zampini } 4290a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 4291f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 429216e386b8SStefano Zampini } 42933301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 42943301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 42956816873aSStefano Zampini } 4296f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 4297304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 4298304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 4299304d26faSStefano Zampini /* default */ 4300304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 4301e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 4302304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 43039577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 43049577ea80SStefano Zampini if (issbaij) { 43059577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 43069577ea80SStefano Zampini } else { 4307304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 43089577ea80SStefano Zampini } 4309304d26faSStefano Zampini /* Allow user's customization */ 4310304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 4311304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4312304d26faSStefano Zampini } 4313304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4314304d26faSStefano Zampini if (!n_R) { 4315304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 4316304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4317304d26faSStefano Zampini } 43185cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 4319df4d28bfSStefano Zampini /* Reuse solver if it is present */ 4320b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4321df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4322d62866d3SStefano Zampini 4323df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 4324d62866d3SStefano Zampini } 4325304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 4326304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 4327684f6988SStefano Zampini } 4328304d26faSStefano Zampini 4329684f6988SStefano Zampini if (pcbddc->dbg_flag) { 4330684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 43311575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4332684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4333684f6988SStefano Zampini } 4334c7017625SStefano Zampini 4335c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 4336c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 4337c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 4338c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 4339c7017625SStefano Zampini } 4340c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 4341c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 4342c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 4343c7017625SStefano Zampini } 4344c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 4345c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 4346c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 4347c7017625SStefano Zampini } 4348c7017625SStefano Zampini 4349c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 4350c7017625SStefano Zampini if (pcbddc->dbg_flag) { 4351684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 43520fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 43530fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 43540fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 43550fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 43560fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 4357e604994aSStefano 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); 4358c7017625SStefano Zampini if (check_corr[0]) { 4359c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 4360c7017625SStefano Zampini } 4361304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4362304d26faSStefano Zampini } 4363684f6988SStefano Zampini if (neumann) { /* Neumann */ 43640fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 43650fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 43660fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 43670fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 43680fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 4369e604994aSStefano 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); 4370c7017625SStefano Zampini if (check_corr[1]) { 4371c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 4372c7017625SStefano Zampini } 4373304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4374304d26faSStefano Zampini } 4375684f6988SStefano Zampini } 43765cbda25cSStefano Zampini /* free Neumann problem's matrix */ 43775cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4378304d26faSStefano Zampini PetscFunctionReturn(0); 4379304d26faSStefano Zampini } 4380304d26faSStefano Zampini 4381304d26faSStefano Zampini #undef __FUNCT__ 4382ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 438380677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 4384674ae819SStefano Zampini { 4385674ae819SStefano Zampini PetscErrorCode ierr; 4386674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4387be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4388b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 4389674ae819SStefano Zampini 4390674ae819SStefano Zampini PetscFunctionBegin; 4391b334f244SStefano Zampini if (!reuse_solver) { 439280677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 439320c7b377SStefano Zampini } 439480677318SStefano Zampini if (!pcbddc->switch_static) { 439580677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 439680677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 439780677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 439820c7b377SStefano Zampini } 4399b334f244SStefano Zampini if (!reuse_solver) { 440080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 440180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 440220c7b377SStefano Zampini } else { 4403df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4404be83ff47SStefano Zampini 4405df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4406df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 440720c7b377SStefano Zampini } 4408be83ff47SStefano Zampini } else { 440980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 441080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 441180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 441280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 441380677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 441480677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 441580677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 441680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 441780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4418674ae819SStefano Zampini } 4419674ae819SStefano Zampini } 4420b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 442180677318SStefano Zampini if (applytranspose) { 442280677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 442380677318SStefano Zampini } else { 442480677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 442580677318SStefano Zampini } 4426be83ff47SStefano Zampini } else { 4427df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4428be83ff47SStefano Zampini 4429be83ff47SStefano Zampini if (applytranspose) { 4430df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4431be83ff47SStefano Zampini } else { 4432df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4433be83ff47SStefano Zampini } 4434be83ff47SStefano Zampini } 443580677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 443680677318SStefano Zampini if (!pcbddc->switch_static) { 4437b334f244SStefano Zampini if (!reuse_solver) { 443880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 443980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4440be83ff47SStefano Zampini } else { 4441df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4442be83ff47SStefano Zampini 4443df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4444df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4445be83ff47SStefano Zampini } 444680677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 444780677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 444880677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 444980677318SStefano Zampini } 445080677318SStefano Zampini } else { 445180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 445280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 445380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 445480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 445580677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 445680677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 445780677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 445880677318SStefano Zampini } 445980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 446080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 446180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 446280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4463674ae819SStefano Zampini } 4464674ae819SStefano Zampini PetscFunctionReturn(0); 4465674ae819SStefano Zampini } 4466674ae819SStefano Zampini 4467dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 4468674ae819SStefano Zampini #undef __FUNCT__ 4469674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 4470dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 4471674ae819SStefano Zampini { 4472674ae819SStefano Zampini PetscErrorCode ierr; 4473674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4474674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 4475674ae819SStefano Zampini const PetscScalar zero = 0.0; 4476674ae819SStefano Zampini 4477674ae819SStefano Zampini PetscFunctionBegin; 4478dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 44794fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4480dc359a40SStefano Zampini if (applytranspose) { 4481674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 44828eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 4483dc359a40SStefano Zampini } else { 4484674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 4485674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 448615aaf578SStefano Zampini } 44874fee134fSStefano Zampini } else { 44884fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 44894fee134fSStefano Zampini } 4490efc2fbd9SStefano Zampini 4491efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 44924f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4493efc2fbd9SStefano Zampini PetscScalar *array; 44944f1b2e48SStefano Zampini PetscInt j; 4495efc2fbd9SStefano Zampini 4496efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 44974f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 4498efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4499efc2fbd9SStefano Zampini } 4500efc2fbd9SStefano Zampini 450112edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 450212edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 450312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 450412edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 450512edc857SStefano Zampini 45069f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 450712edc857SStefano Zampini if (pcbddc->coarse_ksp) { 450851694757SStefano Zampini Mat coarse_mat; 4509964fefecSStefano Zampini Vec rhs,sol; 451051694757SStefano Zampini MatNullSpace nullsp; 451127b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 4512964fefecSStefano Zampini 451327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 451427b6a85dSStefano Zampini PC coarse_pc; 451527b6a85dSStefano Zampini 451627b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 451727b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 451827b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 451927b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 452027b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 452127b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 45223bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 452327b6a85dSStefano Zampini } 452427b6a85dSStefano Zampini } 4525964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 4526964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 452751694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 452851694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 452951694757SStefano Zampini if (nullsp) { 453051694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 453151694757SStefano Zampini } 453212edc857SStefano Zampini if (applytranspose) { 45339a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 4534964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 45352701bc32SStefano Zampini } else { 45361f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 45372701bc32SStefano Zampini PC coarse_pc; 45382701bc32SStefano Zampini 45392701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 45402701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 45413e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 45422701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 454312edc857SStefano Zampini } else { 4544964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 454512edc857SStefano Zampini } 45462701bc32SStefano Zampini } 45471d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 454827b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 454927b6a85dSStefano Zampini PC coarse_pc; 455027b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 455127b6a85dSStefano Zampini 455227b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 455327b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 455427b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 45553bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 455627b6a85dSStefano Zampini } 455751694757SStefano Zampini if (nullsp) { 455851694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 455951694757SStefano Zampini } 456012edc857SStefano Zampini } 4561674ae819SStefano Zampini 4562674ae819SStefano Zampini /* Local solution on R nodes */ 45634fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 456480677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 45659f00e9b4SStefano Zampini } 45669f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 45679f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 456812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4569674ae819SStefano Zampini 45704fee134fSStefano Zampini /* Sum contributions from the two levels */ 45714fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4572dc359a40SStefano Zampini if (applytranspose) { 4573dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 4574dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4575dc359a40SStefano Zampini } else { 4576674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 45778eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4578dc359a40SStefano Zampini } 4579efc2fbd9SStefano Zampini /* store p0 */ 45804f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4581efc2fbd9SStefano Zampini PetscScalar *array; 45824f1b2e48SStefano Zampini PetscInt j; 4583efc2fbd9SStefano Zampini 4584efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 45854f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 4586efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4587efc2fbd9SStefano Zampini } 45884fee134fSStefano Zampini } else { /* expand the coarse solution */ 45894fee134fSStefano Zampini if (applytranspose) { 45904fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 45914fee134fSStefano Zampini } else { 45924fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 45934fee134fSStefano Zampini } 45944fee134fSStefano Zampini } 4595674ae819SStefano Zampini PetscFunctionReturn(0); 4596674ae819SStefano Zampini } 4597674ae819SStefano Zampini 4598674ae819SStefano Zampini #undef __FUNCT__ 4599674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 460012edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 4601674ae819SStefano Zampini { 4602674ae819SStefano Zampini PetscErrorCode ierr; 4603674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 460458da7f69SStefano Zampini PetscScalar *array; 460512edc857SStefano Zampini Vec from,to; 4606674ae819SStefano Zampini 4607674ae819SStefano Zampini PetscFunctionBegin; 460812edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 460912edc857SStefano Zampini from = pcbddc->coarse_vec; 461012edc857SStefano Zampini to = pcbddc->vec1_P; 461112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 461212edc857SStefano Zampini Vec tvec; 461358da7f69SStefano Zampini 461458da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 461558da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 461612edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 461758da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 461858da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 461958da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 462012edc857SStefano Zampini } 462112edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 462212edc857SStefano Zampini from = pcbddc->vec1_P; 462312edc857SStefano Zampini to = pcbddc->coarse_vec; 462412edc857SStefano Zampini } 462512edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 4626674ae819SStefano Zampini PetscFunctionReturn(0); 4627674ae819SStefano Zampini } 4628674ae819SStefano Zampini 4629674ae819SStefano Zampini #undef __FUNCT__ 4630674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 463112edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 4632674ae819SStefano Zampini { 4633674ae819SStefano Zampini PetscErrorCode ierr; 4634674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 463558da7f69SStefano Zampini PetscScalar *array; 463612edc857SStefano Zampini Vec from,to; 4637674ae819SStefano Zampini 4638674ae819SStefano Zampini PetscFunctionBegin; 463912edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 464012edc857SStefano Zampini from = pcbddc->coarse_vec; 464112edc857SStefano Zampini to = pcbddc->vec1_P; 464212edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 464312edc857SStefano Zampini from = pcbddc->vec1_P; 464412edc857SStefano Zampini to = pcbddc->coarse_vec; 464512edc857SStefano Zampini } 464612edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 464712edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 464812edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 464912edc857SStefano Zampini Vec tvec; 465058da7f69SStefano Zampini 465112edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 465258da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 465358da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 465458da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 465558da7f69SStefano Zampini } 465658da7f69SStefano Zampini } else { 465758da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 465858da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 465912edc857SStefano Zampini } 466012edc857SStefano Zampini } 4661674ae819SStefano Zampini PetscFunctionReturn(0); 4662674ae819SStefano Zampini } 4663674ae819SStefano Zampini 4664984c4197SStefano Zampini /* uncomment for testing purposes */ 4665984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 4666674ae819SStefano Zampini #undef __FUNCT__ 4667674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 4668674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 4669674ae819SStefano Zampini { 4670674ae819SStefano Zampini PetscErrorCode ierr; 4671674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4672674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4673674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4674984c4197SStefano Zampini /* one and zero */ 4675984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 4676984c4197SStefano Zampini /* space to store constraints and their local indices */ 46779162d606SStefano Zampini PetscScalar *constraints_data; 46789162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 46799162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 46809162d606SStefano Zampini PetscInt *constraints_n; 4681984c4197SStefano Zampini /* iterators */ 4682b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 4683984c4197SStefano Zampini /* BLAS integers */ 4684e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 4685e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 4686c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 4687727cdba6SStefano Zampini /* reuse */ 46880e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 46890e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 4690984c4197SStefano Zampini /* change of basis */ 4691b3d85658SStefano Zampini PetscBool qr_needed; 46929162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 4693984c4197SStefano Zampini /* auxiliary stuff */ 469464efe560SStefano Zampini PetscInt *nnz,*is_indices; 46958a0068c3SStefano Zampini PetscInt ncc; 4696984c4197SStefano Zampini /* some quantities */ 469745a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 4698a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 4699984c4197SStefano Zampini 4700674ae819SStefano Zampini PetscFunctionBegin; 47018e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 47028e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 47038e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 470416909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 4705088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 4706088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 47070e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 47080e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 47090e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 47100e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 47110e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 4712088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 4713cf5a6209SStefano Zampini 4714cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 47159162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 4716cf5a6209SStefano Zampini MatNullSpace nearnullsp; 4717cf5a6209SStefano Zampini const Vec *nearnullvecs; 4718cf5a6209SStefano Zampini Vec *localnearnullsp; 4719cf5a6209SStefano Zampini PetscScalar *array; 4720cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 4721cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 4722674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 4723b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 4724674ae819SStefano Zampini PetscScalar *work; 4725674ae819SStefano Zampini PetscReal *singular_vals; 4726674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4727674ae819SStefano Zampini PetscReal *rwork; 4728674ae819SStefano Zampini #endif 4729674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4730674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 4731674ae819SStefano Zampini #else 4732964fefecSStefano Zampini PetscBLASInt dummy_int=1; 4733964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 4734674ae819SStefano Zampini #endif 4735674ae819SStefano Zampini 4736674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 4737d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 4738e4d548c7SStefano Zampini /* print some info */ 47391f4df5f7SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs) { 4740e4d548c7SStefano Zampini PetscInt nv; 4741e4d548c7SStefano Zampini 4742c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 4743e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 4744e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4745e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 4746e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 4747e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 4748e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 4749e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4750e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4751e4d548c7SStefano Zampini } 4752e4d548c7SStefano Zampini 4753d06fc5fdSStefano Zampini /* free unneeded index sets */ 4754d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 4755d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 4756674ae819SStefano Zampini } 4757d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 4758d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 4759d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 4760d06fc5fdSStefano Zampini } 4761d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 4762d06fc5fdSStefano Zampini n_ISForEdges = 0; 4763d06fc5fdSStefano Zampini } 4764d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 4765d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 4766d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 4767d06fc5fdSStefano Zampini } 4768d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 4769d06fc5fdSStefano Zampini n_ISForFaces = 0; 4770d06fc5fdSStefano Zampini } 477170022509SStefano Zampini 4772674ae819SStefano Zampini /* check if near null space is attached to global mat */ 4773674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 4774674ae819SStefano Zampini if (nearnullsp) { 4775674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 4776f4ddd8eeSStefano Zampini /* remove any stored info */ 4777f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 4778f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 4779f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 4780f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 4781f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 4782473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 4783f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 4784f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 4785f4ddd8eeSStefano Zampini } 4786984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 4787984c4197SStefano Zampini nnsp_size = 0; 4788674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 4789674ae819SStefano Zampini } 4790984c4197SStefano Zampini /* get max number of constraints on a single cc */ 4791984c4197SStefano Zampini max_constraints = nnsp_size; 4792984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 4793984c4197SStefano Zampini 4794674ae819SStefano Zampini /* 4795674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 47969162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 47979162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 47989162d606SStefano Zampini There can be multiple constraints per connected component 4799674ae819SStefano Zampini */ 4800674ae819SStefano Zampini n_vertices = 0; 4801674ae819SStefano Zampini if (ISForVertices) { 4802674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 4803674ae819SStefano Zampini } 48049162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 48059162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 48069162d606SStefano Zampini 48079162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 48089162d606SStefano Zampini total_counts *= max_constraints; 4809674ae819SStefano Zampini total_counts += n_vertices; 48104641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 48119162d606SStefano Zampini 4812674ae819SStefano Zampini total_counts = 0; 4813674ae819SStefano Zampini max_size_of_constraint = 0; 4814674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 48159162d606SStefano Zampini IS used_is; 4816674ae819SStefano Zampini if (i<n_ISForEdges) { 48179162d606SStefano Zampini used_is = ISForEdges[i]; 4818674ae819SStefano Zampini } else { 48199162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 4820674ae819SStefano Zampini } 48219162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 4822674ae819SStefano Zampini total_counts += j; 4823674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 4824674ae819SStefano Zampini } 48259162d606SStefano 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); 48269162d606SStefano Zampini 4827984c4197SStefano Zampini /* get local part of global near null space vectors */ 4828785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 4829984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 4830984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 4831e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4832e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4833984c4197SStefano Zampini } 4834674ae819SStefano Zampini 4835242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 4836242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 4837a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 4838242a89d7SStefano Zampini 4839984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 4840a773dcb8SStefano Zampini if (!skip_lapack) { 4841674ae819SStefano Zampini PetscScalar temp_work; 4842911cabfeSStefano Zampini 4843674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4844984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 4845785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 4846785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 4847785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 4848674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4849785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 4850674ae819SStefano Zampini #endif 4851674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 4852c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 4853c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 4854674ae819SStefano Zampini lwork = -1; 4855674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4856674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 4857c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 4858674ae819SStefano Zampini #else 4859c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 4860674ae819SStefano Zampini #endif 4861674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4862984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 4863674ae819SStefano Zampini #else /* on missing GESVD */ 4864674ae819SStefano Zampini /* SVD */ 4865674ae819SStefano Zampini PetscInt max_n,min_n; 4866674ae819SStefano Zampini max_n = max_size_of_constraint; 4867984c4197SStefano Zampini min_n = max_constraints; 4868984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 4869674ae819SStefano Zampini min_n = max_size_of_constraint; 4870984c4197SStefano Zampini max_n = max_constraints; 4871674ae819SStefano Zampini } 4872785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 4873674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4874785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 4875674ae819SStefano Zampini #endif 4876674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 4877674ae819SStefano Zampini lwork = -1; 4878e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 4879e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 4880b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 4881674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4882674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 48839162d606SStefano 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)); 4884674ae819SStefano Zampini #else 48859162d606SStefano 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)); 4886674ae819SStefano Zampini #endif 4887674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4888984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 4889984c4197SStefano Zampini #endif /* on missing GESVD */ 4890674ae819SStefano Zampini /* Allocate optimal workspace */ 4891674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 4892854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 4893674ae819SStefano Zampini } 4894674ae819SStefano Zampini /* Now we can loop on constraining sets */ 4895674ae819SStefano Zampini total_counts = 0; 48969162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 48979162d606SStefano Zampini constraints_data_ptr[0] = 0; 4898674ae819SStefano Zampini /* vertices */ 48999162d606SStefano Zampini if (n_vertices) { 4900674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 49019162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 4902674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 49039162d606SStefano Zampini constraints_n[total_counts] = 1; 49049162d606SStefano Zampini constraints_data[total_counts] = 1.0; 49059162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 49069162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 4907674ae819SStefano Zampini total_counts++; 4908674ae819SStefano Zampini } 4909674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4910674ae819SStefano Zampini n_vertices = total_counts; 4911674ae819SStefano Zampini } 4912984c4197SStefano Zampini 4913674ae819SStefano Zampini /* edges and faces */ 49149162d606SStefano Zampini total_counts_cc = total_counts; 4915911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 49169162d606SStefano Zampini IS used_is; 49179162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 49189162d606SStefano Zampini 4919911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 49209162d606SStefano Zampini used_is = ISForEdges[ncc]; 4921984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 4922674ae819SStefano Zampini } else { 49239162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 4924984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 4925674ae819SStefano Zampini } 4926674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 49279162d606SStefano Zampini 49289162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 49299162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4930984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 4931984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 4932674ae819SStefano Zampini if (nnsp_has_cnst) { 49335b08dc53SStefano Zampini PetscScalar quad_value; 49349162d606SStefano Zampini 49359162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 49369162d606SStefano Zampini idxs_copied = PETSC_TRUE; 49379162d606SStefano Zampini 4938a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 4939674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 4940a773dcb8SStefano Zampini } else { 4941a773dcb8SStefano Zampini quad_value = 1.0; 4942a773dcb8SStefano Zampini } 4943674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 49449162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 4945674ae819SStefano Zampini } 49469162d606SStefano Zampini temp_constraints++; 4947674ae819SStefano Zampini total_counts++; 4948674ae819SStefano Zampini } 4949674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 4950984c4197SStefano Zampini PetscReal real_value; 49519162d606SStefano Zampini PetscScalar *ptr_to_data; 49529162d606SStefano Zampini 4953984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 49549162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 4955674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 49569162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 4957674ae819SStefano Zampini } 4958984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 4959984c4197SStefano Zampini /* check if array is null on the connected component */ 4960e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 49619162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 49625b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 4963674ae819SStefano Zampini temp_constraints++; 4964674ae819SStefano Zampini total_counts++; 49659162d606SStefano Zampini if (!idxs_copied) { 49669162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 49679162d606SStefano Zampini idxs_copied = PETSC_TRUE; 4968674ae819SStefano Zampini } 4969674ae819SStefano Zampini } 49709162d606SStefano Zampini } 49719162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 497245a1bb75SStefano Zampini valid_constraints = temp_constraints; 4973eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 4974a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 49759162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 49769162d606SStefano Zampini 49779162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 4978a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 49799162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 4980a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 49819162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 4982a773dcb8SStefano Zampini } else { /* perform SVD */ 4983984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 49849162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 4985674ae819SStefano Zampini 4986674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4987984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 4988984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 4989984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 4990984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 4991984c4197SStefano Zampini from that computed using LAPACKgesvd 4992984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 4993984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 4994984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 4995674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 4996e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 4997984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4998674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 4999674ae819SStefano Zampini for (k=0;k<j+1;k++) { 50009162d606SStefano 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)); 5001674ae819SStefano Zampini } 5002674ae819SStefano Zampini } 5003e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 5004e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5005e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 5006674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5007c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 5008674ae819SStefano Zampini #else 5009c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 5010674ae819SStefano Zampini #endif 5011674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5012984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 5013984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 5014674ae819SStefano Zampini j = 0; 5015984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 5016674ae819SStefano Zampini total_counts = total_counts-j; 501745a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 5018e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 5019c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5020c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5021c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 5022c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5023c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 5024c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5025674ae819SStefano Zampini if (j<temp_constraints) { 5026984c4197SStefano Zampini PetscInt ii; 5027984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 5028674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 50299162d606SStefano 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)); 5030674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5031984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 5032674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 50339162d606SStefano 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]; 5034674ae819SStefano Zampini } 5035674ae819SStefano Zampini } 5036674ae819SStefano Zampini } 5037674ae819SStefano Zampini #else /* on missing GESVD */ 5038e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5039e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5040b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5041674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5042674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 50439162d606SStefano 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)); 5044674ae819SStefano Zampini #else 50459162d606SStefano 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)); 5046674ae819SStefano Zampini #endif 5047984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 5048674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5049984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 5050e310c8b4SStefano Zampini k = temp_constraints; 5051e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 5052674ae819SStefano Zampini j = 0; 5053e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 505445a1bb75SStefano Zampini valid_constraints = k-j; 5055911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 5056984c4197SStefano Zampini #endif /* on missing GESVD */ 5057674ae819SStefano Zampini } 5058a773dcb8SStefano Zampini } 50599162d606SStefano Zampini /* update pointers information */ 50609162d606SStefano Zampini if (valid_constraints) { 50619162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 50629162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 50639162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 50649162d606SStefano Zampini /* set change_of_basis flag */ 506545a1bb75SStefano Zampini if (boolforchange) { 5066b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 50679162d606SStefano Zampini } 5068b3d85658SStefano Zampini total_counts_cc++; 506945a1bb75SStefano Zampini } 507045a1bb75SStefano Zampini } 5071984c4197SStefano Zampini /* free workspace */ 50728f1c130eSStefano Zampini if (!skip_lapack) { 5073984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 5074984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5075984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 5076984c4197SStefano Zampini #endif 5077984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 5078984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5079984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 5080984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 5081984c4197SStefano Zampini #endif 5082984c4197SStefano Zampini } 5083984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5084984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 5085984c4197SStefano Zampini } 5086984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 5087cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 5088cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5089cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5090cf5a6209SStefano Zampini } 5091cf5a6209SStefano Zampini if (n_ISForFaces) { 5092cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5093cf5a6209SStefano Zampini } 5094cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5095cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5096cf5a6209SStefano Zampini } 5097cf5a6209SStefano Zampini if (n_ISForEdges) { 5098cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5099cf5a6209SStefano Zampini } 5100cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 510108122e43SStefano Zampini } else { 510208122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5103984c4197SStefano Zampini 510408122e43SStefano Zampini total_counts = 0; 510508122e43SStefano Zampini n_vertices = 0; 5106d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 5107d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 510808122e43SStefano Zampini } 510908122e43SStefano Zampini max_constraints = 0; 51109162d606SStefano Zampini total_counts_cc = 0; 511108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 511208122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 51139162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 511408122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 511508122e43SStefano Zampini } 51169162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 51179162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 51189162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 51199162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 512074d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 51219162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 51229162d606SStefano Zampini total_counts_cc = 0; 51239162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 51249162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 51259162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 512608122e43SStefano Zampini } 512708122e43SStefano Zampini } 51289162d606SStefano Zampini #if 0 51299162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 51309162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 51319162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 51329162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 51339162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 51349162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 51359162d606SStefano Zampini } 51369162d606SStefano Zampini printf("\n"); 51379162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 51389162d606SStefano Zampini } 51391b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 51408bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 51411b968477SStefano Zampini } 51421b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 51438bec7fa6SStefano 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]); 51441b968477SStefano Zampini } 514508122e43SStefano Zampini #endif 514608122e43SStefano Zampini 51478bec7fa6SStefano Zampini max_size_of_constraint = 0; 51489162d606SStefano 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]); 51499162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 515008122e43SStefano Zampini /* Change of basis */ 5151b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 515208122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 515308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 515408122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 5155b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 515608122e43SStefano Zampini } 515708122e43SStefano Zampini } 515808122e43SStefano Zampini } 515908122e43SStefano Zampini } 5160984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 51614f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 516208122e43SStefano Zampini 51639162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 51649162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 51656c4ed002SBarry 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); 5166674ae819SStefano Zampini 5167674ae819SStefano Zampini /* Create constraint matrix */ 5168674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 516916f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 5170984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 5171984c4197SStefano Zampini 5172984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 5173a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 5174a717540cSStefano Zampini qr_needed = PETSC_FALSE; 517574d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 5176984c4197SStefano Zampini total_primal_vertices=0; 5177b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 51789162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 51799162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 518072b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 51819162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 5182b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 518364efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 51849162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 51859162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 5186a717540cSStefano Zampini } 5187b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 518891af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 5189a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 5190a717540cSStefano Zampini qr_needed = PETSC_TRUE; 5191a717540cSStefano Zampini } 5192fa434743SStefano Zampini } else { 5193b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 5194fa434743SStefano Zampini } 5195a717540cSStefano Zampini } 5196b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 5197b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 5198674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 519970022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5200b3d85658SStefano Zampini 52014f1b2e48SStefano 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); 52020e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 52030e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 5204984c4197SStefano Zampini 5205984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 520674d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 5207785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 5208984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 520974d5cdf7SStefano Zampini 5210984c4197SStefano Zampini j = total_primal_vertices; 521174d5cdf7SStefano Zampini total_counts = total_primal_vertices; 5212b3d85658SStefano Zampini cum = total_primal_vertices; 52139162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 52144641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 5215b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 5216b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 5217b3d85658SStefano Zampini cum++; 52189162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 521974d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 522074d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 522174d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 522274d5cdf7SStefano Zampini } 52239162d606SStefano Zampini j += constraints_n[i]; 5224674ae819SStefano Zampini } 5225674ae819SStefano Zampini } 5226674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 5227674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 5228088faed8SStefano Zampini 5229674ae819SStefano Zampini /* set values in constraint matrix */ 5230984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 52310e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5232674ae819SStefano Zampini } 5233984c4197SStefano Zampini total_counts = total_primal_vertices; 52349162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 52354641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 52369162d606SStefano Zampini PetscInt *cols; 52379162d606SStefano Zampini 52389162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 52399162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 52409162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 52419162d606SStefano Zampini PetscInt row = total_counts+k; 52429162d606SStefano Zampini PetscScalar *vals; 52439162d606SStefano Zampini 52449162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 52459162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 52469162d606SStefano Zampini } 52479162d606SStefano Zampini total_counts += constraints_n[i]; 5248674ae819SStefano Zampini } 5249674ae819SStefano Zampini } 5250674ae819SStefano Zampini /* assembling */ 5251674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5252674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5253088faed8SStefano Zampini 5254984c4197SStefano Zampini /* 52556a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5256984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 5257f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 5258984c4197SStefano Zampini */ 5259674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 5260674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 5261026de310SStefano Zampini /* dual and primal dofs on a single cc */ 5262984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 5263984c4197SStefano Zampini /* working stuff for GEQRF */ 526481d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 5265984c4197SStefano Zampini PetscBLASInt lqr_work; 5266984c4197SStefano Zampini /* working stuff for UNGQR */ 5267984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 5268984c4197SStefano Zampini PetscBLASInt lgqr_work; 5269984c4197SStefano Zampini /* working stuff for TRTRS */ 5270984c4197SStefano Zampini PetscScalar *trs_rhs; 52713f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 5272984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 5273984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 5274984c4197SStefano Zampini PetscScalar *start_vals; 5275984c4197SStefano Zampini /* working stuff for values insertion */ 52764641a718SStefano Zampini PetscBT is_primal; 527764efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 5278906d46d4SStefano Zampini /* matrix sizes */ 5279906d46d4SStefano Zampini PetscInt global_size,local_size; 5280906d46d4SStefano Zampini /* temporary change of basis */ 5281906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 5282cf5a6209SStefano Zampini /* extra space for debugging */ 5283cf5a6209SStefano Zampini PetscScalar *dbg_work; 5284984c4197SStefano Zampini 5285906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 5286906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 528716f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 5288bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 5289906d46d4SStefano Zampini /* nonzeros for local mat */ 5290bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 52911dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5292bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 52931dd7afcfSStefano Zampini } else { 52941dd7afcfSStefano Zampini const PetscInt *ii; 52951dd7afcfSStefano Zampini PetscInt n; 52961dd7afcfSStefano Zampini PetscBool flg_row; 52971dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 52981dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 52991dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 53001dd7afcfSStefano Zampini } 53019162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 5302a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 53039162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 5304a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 53059162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 5306a717540cSStefano Zampini } else { 53079162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 53089162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 5309a717540cSStefano Zampini } 5310a717540cSStefano Zampini } 5311a717540cSStefano Zampini } 5312906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 5313bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 53141dd7afcfSStefano Zampini /* Set interior change in the matrix */ 53151dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5316bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 5317906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 5318a717540cSStefano Zampini } 53191dd7afcfSStefano Zampini } else { 53201dd7afcfSStefano Zampini const PetscInt *ii,*jj; 53211dd7afcfSStefano Zampini PetscScalar *aa; 53221dd7afcfSStefano Zampini PetscInt n; 53231dd7afcfSStefano Zampini PetscBool flg_row; 53241dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 53251dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 53261dd7afcfSStefano Zampini for (i=0;i<n;i++) { 53271dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 53281dd7afcfSStefano Zampini } 53291dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 53301dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 53311dd7afcfSStefano Zampini } 5332a717540cSStefano Zampini 5333a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5334a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5335a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5336a717540cSStefano Zampini } 5337a717540cSStefano Zampini 5338a717540cSStefano Zampini 5339a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 5340a717540cSStefano Zampini /* 5341a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 5342a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 5343a717540cSStefano Zampini 5344a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 5345a717540cSStefano Zampini 5346a6b551f4SStefano 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) 5347a6b551f4SStefano Zampini 5348a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 5349a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 5350a717540cSStefano Zampini | ... | 5351a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 5352a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 5353a717540cSStefano Zampini 5354a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 5355a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 5356a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 5357a6b551f4SStefano Zampini 5358a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 5359a717540cSStefano Zampini */ 5360a717540cSStefano Zampini if (qr_needed) { 5361984c4197SStefano Zampini /* space to store Q */ 5362854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 53634e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 53644e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 5365984c4197SStefano Zampini /* first we issue queries for optimal work */ 53663f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 53673f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 53683f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5369984c4197SStefano Zampini lqr_work = -1; 53703f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 5371984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 5372984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 5373785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 5374984c4197SStefano Zampini lgqr_work = -1; 53753f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 53763f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 53773f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 53783f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 53793f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 53803f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 5381984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 5382984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 5383785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 5384984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 5385785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 5386a717540cSStefano Zampini /* allocating workspace for check */ 5387a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5388cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 5389a717540cSStefano Zampini } 5390a717540cSStefano Zampini } 5391984c4197SStefano Zampini /* array to store whether a node is primal or not */ 53924641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 5393473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 53940e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 53956c4ed002SBarry 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); 539639e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 539739e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 539839e2fb2aSStefano Zampini } 539939e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 5400984c4197SStefano Zampini 5401a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 54029162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 54039162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 54044641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 5405984c4197SStefano Zampini /* get constraint info */ 54069162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 5407984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 5408984c4197SStefano Zampini 5409984c4197SStefano Zampini if (pcbddc->dbg_flag) { 54109162d606SStefano 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); 5411674ae819SStefano Zampini } 5412984c4197SStefano Zampini 5413fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 5414a717540cSStefano Zampini 5415a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 5416a717540cSStefano Zampini if (pcbddc->dbg_flag) { 54179162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5418a717540cSStefano Zampini } 5419984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 54209162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5421984c4197SStefano Zampini 5422984c4197SStefano Zampini /* compute QR decomposition of constraints */ 54233f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 54243f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 54253f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5426674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 54273f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 5428984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 5429674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5430984c4197SStefano Zampini 5431984c4197SStefano Zampini /* explictly compute R^-T */ 5432984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 5433984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 54343f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 54353f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 54363f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 54373f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 5438984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 54393f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 5440984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 5441984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5442984c4197SStefano Zampini 5443a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 54443f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 54453f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 54463f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 54473f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5448984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 54493f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 5450984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 5451984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5452984c4197SStefano Zampini 5453984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 5454984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 5455984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 54563f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 54573f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 54583f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 54593f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 54603f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 54613f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5462984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 54639162d606SStefano 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)); 5464984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 54659162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5466984c4197SStefano Zampini 5467984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 54689162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 5469984c4197SStefano Zampini /* insert cols for primal dofs */ 5470984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 5471984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 54729162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5473906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5474984c4197SStefano Zampini } 5475984c4197SStefano Zampini /* insert cols for dual dofs */ 5476984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 54779162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 5478984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 54799162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5480906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5481984c4197SStefano Zampini j++; 5482674ae819SStefano Zampini } 5483674ae819SStefano Zampini } 5484984c4197SStefano Zampini 5485984c4197SStefano Zampini /* check change of basis */ 5486984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5487984c4197SStefano Zampini PetscInt ii,jj; 5488984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 5489c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 5490c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5491c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 5492c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5493c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 5494c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 5495984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5496cf5a6209SStefano 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)); 5497984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5498984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5499984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5500cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 5501cf5a6209SStefano 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; 5502674ae819SStefano Zampini } 5503674ae819SStefano Zampini } 5504984c4197SStefano Zampini if (!valid_qr) { 550522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 5506984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5507984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5508cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 5509cf5a6209SStefano 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])); 5510674ae819SStefano Zampini } 5511cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 5512cf5a6209SStefano 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])); 5513984c4197SStefano Zampini } 5514984c4197SStefano Zampini } 5515984c4197SStefano Zampini } 5516674ae819SStefano Zampini } else { 551722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 5518674ae819SStefano Zampini } 5519674ae819SStefano Zampini } 5520a717540cSStefano Zampini } else { /* simple transformation block */ 5521a717540cSStefano Zampini PetscInt row,col; 5522a6b551f4SStefano Zampini PetscScalar val,norm; 5523a6b551f4SStefano Zampini 5524a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 55259162d606SStefano 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)); 5526a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 55279162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 55289162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5529bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 55309162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 5531906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 55329162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 5533a717540cSStefano Zampini } else { 5534a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 55359162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5536a717540cSStefano Zampini if (row != col) { 55379162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 5538a717540cSStefano Zampini } else { 55399162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 5540a717540cSStefano Zampini } 5541906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 5542a717540cSStefano Zampini } 5543a717540cSStefano Zampini } 5544a717540cSStefano Zampini } 554598a51de6SStefano Zampini if (pcbddc->dbg_flag) { 554622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 5547a717540cSStefano Zampini } 5548674ae819SStefano Zampini } 5549984c4197SStefano Zampini } else { 5550984c4197SStefano Zampini if (pcbddc->dbg_flag) { 55519162d606SStefano 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); 5552674ae819SStefano Zampini } 5553674ae819SStefano Zampini } 5554674ae819SStefano Zampini } 5555a717540cSStefano Zampini 5556a717540cSStefano Zampini /* free workspace */ 5557a717540cSStefano Zampini if (qr_needed) { 5558984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5559cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 5560984c4197SStefano Zampini } 5561984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 5562984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 5563984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 5564984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 5565984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 5566674ae819SStefano Zampini } 5567a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 5568906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5569906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5570906d46d4SStefano Zampini 5571906d46d4SStefano Zampini /* assembling of global change of variable */ 557288c03ad3SStefano Zampini if (!pcbddc->fake_change) { 5573bbb9e6c6SStefano Zampini Mat tmat; 557416f15bc4SStefano Zampini PetscInt bs; 557516f15bc4SStefano Zampini 5576906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 5577906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 5578bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 5579bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 5580bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5581bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 558216f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 558316f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 5584906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 5585bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 5586bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5587bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 5588bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5589bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5590e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5591e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5592bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 5593bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 559488c03ad3SStefano Zampini 5595906d46d4SStefano Zampini /* check */ 5596906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 5597906d46d4SStefano Zampini PetscReal error; 5598906d46d4SStefano Zampini Vec x,x_change; 5599906d46d4SStefano Zampini 5600906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 5601906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 5602906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 5603906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 5604e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5605e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5606bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 5607e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5608e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5609906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 5610906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 5611906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 5612906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5613bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 5614906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 5615906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 5616906d46d4SStefano Zampini } 5617b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 5618b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 5619b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5620bf3a8328SStefano Zampini 56219a962809SStefano 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); 5622b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 5623ac632422SStefano Zampini Mat S_new,tmat; 5624bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 5625bbb9e6c6SStefano Zampini 5626bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 56276816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 5628bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5629bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 5630bf3a8328SStefano Zampini IS is_V; 5631b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 5632b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 5633b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 5634b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 5635b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 5636bf3a8328SStefano Zampini } 5637bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 5638ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 5639b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 5640ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 5641bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5642bf3a8328SStefano Zampini const PetscScalar *array; 5643bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 5644bf3a8328SStefano Zampini PetscInt i,n_V; 5645bf3a8328SStefano Zampini 5646b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 5647b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 5648b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 5649b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 5650b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 5651b087196eSStefano Zampini for (i=0;i<n_V;i++) { 5652b087196eSStefano Zampini PetscScalar val; 5653b087196eSStefano Zampini PetscInt idx; 5654b087196eSStefano Zampini 5655b087196eSStefano Zampini idx = idxs_V[i]; 5656b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 5657b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 5658b087196eSStefano Zampini } 5659b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5660b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5661bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 5662bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 5663bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 5664bf3a8328SStefano Zampini } 5665ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 5666ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 5667ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 5668ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 5669b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 5670ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 5671bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5672b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 5673bf3a8328SStefano Zampini } 5674ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 5675ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 5676ac632422SStefano Zampini } 5677b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 567888c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 5679b96c3477SStefano Zampini } 5680c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 5681b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 5682c9db6a07SStefano Zampini PetscInt i; 5683c9db6a07SStefano Zampini 5684c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5685c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 5686c9db6a07SStefano Zampini } 5687c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 5688c9db6a07SStefano Zampini } 5689b96c3477SStefano Zampini } 569016909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 569116909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 569216909a7fSStefano Zampini } else { 5693906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 569416909a7fSStefano Zampini } 56951dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 569627b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 569772b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 569872b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 569972b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 570072b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 570172b8c272SStefano Zampini } 57021dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 570327b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 5704b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 5705b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 5706906d46d4SStefano Zampini } else { 57071dd7afcfSStefano Zampini Mat benign_global = NULL; 570827b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 57091dd7afcfSStefano Zampini Mat tmat; 57101dd7afcfSStefano Zampini 57111dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 57121dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 57131dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 57141dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 57151dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 57161dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 57171dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 57181dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 57191dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 57201dd7afcfSStefano Zampini if (pcbddc->benign_change) { 57211dd7afcfSStefano Zampini Mat M; 57221dd7afcfSStefano Zampini 57231dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 57241dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 57251dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 57261dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 5727906d46d4SStefano Zampini } else { 57281dd7afcfSStefano Zampini Mat eye; 57291dd7afcfSStefano Zampini PetscScalar *array; 57301dd7afcfSStefano Zampini 57311dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 57321dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 57331dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 57341dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 5735906d46d4SStefano Zampini } 57361dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 57371dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 57381dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 57391dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 57401dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 57411dd7afcfSStefano Zampini } 57421dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 57431dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 57441dd7afcfSStefano Zampini } 57451dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 57461dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 57471dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 574827b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 57491dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 57501dd7afcfSStefano Zampini } 57511dd7afcfSStefano Zampini } 575216909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 575316909a7fSStefano Zampini IS is_global; 575416909a7fSStefano Zampini const PetscInt *gidxs; 575516909a7fSStefano Zampini 575616909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 575716909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 575816909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 575916909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 576016909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 576116909a7fSStefano Zampini } 57621dd7afcfSStefano Zampini } 57631dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 57641dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 5765b9b85e73SStefano Zampini } 5766a717540cSStefano Zampini 576772b8c272SStefano Zampini if (!pcbddc->fake_change) { 57684f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 57694f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 57704f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 57714f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 5772019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 5773019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 5774019a44ceSStefano Zampini pcbddc->local_primal_size++; 5775019a44ceSStefano Zampini } 5776019a44ceSStefano Zampini 5777019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 5778727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 5779727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 57809f47a83aSStefano 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); 5781c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 57820e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 57839f47a83aSStefano 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); 5784727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 5785727cdba6SStefano Zampini } 57860e6343abSStefano Zampini } 5787727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 5788b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 578972b8c272SStefano Zampini } 579072b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 5791727cdba6SStefano Zampini 5792a717540cSStefano Zampini /* flush dbg viewer */ 5793b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 5794b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5795b8ffe317SStefano Zampini } 5796a717540cSStefano Zampini 5797e310c8b4SStefano Zampini /* free workspace */ 5798a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 57994641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 580008122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 58019162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 58029162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 580308122e43SStefano Zampini } else { 58049162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 58059162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 58069162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 580708122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 580808122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 58099162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 58109162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 581108122e43SStefano Zampini } 5812674ae819SStefano Zampini PetscFunctionReturn(0); 5813674ae819SStefano Zampini } 5814674ae819SStefano Zampini 5815674ae819SStefano Zampini #undef __FUNCT__ 5816674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 5817674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 5818674ae819SStefano Zampini { 581971582508SStefano Zampini ISLocalToGlobalMapping map; 5820674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5821674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 582214f95afaSStefano Zampini PetscInt ierr,i,N; 5823674ae819SStefano Zampini 5824674ae819SStefano Zampini PetscFunctionBegin; 5825c8272957SStefano Zampini if (pcbddc->graphanalyzed && !pcbddc->recompute_topography) PetscFunctionReturn(0); 58268e61c736SStefano Zampini /* Reset previously computed graph */ 58278e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 5828674ae819SStefano Zampini /* Init local Graph struct */ 58297fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 583071582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 5831be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 5832674ae819SStefano Zampini 5833575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 58349a962809SStefano 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); 58359577ea80SStefano Zampini 5836674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 5837d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 58384d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 58394d379d7bSStefano Zampini PetscInt nvtxs; 5840e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 5841674ae819SStefano Zampini 58422fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 58432fffb893SStefano Zampini if (flg_row) { 58444d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 5845b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 58462fffb893SStefano Zampini } 58472fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 5848674ae819SStefano Zampini } 58499b28b941SStefano Zampini if (pcbddc->dbg_flag) { 58509b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5851674ae819SStefano Zampini } 5852674ae819SStefano Zampini 5853674ae819SStefano Zampini /* Setup of Graph */ 58544b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 585514f95afaSStefano 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); 5856674ae819SStefano Zampini 58574f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 58584f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 58594f1b2e48SStefano Zampini PetscInt *local_subs; 58604f1b2e48SStefano Zampini 58614f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 58624f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 58634f1b2e48SStefano Zampini const PetscInt *idxs; 58644f1b2e48SStefano Zampini PetscInt nl,j; 58654f1b2e48SStefano Zampini 58664f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 58674f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 586871582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 58694f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 58704f1b2e48SStefano Zampini } 58714f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 58724f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 58734f1b2e48SStefano Zampini } 58744f1b2e48SStefano Zampini 5875674ae819SStefano Zampini /* Graph's connected components analysis */ 5876674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 587771582508SStefano Zampini 587871582508SStefano Zampini /* set flag indicating analysis has been done */ 587971582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 5880674ae819SStefano Zampini PetscFunctionReturn(0); 5881674ae819SStefano Zampini } 5882674ae819SStefano Zampini 58839a7d3425SStefano Zampini #undef __FUNCT__ 58849a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 58859a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 58869a7d3425SStefano Zampini { 58879a7d3425SStefano Zampini PetscInt i,j; 58889a7d3425SStefano Zampini PetscScalar *alphas; 58899a7d3425SStefano Zampini PetscErrorCode ierr; 58909a7d3425SStefano Zampini 58919a7d3425SStefano Zampini PetscFunctionBegin; 5892785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 58939a7d3425SStefano Zampini for (i=0;i<n;i++) { 58949a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 5895669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 5896669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 5897669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 58989a7d3425SStefano Zampini } 58999a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 59009a7d3425SStefano Zampini PetscFunctionReturn(0); 59019a7d3425SStefano Zampini } 59029a7d3425SStefano Zampini 5903e7931f94SStefano Zampini #undef __FUNCT__ 590470cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 590557de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 5906e7931f94SStefano Zampini { 590757de7509SStefano Zampini Mat A; 5908e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 5909e7931f94SStefano Zampini PetscMPIInt size,rank,color; 591052e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 591152e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 591227b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 591357de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 591427b6a85dSStefano Zampini PetscInt xadj_count, *count; 591527b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 591627b6a85dSStefano Zampini PetscSubcomm psubcomm; 591727b6a85dSStefano Zampini MPI_Comm subcomm; 591852e5ac9dSStefano Zampini PetscErrorCode ierr; 5919a57a6d2fSStefano Zampini 5920e7931f94SStefano Zampini PetscFunctionBegin; 592157de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 592257de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 592357de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 592457de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 592557de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 592657de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 592757de7509SStefano Zampini 592857de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 592957de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 593057de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 593157de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 593257de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 593357de7509SStefano Zampini im_active = !!(n); 593457de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 593557de7509SStefano Zampini void_procs = size - active_procs; 593657de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 593757de7509SStefano Zampini if (void_procs) { 593857de7509SStefano Zampini PetscInt ncand; 593957de7509SStefano Zampini 594057de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 594157de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 594257de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 594357de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 594457de7509SStefano Zampini if (!procs_candidates[i]) { 594557de7509SStefano Zampini procs_candidates[ncand++] = i; 594657de7509SStefano Zampini } 594757de7509SStefano Zampini } 594857de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 594957de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 595057de7509SStefano Zampini } 595157de7509SStefano Zampini 595214f0bfb9SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix 595314f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 595414f0bfb9SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1) { 595514f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 595614f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 595714f0bfb9SStefano Zampini else dest = rank; 595857de7509SStefano Zampini if (im_active) { 595957de7509SStefano Zampini issize = 1; 596057de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 596114f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 596257de7509SStefano Zampini } else { 596314f0bfb9SStefano Zampini isidx = dest; 596457de7509SStefano Zampini } 596557de7509SStefano Zampini } else { 596657de7509SStefano Zampini issize = 0; 596757de7509SStefano Zampini isidx = -1; 596857de7509SStefano Zampini } 596957de7509SStefano Zampini *n_subdomains = active_procs; 597057de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 5971daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 597257de7509SStefano Zampini PetscFunctionReturn(0); 597357de7509SStefano Zampini } 5974c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 5975c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 597627b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 5977e7931f94SStefano Zampini 5978e7931f94SStefano Zampini /* Get info on mapping */ 59793bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 59803bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 5981e7931f94SStefano Zampini 5982e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 5983785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 5984e7931f94SStefano Zampini xadj[0] = 0; 5985e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 5986785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 5987785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 598827b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 598927b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 599027b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 599127b6a85dSStefano Zampini count[shared[i][j]] += 1; 5992e7931f94SStefano Zampini 599327b6a85dSStefano Zampini xadj_count = 0; 59942b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 599527b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 599627b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 5997d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 5998d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 5999d023bfaeSStefano Zampini xadj_count++; 600027b6a85dSStefano Zampini break; 600127b6a85dSStefano Zampini } 6002e7931f94SStefano Zampini } 6003e7931f94SStefano Zampini } 6004d023bfaeSStefano Zampini xadj[1] = xadj_count; 600527b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 60063bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6007e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 6008e7931f94SStefano Zampini 60093837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 6010e7931f94SStefano Zampini 601127b6a85dSStefano Zampini /* Restrict work on active processes only */ 601227b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 601327b6a85dSStefano Zampini if (void_procs) { 601427b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 601527b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 601627b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 601727b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 601827b6a85dSStefano Zampini } else { 601927b6a85dSStefano Zampini psubcomm = NULL; 602027b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 602127b6a85dSStefano Zampini } 602227b6a85dSStefano Zampini 602327b6a85dSStefano Zampini v_wgt = NULL; 602427b6a85dSStefano Zampini if (!color) { 6025e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 6026e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 6027e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6028c8587f34SStefano Zampini } else { 602952e5ac9dSStefano Zampini Mat subdomain_adj; 603052e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 603152e5ac9dSStefano Zampini MatPartitioning partitioner; 603227b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 603352e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 603457de7509SStefano Zampini PetscMPIInt size; 6035b0c7d250SStefano Zampini PetscBool aggregate; 6036b0c7d250SStefano Zampini 603727b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 603827b6a85dSStefano Zampini if (void_procs) { 603927b6a85dSStefano Zampini PetscInt prank = rank; 6040785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 604127b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 6042e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 6043e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 6044c8587f34SStefano Zampini } 6045e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 604627b6a85dSStefano Zampini } else { 604727b6a85dSStefano Zampini oldranks = NULL; 604827b6a85dSStefano Zampini } 6049b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 605027b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 6051b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 6052b0c7d250SStefano Zampini PetscMPIInt nrank; 6053b0c7d250SStefano Zampini PetscScalar *vals; 6054b0c7d250SStefano Zampini 605527b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 6056b0c7d250SStefano Zampini lrows = 0; 6057b0c7d250SStefano Zampini if (nrank<redprocs) { 6058b0c7d250SStefano Zampini lrows = size/redprocs; 6059b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 6060b0c7d250SStefano Zampini } 606127b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 6062b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 6063b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6064b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6065b0c7d250SStefano Zampini row = nrank; 6066b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 6067b0c7d250SStefano Zampini cols = adjncy; 6068b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 6069b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 6070b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 6071b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6072b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 607352e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 607452e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 607552e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6076b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 607727b6a85dSStefano Zampini if (use_vwgt) { 607827b6a85dSStefano Zampini Vec v; 607927b6a85dSStefano Zampini const PetscScalar *array; 608027b6a85dSStefano Zampini PetscInt nl; 608127b6a85dSStefano Zampini 608227b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 608327b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 608427b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 608527b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 608627b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 608727b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 608827b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 608922db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 609027b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 609127b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 609227b6a85dSStefano Zampini } 6093b0c7d250SStefano Zampini } else { 609427b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 609527b6a85dSStefano Zampini if (use_vwgt) { 609627b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 609727b6a85dSStefano Zampini v_wgt[0] = local_size; 609827b6a85dSStefano Zampini } 6099b0c7d250SStefano Zampini } 610022b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 6101e7931f94SStefano Zampini 6102e7931f94SStefano Zampini /* Partition */ 610327b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 6104e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 610527b6a85dSStefano Zampini if (v_wgt) { 6106e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 6107c8587f34SStefano Zampini } 610857de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 610957de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 6110e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 6111e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 611222b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 6113e7931f94SStefano Zampini 611452e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 61156583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 611652e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 611752e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 611857de7509SStefano Zampini if (!aggregate) { 611957de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 612027b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 612127b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 612227b6a85dSStefano Zampini #endif 612357de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 612427b6a85dSStefano Zampini } else if (oldranks) { 6125b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 612627b6a85dSStefano Zampini } else { 612727b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 612857de7509SStefano Zampini } 612928143c3dSStefano Zampini } else { 6130b0c7d250SStefano Zampini PetscInt idxs[1]; 6131b0c7d250SStefano Zampini PetscMPIInt tag; 6132b0c7d250SStefano Zampini MPI_Request *reqs; 6133b0c7d250SStefano Zampini 6134b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 6135b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 6136b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 613727b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 613828143c3dSStefano Zampini } 613927b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 6140b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6141b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 614257de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 614327b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 614427b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 614527b6a85dSStefano Zampini #endif 614657de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 614727b6a85dSStefano Zampini } else if (oldranks) { 6148b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 614927b6a85dSStefano Zampini } else { 615027b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 6151e7931f94SStefano Zampini } 615257de7509SStefano Zampini } 615352e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6154e7931f94SStefano Zampini /* clean up */ 6155e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 615652e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 6157e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 6158e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 6159e7931f94SStefano Zampini } 616027b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 616157de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 6162e7931f94SStefano Zampini 6163e7931f94SStefano Zampini /* assemble parallel IS for sends */ 6164e7931f94SStefano Zampini i = 1; 616527b6a85dSStefano Zampini if (!color) i=0; 616657de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 6167e7931f94SStefano Zampini PetscFunctionReturn(0); 6168e7931f94SStefano Zampini } 6169e7931f94SStefano Zampini 6170e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 6171e7931f94SStefano Zampini 6172e7931f94SStefano Zampini #undef __FUNCT__ 6173e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 61741ae86dd6SStefano 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[]) 6175e7931f94SStefano Zampini { 617670cf5478SStefano Zampini Mat local_mat; 6177e7931f94SStefano Zampini IS is_sends_internal; 61789d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 61791ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 61809d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 6181e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 6182e7931f94SStefano Zampini PetscInt* l2gmap_indices; 6183e7931f94SStefano Zampini const PetscInt* is_indices; 6184e7931f94SStefano Zampini MatType new_local_type; 6185e7931f94SStefano Zampini /* buffers */ 6186e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 618728143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 61889d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 6189e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 61901ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 6191e7931f94SStefano Zampini /* MPI */ 619228143c3dSStefano Zampini MPI_Comm comm,comm_n; 619328143c3dSStefano Zampini PetscSubcomm subcomm; 6194e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 619528143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 619628143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 61971ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 61981ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 61991ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 6200e7931f94SStefano Zampini PetscErrorCode ierr; 6201e7931f94SStefano Zampini 6202e7931f94SStefano Zampini PetscFunctionBegin; 620357de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6204e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 620528143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 620657de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 620757de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 620857de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 620957de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 621057de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 62111ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 62121ae86dd6SStefano Zampini if (nvecs) { 62131ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 62141ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 62151ae86dd6SStefano Zampini } 621657de7509SStefano Zampini /* further checks */ 6217e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6218e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 6219e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 6220e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 6221e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 622257de7509SStefano Zampini if (reuse && *mat_n) { 622370cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 622457de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 622570cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 622628143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 622770cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 622870cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 622970cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 623070cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 623170cf5478SStefano Zampini } 6232e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 6233e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 623457de7509SStefano Zampini 6235e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 6236e7931f94SStefano Zampini if (!is_sends) { 623728143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 623857de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 6239c8587f34SStefano Zampini } else { 6240e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 6241e7931f94SStefano Zampini is_sends_internal = is_sends; 6242c8587f34SStefano Zampini } 6243e7931f94SStefano Zampini 6244e7931f94SStefano Zampini /* get comm */ 6245a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 6246e7931f94SStefano Zampini 6247e7931f94SStefano Zampini /* compute number of sends */ 6248e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 6249e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 6250e7931f94SStefano Zampini 6251e7931f94SStefano Zampini /* compute number of receives */ 6252e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 6253785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 6254e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 6255e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6256e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 6257e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 6258e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 6259e7931f94SStefano Zampini 626028143c3dSStefano Zampini /* restrict comm if requested */ 626128143c3dSStefano Zampini subcomm = 0; 626228143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 626328143c3dSStefano Zampini if (restrict_comm) { 6264779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 6265779c1cceSStefano Zampini 626628143c3dSStefano Zampini color = 0; 626753a05cb3SStefano Zampini if (restrict_full) { 626853a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 626953a05cb3SStefano Zampini } else { 627053a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 627153a05cb3SStefano Zampini } 6272b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 627328143c3dSStefano Zampini subcommsize = commsize - subcommsize; 627428143c3dSStefano Zampini /* check if reuse has been requested */ 627557de7509SStefano Zampini if (reuse) { 627628143c3dSStefano Zampini if (*mat_n) { 627728143c3dSStefano Zampini PetscMPIInt subcommsize2; 627828143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 627928143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 628028143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 628128143c3dSStefano Zampini } else { 628228143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 628328143c3dSStefano Zampini } 628428143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 6285779c1cceSStefano Zampini PetscMPIInt rank; 6286779c1cceSStefano Zampini 6287779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 628828143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 628928143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 629028143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 6291306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 629228143c3dSStefano Zampini } 629328143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 629428143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 629528143c3dSStefano Zampini } else { 629628143c3dSStefano Zampini comm_n = comm; 629728143c3dSStefano Zampini } 629828143c3dSStefano Zampini 6299e7931f94SStefano Zampini /* prepare send/receive buffers */ 6300785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 6301e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 6302785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 6303e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 630428143c3dSStefano Zampini if (nis) { 6305854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 630628143c3dSStefano Zampini } 6307e7931f94SStefano Zampini 630828143c3dSStefano Zampini /* Get data from local matrices */ 63096c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 6310e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 6311e7931f94SStefano Zampini /* 6312e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 6313e7931f94SStefano Zampini send_buffer_idxs should contain: 6314e7931f94SStefano Zampini - MatType_PRIVATE type 6315e7931f94SStefano Zampini - PetscInt size_of_l2gmap 6316e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 6317e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 6318e7931f94SStefano Zampini */ 63196c4ed002SBarry Smith else { 6320e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 63213bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 6322854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 6323e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 6324e7931f94SStefano Zampini send_buffer_idxs[1] = i; 63253bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6326e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 63273bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6328e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 6329e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6330e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 6331e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 6332c8587f34SStefano Zampini } 6333c8587f34SStefano Zampini } 6334e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 633528143c3dSStefano Zampini /* additional is (if any) */ 633628143c3dSStefano Zampini if (nis) { 633728143c3dSStefano Zampini PetscMPIInt psum; 633828143c3dSStefano Zampini PetscInt j; 633928143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 634028143c3dSStefano Zampini PetscInt plen; 634128143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 634228143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 634328143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 634428143c3dSStefano Zampini } 6345854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 634628143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 634728143c3dSStefano Zampini PetscInt plen; 634828143c3dSStefano Zampini const PetscInt *is_array_idxs; 634928143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 635028143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 635128143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 635228143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 635328143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 635428143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 635528143c3dSStefano Zampini } 635628143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 635728143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 635828143c3dSStefano Zampini } 635928143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 636028143c3dSStefano Zampini } 636128143c3dSStefano Zampini 6362e7931f94SStefano Zampini buf_size_idxs = 0; 6363e7931f94SStefano Zampini buf_size_vals = 0; 636428143c3dSStefano Zampini buf_size_idxs_is = 0; 63651ae86dd6SStefano Zampini buf_size_vecs = 0; 6366e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6367e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 6368e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 636928143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 63701ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 6371e7931f94SStefano Zampini } 6372785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 6373785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 637495ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 63751ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 6376e7931f94SStefano Zampini 6377e7931f94SStefano Zampini /* get new tags for clean communications */ 6378e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 6379e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 638028143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 63811ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 6382e7931f94SStefano Zampini 6383e7931f94SStefano Zampini /* allocate for requests */ 6384785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 6385785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 638695ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 63871ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 6388785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 6389785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 639095ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 63911ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 6392e7931f94SStefano Zampini 6393e7931f94SStefano Zampini /* communications */ 6394e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6395e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 639628143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 63971ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 6398e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6399e7931f94SStefano Zampini source_dest = onodes[i]; 6400e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 6401e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 6402e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6403e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 640428143c3dSStefano Zampini if (nis) { 640557de7509SStefano Zampini source_dest = onodes_is[i]; 640628143c3dSStefano 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); 640728143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 640828143c3dSStefano Zampini } 64091ae86dd6SStefano Zampini if (nvecs) { 64101ae86dd6SStefano Zampini source_dest = onodes[i]; 64111ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 64121ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 64131ae86dd6SStefano Zampini } 6414e7931f94SStefano Zampini } 6415e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6416e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 6417e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 6418e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 641928143c3dSStefano Zampini if (nis) { 642028143c3dSStefano 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); 642128143c3dSStefano Zampini } 64221ae86dd6SStefano Zampini if (nvecs) { 64231ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 64241ae86dd6SStefano 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); 64251ae86dd6SStefano Zampini } 6426e7931f94SStefano Zampini } 6427e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6428e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 6429e7931f94SStefano Zampini 6430e7931f94SStefano Zampini /* assemble new l2g map */ 6431e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6432e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 64339d30be91SStefano Zampini new_local_rows = 0; 6434e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 64359d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6436e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6437e7931f94SStefano Zampini } 64389d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 6439e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 64409d30be91SStefano Zampini new_local_rows = 0; 6441e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 64429d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 64439d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6444e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6445e7931f94SStefano Zampini } 64469d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 64479d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 6448e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 6449e7931f94SStefano Zampini 6450e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 6451e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 6452e7931f94SStefano 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) */ 6453e7931f94SStefano Zampini if (n_recvs) { 645428143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 6455e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6456e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6457e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 6458e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 6459e7931f94SStefano Zampini break; 6460e7931f94SStefano Zampini } 6461e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6462e7931f94SStefano Zampini } 6463e7931f94SStefano Zampini switch (new_local_type_private) { 646428143c3dSStefano Zampini case MATDENSE_PRIVATE: 646528143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 6466e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6467e7931f94SStefano Zampini bs = 1; 646828143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 646928143c3dSStefano Zampini new_local_type = MATSEQDENSE; 647028143c3dSStefano Zampini bs = 1; 647128143c3dSStefano Zampini } 6472e7931f94SStefano Zampini break; 6473e7931f94SStefano Zampini case MATAIJ_PRIVATE: 6474e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6475e7931f94SStefano Zampini bs = 1; 6476e7931f94SStefano Zampini break; 6477e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 6478e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 6479e7931f94SStefano Zampini break; 6480e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 6481e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 6482e7931f94SStefano Zampini break; 6483e7931f94SStefano Zampini default: 64849d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 6485e7931f94SStefano Zampini break; 6486e7931f94SStefano Zampini } 648728143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 648828143c3dSStefano Zampini new_local_type = MATSEQDENSE; 648928143c3dSStefano Zampini bs = 1; 6490e7931f94SStefano Zampini } 6491e7931f94SStefano Zampini 649270cf5478SStefano Zampini /* create MATIS object if needed */ 649357de7509SStefano Zampini if (!reuse) { 6494e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 6495e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 649670cf5478SStefano Zampini } else { 649770cf5478SStefano Zampini /* it also destroys the local matrices */ 649857de7509SStefano Zampini if (*mat_n) { 649970cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 650057de7509SStefano Zampini } else { /* this is a fake object */ 650157de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 650257de7509SStefano Zampini } 650370cf5478SStefano Zampini } 650470cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 6505e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 65069d30be91SStefano Zampini 65079d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 65089d30be91SStefano Zampini 65099d30be91SStefano Zampini /* Global to local map of received indices */ 65109d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 65119d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 65129d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 65139d30be91SStefano Zampini 65149d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 65159d30be91SStefano Zampini buf_size_idxs = 0; 65169d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 65179d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 65189d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 65199d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 65209d30be91SStefano Zampini } 65219d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 65229d30be91SStefano Zampini 65239d30be91SStefano Zampini /* set preallocation */ 65249d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 65259d30be91SStefano Zampini if (!newisdense) { 65269d30be91SStefano Zampini PetscInt *new_local_nnz=0; 65279d30be91SStefano Zampini 65289d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 65299d30be91SStefano Zampini if (n_recvs) { 65309d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 65319d30be91SStefano Zampini } 65329d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 65339d30be91SStefano Zampini PetscInt j; 65349d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 65359d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 65369d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 65379d30be91SStefano Zampini } 65389d30be91SStefano Zampini } else { 65399d30be91SStefano Zampini /* TODO */ 65409d30be91SStefano Zampini } 65419d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 65429d30be91SStefano Zampini } 65439d30be91SStefano Zampini if (new_local_nnz) { 65449d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 65459d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 65469d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 65479d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 65489d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 65499d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 65509d30be91SStefano Zampini } else { 65519d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 65529d30be91SStefano Zampini } 65539d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 65549d30be91SStefano Zampini } else { 65559d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 65569d30be91SStefano Zampini } 6557e7931f94SStefano Zampini 6558e7931f94SStefano Zampini /* set values */ 6559e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 65609d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 6561e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6562e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 6563e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 65649d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 6565e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6566e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6567e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 656828143c3dSStefano Zampini } else { 656928143c3dSStefano Zampini /* TODO */ 6570e7931f94SStefano Zampini } 6571e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6572e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 6573e7931f94SStefano Zampini } 6574e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6575e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 657670cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 657770cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 65789d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 6579e7931f94SStefano Zampini 6580dfd14d43SStefano Zampini #if 0 658128143c3dSStefano Zampini if (!restrict_comm) { /* check */ 6582e7931f94SStefano Zampini Vec lvec,rvec; 6583e7931f94SStefano Zampini PetscReal infty_error; 6584e7931f94SStefano Zampini 65852a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 6586e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 6587e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 6588e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 658970cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 6590e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 6591e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 6592e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 6593e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 6594e7931f94SStefano Zampini } 659528143c3dSStefano Zampini #endif 6596e7931f94SStefano Zampini 659728143c3dSStefano Zampini /* assemble new additional is (if any) */ 659828143c3dSStefano Zampini if (nis) { 659928143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 660028143c3dSStefano Zampini 660128143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6602854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 660328143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 660428143c3dSStefano Zampini psum = 0; 660528143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 660628143c3dSStefano Zampini for (j=0;j<nis;j++) { 660728143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 660828143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 660928143c3dSStefano Zampini psum += plen; 661028143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 661128143c3dSStefano Zampini } 661228143c3dSStefano Zampini } 6613854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 6614854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 661528143c3dSStefano Zampini for (i=1;i<nis;i++) { 661628143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 661728143c3dSStefano Zampini } 661828143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 661928143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 662028143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 662128143c3dSStefano Zampini for (j=0;j<nis;j++) { 662228143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 662328143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 662428143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 662528143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 662628143c3dSStefano Zampini } 662728143c3dSStefano Zampini } 662828143c3dSStefano Zampini for (i=0;i<nis;i++) { 662928143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 663028143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 663128143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 663228143c3dSStefano Zampini } 663328143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 663428143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 663528143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 663628143c3dSStefano Zampini } 6637e7931f94SStefano Zampini /* free workspace */ 663828143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 6639e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6640e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 6641e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6642e7931f94SStefano Zampini if (isdense) { 6643e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6644e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 6645e7931f94SStefano Zampini } else { 6646e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 6647e7931f94SStefano Zampini } 664828143c3dSStefano Zampini if (nis) { 664928143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 665028143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 665128143c3dSStefano Zampini } 66521ae86dd6SStefano Zampini 66531ae86dd6SStefano Zampini if (nvecs) { 66541ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 66551ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 66561ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 66571ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 66581ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 66591ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 66601ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 66611ae86dd6SStefano Zampini /* set values */ 66621ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 66631ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 66641ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 66651ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 66661ae86dd6SStefano Zampini PetscInt j; 66671ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 66681ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 66691ae86dd6SStefano Zampini } 66701ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 66711ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 66721ae86dd6SStefano Zampini } 66731ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 66741ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 66751ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 66761ae86dd6SStefano Zampini } 66771ae86dd6SStefano Zampini 66781ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 66791ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 6680e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 6681e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 66821ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 668328143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 6684e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 6685e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 66861ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 668728143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 6688e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 6689e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 6690e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 6691e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 6692e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 669328143c3dSStefano Zampini if (nis) { 669428143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 669528143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 669628143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 669728143c3dSStefano Zampini } 669828143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 669928143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 670028143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 670128143c3dSStefano Zampini for (i=0;i<nis;i++) { 670228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 670328143c3dSStefano Zampini } 67041ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 67051ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 67061ae86dd6SStefano Zampini } 670753a05cb3SStefano Zampini *mat_n = NULL; 670828143c3dSStefano Zampini } 6709e7931f94SStefano Zampini PetscFunctionReturn(0); 6710e7931f94SStefano Zampini } 6711a57a6d2fSStefano Zampini 671212edc857SStefano Zampini /* temporary hack into ksp private data structure */ 6713af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 671412edc857SStefano Zampini 6715c8587f34SStefano Zampini #undef __FUNCT__ 6716c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 6717c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 6718c8587f34SStefano Zampini { 6719c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6720c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 672120a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 67221ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 67239881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 672420a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 67256e683305SStefano Zampini IS coarse_is,*isarray; 67266e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 672730368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 6728f9eb5b7dSStefano Zampini PC pc_temp; 6729c8587f34SStefano Zampini PCType coarse_pc_type; 6730c8587f34SStefano Zampini KSPType coarse_ksp_type; 6731f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 67324f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 67336e683305SStefano Zampini Mat t_coarse_mat_is; 673457de7509SStefano Zampini PetscInt ncoarse; 673568457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 673622bc73bbSStefano Zampini PetscScalar *array; 673757de7509SStefano Zampini MatReuse coarse_mat_reuse; 673857de7509SStefano Zampini PetscBool restr, full_restr, have_void; 67399881197aSStefano Zampini PetscErrorCode ierr; 6740fdc09c96SStefano Zampini 6741c8587f34SStefano Zampini PetscFunctionBegin; 6742c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 674368457ee5SStefano 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 */ 6744fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 67455a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 6746fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 6747f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 6748f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 6749f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 6750fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 675151bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 675251bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 6753dc4bcba2SStefano Zampini PC pc; 6754dc4bcba2SStefano Zampini PetscBool isbddc; 6755dc4bcba2SStefano Zampini 6756dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 6757dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 6758dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 6759dc4bcba2SStefano Zampini if (isbddc) { 676063c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 676163c961adSStefano Zampini } else { 6762727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 676363c961adSStefano Zampini } 6764fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 6765fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 6766fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 6767f4ddd8eeSStefano Zampini } 6768fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 6769fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 6770f4ddd8eeSStefano Zampini } 677170cf5478SStefano Zampini /* reset any subassembling information */ 677257de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 677370cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 677457de7509SStefano Zampini } 67756e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 6776fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 6777f4ddd8eeSStefano Zampini } 677857de7509SStefano Zampini /* assemble coarse matrix */ 677957de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 678057de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 678157de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 678257de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 678318a45a71SStefano Zampini } else { 678457de7509SStefano Zampini coarse_mat = NULL; 678557de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 67866e683305SStefano Zampini } 6787e7931f94SStefano Zampini 6788abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 6789abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 6790abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 6791abbbba34SStefano Zampini 6792abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 679322bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 679422bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 679522bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 679622bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 6797e176bc59SStefano 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); 67986e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 67996e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 68006e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6801abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 6802abbbba34SStefano Zampini 680357de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 680457de7509SStefano Zampini im_active = !!(pcis->n); 680557de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 680657de7509SStefano Zampini 680714f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 680857de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 680957de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 681057de7509SStefano Zampini coarse_mat_is = NULL; 681157de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 681257de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 681357de7509SStefano Zampini full_restr = PETSC_TRUE; 68141ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 681557de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 681657de7509SStefano Zampini if (multilevel_requested) { 681757de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 681857de7509SStefano Zampini restr = PETSC_FALSE; 681957de7509SStefano Zampini full_restr = PETSC_FALSE; 682057de7509SStefano Zampini } else { 682157de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 682257de7509SStefano Zampini restr = PETSC_TRUE; 682357de7509SStefano Zampini full_restr = PETSC_TRUE; 682457de7509SStefano Zampini } 68254b2aedd3SStefano Zampini if (!pcbddc->coarse_size) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 682657de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 682757de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 6828a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 682957de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 6830a198735bSStefano Zampini } else { 6831a198735bSStefano Zampini PetscMPIInt size,rank; 6832a198735bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 6833a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 6834a198735bSStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 6835a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 6836a198735bSStefano Zampini } 683757de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 683857de7509SStefano Zampini PetscInt psum; 683957de7509SStefano Zampini PetscMPIInt size; 684057de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 684157de7509SStefano Zampini else psum = 0; 684257de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 684357de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 684457de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 684557de7509SStefano Zampini } 684657de7509SStefano Zampini /* determine if we can go multilevel */ 684757de7509SStefano Zampini if (multilevel_requested) { 684857de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 684957de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 685057de7509SStefano Zampini } 685157de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 685257de7509SStefano Zampini 6853e4d548c7SStefano Zampini /* dump subassembling pattern */ 6854e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 6855e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 6856e4d548c7SStefano Zampini } 6857e4d548c7SStefano Zampini 68586e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 685927b6a85dSStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal)) { /* protects from unneded computations */ 68606e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 68616e683305SStefano Zampini const PetscInt *idxs; 68626e683305SStefano Zampini ISLocalToGlobalMapping tmap; 68636e683305SStefano Zampini 68646e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 68650be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 68666e683305SStefano Zampini /* allocate space for temporary storage */ 6867854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 6868854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 68696e683305SStefano Zampini /* allocate for IS array */ 68706e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 68716e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 687227b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 687330368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 6874854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 68756e683305SStefano Zampini /* dofs splitting */ 68766e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 68776e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 68786e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 68796e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 68806e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 68816e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 68826e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 688330368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 68846e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 68856e683305SStefano Zampini } 68866e683305SStefano Zampini /* neumann boundaries */ 68876e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 68886e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 68896e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 68906e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 68916e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 68926e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 68936e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 689430368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 68956e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 68966e683305SStefano Zampini } 68976e683305SStefano Zampini /* free memory */ 68986e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 68996e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 69006e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 69016e683305SStefano Zampini } else { 69026e683305SStefano Zampini nis = 0; 69036e683305SStefano Zampini nisdofs = 0; 69046e683305SStefano Zampini nisneu = 0; 690530368db7SStefano Zampini nisvert = 0; 69066e683305SStefano Zampini isarray = NULL; 69076e683305SStefano Zampini } 69086e683305SStefano Zampini /* destroy no longer needed map */ 69096e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 69106e683305SStefano Zampini 691157de7509SStefano Zampini /* subassemble */ 691257de7509SStefano Zampini if (multilevel_allowed) { 69131ae86dd6SStefano Zampini Vec vp[1]; 69141ae86dd6SStefano Zampini PetscInt nvecs = 0; 691557de7509SStefano Zampini PetscBool reuse,reuser; 69161ae86dd6SStefano Zampini 691757de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 691857de7509SStefano Zampini else reuse = PETSC_FALSE; 691957de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 69201ae86dd6SStefano Zampini vp[0] = NULL; 69211ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 69221ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 69231ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 69241ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 69251ae86dd6SStefano Zampini nvecs = 1; 69261ae86dd6SStefano Zampini 69271ae86dd6SStefano Zampini if (pcbddc->divudotp) { 6928a198735bSStefano Zampini Mat B,loc_divudotp; 69291ae86dd6SStefano Zampini Vec v,p; 69301ae86dd6SStefano Zampini IS dummy; 69311ae86dd6SStefano Zampini PetscInt np; 69321ae86dd6SStefano Zampini 6933a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 6934a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 69351ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 6936a198735bSStefano Zampini ierr = MatGetSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 69371ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 69381ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 69391ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 69401ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 69411ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 69421ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 69431ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 69441ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 69451ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 69461ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 69471ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 69481ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 694974e2c79eSStefano Zampini } 69501ae86dd6SStefano Zampini } 69511ae86dd6SStefano Zampini if (reuser) { 69521ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 695374e2c79eSStefano Zampini } else { 69541ae86dd6SStefano 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); 69551ae86dd6SStefano Zampini } 69561ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 69571ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 69581ae86dd6SStefano Zampini PetscInt nl; 69591ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 69601ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 69611ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 69621ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 69631ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 69641ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 69651ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 69661ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 6967a198735bSStefano Zampini } else { 6968a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 69691ae86dd6SStefano Zampini } 69701ae86dd6SStefano Zampini } else { 69711ae86dd6SStefano 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); 69726e683305SStefano Zampini } 697357de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 697457de7509SStefano Zampini PetscMPIInt size; 697557de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size); 697657de7509SStefano Zampini if (!multilevel_allowed) { 697757de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 69786e683305SStefano Zampini } else { 697957de7509SStefano Zampini Mat A; 6980779c1cceSStefano Zampini 698157de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 698257de7509SStefano Zampini if (coarse_mat_is) { 698357de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 698457de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 698557de7509SStefano Zampini coarse_mat = coarse_mat_is; 698657de7509SStefano Zampini } 698757de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 698857de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 698957de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 6990779c1cceSStefano Zampini } 6991779c1cceSStefano Zampini } 699257de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 699357de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 69946e683305SStefano Zampini 69956e683305SStefano Zampini /* create local to global scatters for coarse problem */ 699668457ee5SStefano Zampini if (compute_vecs) { 69976e683305SStefano Zampini PetscInt lrows; 69986e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 699957de7509SStefano Zampini if (coarse_mat) { 700057de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 70016e683305SStefano Zampini } else { 70026e683305SStefano Zampini lrows = 0; 70036e683305SStefano Zampini } 70046e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 70056e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 70066e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 70076e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 70086e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 70096e683305SStefano Zampini } 70106e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 7011c8587f34SStefano Zampini 7012f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 7013f9eb5b7dSStefano Zampini if (multilevel_allowed) { 7014f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 7015f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 7016f9eb5b7dSStefano Zampini } else { 7017f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 7018f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 7019c8587f34SStefano Zampini } 7020c8587f34SStefano Zampini 70216e683305SStefano Zampini /* print some info if requested */ 70226e683305SStefano Zampini if (pcbddc->dbg_flag) { 70236e683305SStefano Zampini if (!multilevel_allowed) { 70246e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 70256e683305SStefano Zampini if (multilevel_requested) { 70266e683305SStefano 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); 70276e683305SStefano Zampini } else if (pcbddc->max_levels) { 70286e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 70296e683305SStefano Zampini } 70306e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 70316e683305SStefano Zampini } 70326e683305SStefano Zampini } 70336e683305SStefano Zampini 7034f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 703557de7509SStefano Zampini if (coarse_mat) { 70366a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 70376e683305SStefano Zampini if (pcbddc->dbg_flag) { 703857de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 70396e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 70406e683305SStefano Zampini } 7041f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 7042312be037SStefano Zampini char prefix[256],str_level[16]; 7043e604994aSStefano Zampini size_t len; 704457de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 7045422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 7046c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 7047f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 704857de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7049c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 70506e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 7051c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 7052c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7053e604994aSStefano Zampini /* prefix */ 7054e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 7055e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 7056e604994aSStefano Zampini if (!pcbddc->current_level) { 7057e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 7058e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 7059c8587f34SStefano Zampini } else { 7060e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 7061312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 7062312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 706334d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 7064312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 7065e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 7066e604994aSStefano Zampini } 7067e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 70683e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 70693e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 70703e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 70713e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 7072f9eb5b7dSStefano Zampini /* allow user customization */ 7073f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 70743e3c6dadSStefano Zampini } 70753e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 707651bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 70773e3c6dadSStefano Zampini if (nisdofs) { 70783e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 70793e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 70803e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 70813e3c6dadSStefano Zampini } 70823e3c6dadSStefano Zampini } 70833e3c6dadSStefano Zampini if (nisneu) { 70843e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 70853e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 7086312be037SStefano Zampini } 708730368db7SStefano Zampini if (nisvert) { 708830368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 708930368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 709030368db7SStefano Zampini } 7091f9eb5b7dSStefano Zampini 7092f9eb5b7dSStefano Zampini /* get some info after set from options */ 7093f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 7094f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 70954f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 70966e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 7097f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7098f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 7099f9eb5b7dSStefano Zampini } 710039f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 71014f3a063dSStefano Zampini if (isredundant) { 71024f3a063dSStefano Zampini KSP inner_ksp; 71034f3a063dSStefano Zampini PC inner_pc; 71044f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 71054f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 71064f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 71074f3a063dSStefano Zampini } 7108f9eb5b7dSStefano Zampini 710957de7509SStefano Zampini /* parameters which miss an API */ 711057de7509SStefano Zampini if (isbddc) { 7111720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 7112720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 711357de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 711427b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 711527b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 7116a198735bSStefano Zampini Mat coarsedivudotp_is; 7117a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 7118a198735bSStefano Zampini IS row,col; 7119a198735bSStefano Zampini const PetscInt *gidxs; 7120a198735bSStefano Zampini PetscInt n,st,M,N; 7121a198735bSStefano Zampini 7122a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 7123a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 7124a198735bSStefano Zampini st = st-n; 7125a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 7126a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 7127a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 7128a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7129a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 7130a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7131a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 7132a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 7133a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 7134a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 7135a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 7136a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 7137a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 7138a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 7139a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 7140a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 7141a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7142a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7143a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 7144a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 71458ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 7146a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 7147720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 714859e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 7149720d30f9SStefano Zampini } 7150d4d8cf7bSStefano Zampini } 71519881197aSStefano Zampini 71523301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 71535a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 71543301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 71553301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 71563301b35fSStefano Zampini } 71573301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 71583301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 71593301b35fSStefano Zampini } 71603301b35fSStefano Zampini if (pc->pmat->spd_set) { 71613301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 71623301b35fSStefano Zampini } 716327b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 716427b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 716527b6a85dSStefano Zampini } 71666e683305SStefano Zampini /* set operators */ 71675f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 71686e683305SStefano Zampini if (pcbddc->dbg_flag) { 71696e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 71706e683305SStefano Zampini } 71716e683305SStefano Zampini } 71726e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 7173b1ecc7b1SStefano Zampini #if 0 7174b9b85e73SStefano Zampini { 7175b9b85e73SStefano Zampini PetscViewer viewer; 7176b9b85e73SStefano Zampini char filename[256]; 7177b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 7178b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 71796a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 7180b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 7181f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 7182b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 7183b9b85e73SStefano Zampini } 7184b9b85e73SStefano Zampini #endif 7185f9eb5b7dSStefano Zampini 718698a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 718798a51de6SStefano Zampini Vec crhs,csol; 718804708bb6SStefano Zampini 7189f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 7190f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 7191f347579bSStefano Zampini if (!csol) { 71922a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 7193f9eb5b7dSStefano Zampini } 7194f347579bSStefano Zampini if (!crhs) { 71952a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 7196f347579bSStefano Zampini } 7197b0f5fe93SStefano Zampini } 71981ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 7199b0f5fe93SStefano Zampini 7200b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 7201b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 7202b0f5fe93SStefano Zampini 7203b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 72044f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 72054f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 72064f1b2e48SStefano Zampini } 7207b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 7208b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 7209b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7210b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7211b0f5fe93SStefano Zampini if (coarse_mat) { 7212b0f5fe93SStefano Zampini Vec nullv; 7213b0f5fe93SStefano Zampini PetscScalar *array,*array2; 7214b0f5fe93SStefano Zampini PetscInt nl; 7215b0f5fe93SStefano Zampini 7216b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 7217b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 7218b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7219b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 7220b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 7221b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 7222b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7223b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 7224b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 7225b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 7226b0f5fe93SStefano Zampini } 7227b0f5fe93SStefano Zampini } 7228b0f5fe93SStefano Zampini 7229b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 7230b0f5fe93SStefano Zampini PetscBool ispreonly; 7231b0f5fe93SStefano Zampini 7232b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7233b0f5fe93SStefano Zampini PetscBool isnull; 7234b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 7235bef83e63SStefano Zampini if (isnull) { 7236b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 7237b0f5fe93SStefano Zampini } 7238bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 7239b0f5fe93SStefano Zampini } 7240b0f5fe93SStefano Zampini /* setup coarse ksp */ 7241b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 7242cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 7243cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 72446e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 7245c8587f34SStefano Zampini KSP check_ksp; 72462b510759SStefano Zampini KSPType check_ksp_type; 7247c8587f34SStefano Zampini PC check_pc; 72486e683305SStefano Zampini Vec check_vec,coarse_vec; 72496a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 72502b510759SStefano Zampini PetscInt its; 72516e683305SStefano Zampini PetscBool compute_eigs; 72526e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 72536e683305SStefano Zampini PetscInt neigs; 72548e185a42SStefano Zampini const char *prefix; 7255c8587f34SStefano Zampini 72562b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 72576e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 7258422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 725923ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7260f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 7261e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 7262e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 7263e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 72642b510759SStefano Zampini if (ispreonly) { 72652b510759SStefano Zampini check_ksp_type = KSPPREONLY; 72666e683305SStefano Zampini compute_eigs = PETSC_FALSE; 72672b510759SStefano Zampini } else { 7268cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 72696e683305SStefano Zampini compute_eigs = PETSC_TRUE; 7270c8587f34SStefano Zampini } 7271c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 72726e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 72736e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 72746e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 7275a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 7276a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 7277a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 7278a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 7279c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 7280c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 7281c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 7282c8587f34SStefano Zampini /* create random vec */ 72832701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 7284c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 72856e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 7286c8587f34SStefano Zampini /* solve coarse problem */ 72876e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 7288cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 72896e683305SStefano Zampini if (compute_eigs) { 7290854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 7291854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 72926e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 72931ae86dd6SStefano Zampini if (neigs) { 72946e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 72956e683305SStefano Zampini lambda_min = eigs_r[0]; 72966e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 72972701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 72982701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 7299cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 7300cbcc2c2aSStefano Zampini } 7301c8587f34SStefano Zampini } 7302c8587f34SStefano Zampini } 73031ae86dd6SStefano Zampini } 7304cbcc2c2aSStefano Zampini 7305c8587f34SStefano Zampini /* check coarse problem residual error */ 73066e683305SStefano Zampini if (pcbddc->dbg_flag) { 73076e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 73086e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 73096e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 7310c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 73116e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 73126e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 7313779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 73146e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 73156e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 73166e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 73176e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 7318b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7319b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 7320b0f5fe93SStefano Zampini } 73216e683305SStefano Zampini if (compute_eigs) { 73226e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 7323deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 7324c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 73256e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 73266e683305SStefano 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); 73276e683305SStefano Zampini for (i=0;i<neigs;i++) { 73286e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 7329c8587f34SStefano Zampini } 73306e683305SStefano Zampini } 73316e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 73326e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 73336e683305SStefano Zampini } 7334e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 73352701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 7336c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 73376e683305SStefano Zampini if (compute_eigs) { 73386e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 73396e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 7340c8587f34SStefano Zampini } 73416e683305SStefano Zampini } 73426e683305SStefano Zampini } 7343bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 7344cbcc2c2aSStefano Zampini /* print additional info */ 7345cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 73466e683305SStefano Zampini /* waits until all processes reaches this point */ 73476e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 7348cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 7349cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7350cbcc2c2aSStefano Zampini } 7351cbcc2c2aSStefano Zampini 73522b510759SStefano Zampini /* free memory */ 7353fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 7354c8587f34SStefano Zampini PetscFunctionReturn(0); 7355c8587f34SStefano Zampini } 7356674ae819SStefano Zampini 7357f34684f1SStefano Zampini #undef __FUNCT__ 7358f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 7359f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 7360f34684f1SStefano Zampini { 7361f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7362f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 7363f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 7364dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 7365dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 736673be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 7367dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 7368f34684f1SStefano Zampini PetscErrorCode ierr; 7369f34684f1SStefano Zampini 7370f34684f1SStefano Zampini PetscFunctionBegin; 7371f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 73726c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 7373dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 73743bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 7375dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7376dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 73776583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 7378dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 7379dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 7380dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 73816c4ed002SBarry 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); 7382dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 7383dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7384dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 7385dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7386dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7387f34684f1SStefano Zampini 7388f34684f1SStefano Zampini /* check numbering */ 7389f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 7390019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 7391dc456d91SStefano Zampini PetscInt i; 7392b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 7393f34684f1SStefano Zampini 7394f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7395f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 7396f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 73971575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7398019a44ceSStefano Zampini /* counter */ 7399019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7400019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 7401019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7402019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7403019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7404019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7405f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 7406f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 7407727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 7408f34684f1SStefano Zampini } 7409f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7410f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7411f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7412e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7413e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7414e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7415e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7416f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7417019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7418f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7419019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 74202c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 742175c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 7422b9b85e73SStefano Zampini set_error = PETSC_TRUE; 74232c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 74242c66d082SStefano 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); 7425f34684f1SStefano Zampini } 7426f34684f1SStefano Zampini } 7427019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7428b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 7429f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7430f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7431f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 7432f34684f1SStefano Zampini } 7433f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7434f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7435e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7436e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7437f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 7438f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 7439b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 7440ca8b9ea9SStefano Zampini PetscInt *gidxs; 7441ca8b9ea9SStefano Zampini 7442ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 74433bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 7444f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 7445f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7446f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 7447f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 74484bc2dc4bSStefano 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); 7449f34684f1SStefano Zampini } 7450f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7451ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 7452f34684f1SStefano Zampini } 7453f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 74541575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7455302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 7456f34684f1SStefano Zampini } 74578bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 7458f34684f1SStefano Zampini /* get back data */ 7459f34684f1SStefano Zampini *coarse_size_n = coarse_size; 7460f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 7461674ae819SStefano Zampini PetscFunctionReturn(0); 7462674ae819SStefano Zampini } 7463674ae819SStefano Zampini 7464e456f2a8SStefano Zampini #undef __FUNCT__ 7465e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 7466a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 7467e456f2a8SStefano Zampini { 7468e456f2a8SStefano Zampini IS localis_t; 7469a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 7470e456f2a8SStefano Zampini PetscScalar *vals; 7471e456f2a8SStefano Zampini PetscErrorCode ierr; 7472e456f2a8SStefano Zampini 7473e456f2a8SStefano Zampini PetscFunctionBegin; 7474a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 7475e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 7476854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 7477e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 7478e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7479a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 7480a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 74811035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 7482a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 74831035eff8SStefano Zampini } 7484a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 7485e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7486e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 7487a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 7488a7dc3881SStefano Zampini /* now compute set in local ordering */ 7489a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7490a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7491a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7492a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 7493a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7494ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7495e456f2a8SStefano Zampini lsize++; 7496e456f2a8SStefano Zampini } 7497e456f2a8SStefano Zampini } 7498854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 7499a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7500ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7501e456f2a8SStefano Zampini idxs[lsize++] = i; 7502e456f2a8SStefano Zampini } 7503e456f2a8SStefano Zampini } 7504a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7505a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 7506e456f2a8SStefano Zampini *localis = localis_t; 7507e456f2a8SStefano Zampini PetscFunctionReturn(0); 7508e456f2a8SStefano Zampini } 7509906d46d4SStefano Zampini 7510b96c3477SStefano Zampini #undef __FUNCT__ 7511b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 751208122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 7513b96c3477SStefano Zampini { 7514a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7515b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7516b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 7517a64f4aa4SStefano Zampini Mat S_j; 7518b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 7519b96c3477SStefano Zampini PetscBool free_used_adj; 7520b96c3477SStefano Zampini PetscErrorCode ierr; 7521b96c3477SStefano Zampini 7522b96c3477SStefano Zampini PetscFunctionBegin; 7523b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 7524b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 752508122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 7526b96c3477SStefano Zampini used_xadj = NULL; 7527b96c3477SStefano Zampini used_adjncy = NULL; 7528b96c3477SStefano Zampini } else { 752908122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 753008122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 753108122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 753208122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 7533b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 7534b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 7535b96c3477SStefano Zampini } else { 75362fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 7537b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 7538b96c3477SStefano Zampini PetscInt nvtxs; 7539b96c3477SStefano Zampini 75402fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 75412fffb893SStefano Zampini if (flg_row) { 7542b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 7543b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 7544b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 7545b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 75462fffb893SStefano Zampini } else { 75472fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 75482fffb893SStefano Zampini used_xadj = NULL; 75492fffb893SStefano Zampini used_adjncy = NULL; 75502fffb893SStefano Zampini } 75512fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 7552b96c3477SStefano Zampini } 7553b96c3477SStefano Zampini } 7554d5574798SStefano Zampini 7555d5574798SStefano Zampini /* setup sub_schurs data */ 7556a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 7557df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 7558df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 7559a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 756091af6908SStefano 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); 7561a64f4aa4SStefano Zampini } else { 75626816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 75634d7f8f00SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE; 7564a3df083aSStefano Zampini PetscInt benign_n; 756572b8c272SStefano Zampini Mat change = NULL; 75669d54b7f4SStefano Zampini Vec scaling = NULL; 756772b8c272SStefano Zampini IS change_primal = NULL; 7568a3df083aSStefano Zampini 75695feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 75705feab87aSStefano Zampini PetscInt n_vertices; 75715feab87aSStefano Zampini 75725feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 75732034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 75745feab87aSStefano Zampini } 757504708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 757604708bb6SStefano Zampini if (!isseqaij) { 757704708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 757804708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 757904708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 758004708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 758104708bb6SStefano Zampini } else { 7582511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 758304708bb6SStefano Zampini } 758404708bb6SStefano Zampini } 7585a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 7586a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 7587ca92afb2SStefano Zampini } else { 7588a3df083aSStefano Zampini benign_n = 0; 7589ca92afb2SStefano Zampini } 7590b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 7591b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 7592b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 759372b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 759422db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 7595b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 759622db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 7597b7ab4a40SStefano Zampini } 7598b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 7599b7ab4a40SStefano 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 */ 7600b7ab4a40SStefano Zampini if (need_change) { 760188c03ad3SStefano Zampini PC_IS *pcisf; 760288c03ad3SStefano Zampini PC_BDDC *pcbddcf; 760388c03ad3SStefano Zampini PC pcf; 760488c03ad3SStefano Zampini 7605e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 760688c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 760788c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 760888c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 760988c03ad3SStefano Zampini /* hacks */ 761088c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 761172b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 761272b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 761372b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 761472b8c272SStefano Zampini pcisf->n = pcis->n; 761572b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 761688c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 761788c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 761888c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 761988c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 762088c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 762188c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 762272b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 762388c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 762488c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 762572b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 762672b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 762772b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 762872b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 762972b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 763088c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 763172b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 763288c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 763388c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 763488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 763588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 763688c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 763788c03ad3SStefano Zampini pcf->ops->destroy = NULL; 763888c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 763988c03ad3SStefano Zampini } 76409d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 764191af6908SStefano 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); 764272b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 764372b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 7644ca92afb2SStefano Zampini } 7645d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 7646b96c3477SStefano Zampini 7647b96c3477SStefano Zampini /* free adjacency */ 7648b96c3477SStefano Zampini if (free_used_adj) { 7649b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 7650b96c3477SStefano Zampini } 7651b96c3477SStefano Zampini PetscFunctionReturn(0); 7652b96c3477SStefano Zampini } 7653b96c3477SStefano Zampini 7654b96c3477SStefano Zampini #undef __FUNCT__ 7655b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 765608122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 7657b96c3477SStefano Zampini { 7658b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7659b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7660b96c3477SStefano Zampini PCBDDCGraph graph; 7661b96c3477SStefano Zampini PetscErrorCode ierr; 7662b96c3477SStefano Zampini 7663b96c3477SStefano Zampini PetscFunctionBegin; 7664b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 766508122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 76663301b35fSStefano Zampini IS verticesIS,verticescomm; 76673301b35fSStefano Zampini PetscInt vsize,*idxs; 7668b96c3477SStefano Zampini 7669b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 76703301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 76713301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 76723301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 76733301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 7674c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 7675b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 7676be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 7677441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 76783301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 7679b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 7680b96c3477SStefano Zampini } else { 7681b96c3477SStefano Zampini graph = pcbddc->mat_graph; 7682b96c3477SStefano Zampini } 7683e4d548c7SStefano Zampini /* print some info */ 7684e4d548c7SStefano Zampini if (pcbddc->dbg_flag) { 7685e4d548c7SStefano Zampini IS vertices; 7686e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 7687c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 7688e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 7689e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 7690e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7691e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 7692e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 7693e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 7694e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 7695e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7696e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7697c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 7698e4d548c7SStefano Zampini } 7699b96c3477SStefano Zampini 7700b96c3477SStefano Zampini /* sub_schurs init */ 7701b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 7702b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 7703b334f244SStefano Zampini } 7704b334f244SStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 7705a64f4aa4SStefano Zampini 7706b96c3477SStefano Zampini /* free graph struct */ 770708122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 7708b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 7709b96c3477SStefano Zampini } 7710b96c3477SStefano Zampini PetscFunctionReturn(0); 7711b96c3477SStefano Zampini } 7712fa34dd3eSStefano Zampini 7713fa34dd3eSStefano Zampini #undef __FUNCT__ 7714fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 7715fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 7716fa34dd3eSStefano Zampini { 7717fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7718fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7719fa34dd3eSStefano Zampini PetscErrorCode ierr; 7720fa34dd3eSStefano Zampini 7721fa34dd3eSStefano Zampini PetscFunctionBegin; 7722fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 7723fa34dd3eSStefano Zampini IS zerodiag = NULL; 77244f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 7725fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 77264f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 772775c01103SStefano Zampini PetscReal norm; 7728fa34dd3eSStefano Zampini PetscInt i; 7729fa34dd3eSStefano Zampini 7730fa34dd3eSStefano Zampini /* B0 and B0_B */ 7731fa34dd3eSStefano Zampini if (zerodiag) { 7732fa34dd3eSStefano Zampini IS dummy; 7733fa34dd3eSStefano Zampini 77344f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 77354f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 7736fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 7737fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 7738fa34dd3eSStefano Zampini } 7739fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 7740fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 7741fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 7742fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7743fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7744fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7745fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7746fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 7747fa34dd3eSStefano Zampini /* S_j */ 7748fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 7749fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 7750fa34dd3eSStefano Zampini 7751fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 7752fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 7753fa34dd3eSStefano Zampini /* continuous in primal space */ 7754fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 7755fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7756fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7757fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 77584f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 77594f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 7760fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 7761fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7762fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7763fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7764fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7765fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7766fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 7767fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 7768fa34dd3eSStefano Zampini 7769fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 7770fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 7771fa34dd3eSStefano Zampini /* local with Schur */ 7772fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 7773fa34dd3eSStefano Zampini if (zerodiag) { 7774fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 77754f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 7776fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 7777fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 7778fa34dd3eSStefano Zampini } 7779fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 7780fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7781fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7782fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7783fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 7784fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 7785fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 7786fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7787fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 7788fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7789fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7790fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7791fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7792fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7793fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 7794fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 7795fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 7796fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7797fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7798fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7799fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7800fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7801fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 7802fa34dd3eSStefano Zampini if (zerodiag) { 7803fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 7804fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 78054f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 7806fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 7807fa34dd3eSStefano Zampini } 7808fa34dd3eSStefano Zampini /* BDDC */ 7809fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 7810fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 7811fa34dd3eSStefano Zampini 7812fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 7813fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 7814fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 7815fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 78164f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 78174f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 7818fa34dd3eSStefano Zampini } 78194f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 7820fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 7821fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 7822fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 7823fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 7824fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 7825fa34dd3eSStefano Zampini } 7826fa34dd3eSStefano Zampini PetscFunctionReturn(0); 7827fa34dd3eSStefano Zampini } 7828