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 71e0482f5SStefano Zampini static PetscErrorCode MatMPIAIJRestrict(Mat,MPI_Comm,Mat*); 81e0482f5SStefano Zampini 9f498cd09SStefano Zampini /* if range is true, it returns B s.t. span{B} = range(A) 10f498cd09SStefano Zampini if range is false, it returns B s.t. range(B) _|_ range(A) */ 11a13144ffSStefano Zampini #undef __FUNCT__ 12f498cd09SStefano Zampini #define __FUNCT__ "MatDenseOrthogonalRangeOrComplement" 13f498cd09SStefano Zampini PetscErrorCode MatDenseOrthogonalRangeOrComplement(Mat A, PetscBool range, PetscInt lw, PetscScalar *work, PetscReal *rwork, Mat *B) 14a13144ffSStefano Zampini { 15a13144ffSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 16a13144ffSStefano Zampini PetscScalar *uwork,*data,*U, ds = 0.; 17a13144ffSStefano Zampini PetscReal *sing; 18a13144ffSStefano Zampini PetscBLASInt bM,bN,lwork,lierr,di = 1; 19a13144ffSStefano Zampini PetscInt ulw,i,nr,nc,n; 20a13144ffSStefano Zampini PetscErrorCode ierr; 21a13144ffSStefano Zampini 22a13144ffSStefano Zampini PetscFunctionBegin; 23a13144ffSStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 24a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"LAPACK _GESVD not available"); 25*614dbb09SStefano Zampini #else 26a13144ffSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 27a13144ffSStefano Zampini if (!nr || !nc) PetscFunctionReturn(0); 28a13144ffSStefano Zampini 29a13144ffSStefano Zampini /* workspace */ 30a13144ffSStefano Zampini if (!work) { 31a13144ffSStefano Zampini ulw = PetscMax(PetscMax(1,5*PetscMin(nr,nc)),3*PetscMin(nr,nc)+PetscMax(nr,nc)); 32f913dca9SStefano Zampini ierr = PetscMalloc1(ulw,&uwork);CHKERRQ(ierr); 33a13144ffSStefano Zampini } else { 34a13144ffSStefano Zampini ulw = lw; 35a13144ffSStefano Zampini uwork = work; 36a13144ffSStefano Zampini } 37a13144ffSStefano Zampini n = PetscMin(nr,nc); 38a13144ffSStefano Zampini if (!rwork) { 39a13144ffSStefano Zampini ierr = PetscMalloc1(n,&sing);CHKERRQ(ierr); 40a13144ffSStefano Zampini } else { 41a13144ffSStefano Zampini sing = rwork; 42a13144ffSStefano Zampini } 43a13144ffSStefano Zampini 44a13144ffSStefano Zampini /* SVD */ 45a13144ffSStefano Zampini ierr = PetscMalloc1(nr*nr,&U);CHKERRQ(ierr); 46a13144ffSStefano Zampini ierr = PetscBLASIntCast(nr,&bM);CHKERRQ(ierr); 47a13144ffSStefano Zampini ierr = PetscBLASIntCast(nc,&bN);CHKERRQ(ierr); 48a13144ffSStefano Zampini ierr = PetscBLASIntCast(ulw,&lwork);CHKERRQ(ierr); 49a13144ffSStefano Zampini ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); 50a13144ffSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 51a13144ffSStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,&lierr)); 52a13144ffSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 53a13144ffSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 54a13144ffSStefano Zampini ierr = MatDenseRestoreArray(A,&data);CHKERRQ(ierr); 55a13144ffSStefano Zampini for (i=0;i<n;i++) if (sing[i] < PETSC_SMALL) break; 56a13144ffSStefano Zampini if (!rwork) { 57a13144ffSStefano Zampini ierr = PetscFree(sing);CHKERRQ(ierr); 58a13144ffSStefano Zampini } 59a13144ffSStefano Zampini if (!work) { 60a13144ffSStefano Zampini ierr = PetscFree(uwork);CHKERRQ(ierr); 61a13144ffSStefano Zampini } 62a13144ffSStefano Zampini /* create B */ 63f498cd09SStefano Zampini if (!range) { 64a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 65a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 66a13144ffSStefano Zampini ierr = PetscMemcpy(data,U+nr*i,(nr-i)*nr*sizeof(PetscScalar));CHKERRQ(ierr); 67f498cd09SStefano Zampini } else { 68f498cd09SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,i,NULL,B);CHKERRQ(ierr); 69f498cd09SStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 70f498cd09SStefano Zampini ierr = PetscMemcpy(data,U,i*nr*sizeof(PetscScalar));CHKERRQ(ierr); 71f498cd09SStefano Zampini } 72a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 73a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 74*614dbb09SStefano Zampini #endif 75*614dbb09SStefano Zampini #else /* PETSC_USE_COMPLEX */ 76a13144ffSStefano Zampini PetscFunctionBegin; 77a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for complexes"); 78a13144ffSStefano Zampini #endif 79a13144ffSStefano Zampini PetscFunctionReturn(0); 80a13144ffSStefano Zampini } 81a13144ffSStefano Zampini 821e0482f5SStefano Zampini /* TODO REMOVE */ 831e0482f5SStefano Zampini #if defined(PRINT_GDET) 841e0482f5SStefano Zampini static int inc = 0; 851e0482f5SStefano Zampini static int lev = 0; 861e0482f5SStefano Zampini #endif 871e0482f5SStefano Zampini 88a13144ffSStefano Zampini #undef __FUNCT__ 89a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCComputeNedelecChangeEdge" 901e0482f5SStefano Zampini PetscErrorCode PCBDDCComputeNedelecChangeEdge(Mat lG, IS edge, IS extrow, IS extcol, IS corners, Mat* Gins, Mat* GKins, PetscScalar cvals[2], PetscScalar *work, PetscReal *rwork) 91a13144ffSStefano Zampini { 92a13144ffSStefano Zampini PetscErrorCode ierr; 93a13144ffSStefano Zampini Mat GE,GEd; 94a13144ffSStefano Zampini PetscInt rsize,csize,esize; 95a13144ffSStefano Zampini PetscScalar *ptr; 96a13144ffSStefano Zampini 97a13144ffSStefano Zampini PetscFunctionBegin; 98a13144ffSStefano Zampini ierr = ISGetSize(edge,&esize);CHKERRQ(ierr); 99c3c0e390SStefano Zampini if (!esize) PetscFunctionReturn(0); 100a13144ffSStefano Zampini ierr = ISGetSize(extrow,&rsize);CHKERRQ(ierr); 101a13144ffSStefano Zampini ierr = ISGetSize(extcol,&csize);CHKERRQ(ierr); 102a13144ffSStefano Zampini 103a13144ffSStefano Zampini /* gradients */ 104a13144ffSStefano Zampini ptr = work + 5*esize; 105a13144ffSStefano Zampini ierr = MatGetSubMatrix(lG,extrow,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 106a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,rsize,csize,ptr,Gins);CHKERRQ(ierr); 107a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,Gins);CHKERRQ(ierr); 108a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 109a13144ffSStefano Zampini 110a13144ffSStefano Zampini /* constants */ 111a13144ffSStefano Zampini ptr += rsize*csize; 112a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,esize,csize,ptr,&GEd);CHKERRQ(ierr); 113a13144ffSStefano Zampini ierr = MatGetSubMatrix(lG,edge,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 114a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,&GEd);CHKERRQ(ierr); 115a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 116f498cd09SStefano Zampini ierr = MatDenseOrthogonalRangeOrComplement(GEd,PETSC_FALSE,5*esize,work,rwork,GKins);CHKERRQ(ierr); 117a13144ffSStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1181e0482f5SStefano Zampini 1191e0482f5SStefano Zampini if (corners) { 1201e0482f5SStefano Zampini Mat GEc; 1211e0482f5SStefano Zampini PetscScalar *vals,v; 1221e0482f5SStefano Zampini 1231e0482f5SStefano Zampini ierr = MatGetSubMatrix(lG,edge,corners,MAT_INITIAL_MATRIX,&GEc);CHKERRQ(ierr); 1241e0482f5SStefano Zampini ierr = MatTransposeMatMult(GEc,*GKins,MAT_INITIAL_MATRIX,1.0,&GEd);CHKERRQ(ierr); 1251e0482f5SStefano Zampini ierr = MatDenseGetArray(GEd,&vals);CHKERRQ(ierr); 126637e8532SStefano Zampini /* v = PetscAbsScalar(vals[0]) */; 127637e8532SStefano Zampini v = 1.; 1281e0482f5SStefano Zampini cvals[0] = vals[0]/v; 1291e0482f5SStefano Zampini cvals[1] = vals[1]/v; 1301e0482f5SStefano Zampini ierr = MatDenseRestoreArray(GEd,&vals);CHKERRQ(ierr); 1311e0482f5SStefano Zampini ierr = MatScale(*GKins,1./v);CHKERRQ(ierr); 1321e0482f5SStefano Zampini #if defined(PRINT_GDET) 1331e0482f5SStefano Zampini { 1341e0482f5SStefano Zampini PetscViewer viewer; 1351e0482f5SStefano Zampini char filename[256]; 1361e0482f5SStefano Zampini sprintf(filename,"Gdet_l%d_r%d_cc%d.m",lev,PetscGlobalRank,inc++); 1371e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1381e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1391e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEc,"GEc");CHKERRQ(ierr); 1401e0482f5SStefano Zampini ierr = MatView(GEc,viewer);CHKERRQ(ierr); 1411e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)(*GKins),"GK");CHKERRQ(ierr); 1421e0482f5SStefano Zampini ierr = MatView(*GKins,viewer);CHKERRQ(ierr); 1431e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEd,"Gproj");CHKERRQ(ierr); 1441e0482f5SStefano Zampini ierr = MatView(GEd,viewer);CHKERRQ(ierr); 1451e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1461e0482f5SStefano Zampini } 1471e0482f5SStefano Zampini #endif 1481e0482f5SStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1491e0482f5SStefano Zampini ierr = MatDestroy(&GEc);CHKERRQ(ierr); 1501e0482f5SStefano Zampini } 1511e0482f5SStefano Zampini 152a13144ffSStefano Zampini PetscFunctionReturn(0); 153a13144ffSStefano Zampini } 154a13144ffSStefano Zampini 155a13144ffSStefano Zampini #undef __FUNCT__ 156a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCNedelecSupport" 157a13144ffSStefano Zampini PetscErrorCode PCBDDCNedelecSupport(PC pc) 158a13144ffSStefano Zampini { 159a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 160a13144ffSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1610569b399SStefano Zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe,lGinit; 162eee23b56SStefano Zampini Vec tvec; 163a13144ffSStefano Zampini PetscSF sfv; 1641e0482f5SStefano Zampini ISLocalToGlobalMapping el2g,vl2g,fl2g,al2g; 165a13144ffSStefano Zampini MPI_Comm comm; 166c2151214SStefano Zampini IS lned,primals,allprimals,nedfieldlocal; 167c2151214SStefano Zampini IS *eedges,*extrows,*extcols,*alleedges; 1687d871cd7SStefano Zampini PetscBT btv,bte,btvc,btb,btbd,btvcand,btvi,btee,bter; 169a13144ffSStefano Zampini PetscScalar *vals,*work; 170a13144ffSStefano Zampini PetscReal *rwork; 171a13144ffSStefano Zampini const PetscInt *idxs,*ii,*jj,*iit,*jjt; 1721e0482f5SStefano Zampini PetscInt ne,nv,Lv,order,n,field; 173a13144ffSStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 174eee23b56SStefano Zampini PetscInt i,j,extmem,cum,maxsize,nee; 175b03ebc13SStefano Zampini PetscInt *extrow,*extrowcum,*marks,*vmarks,*gidxs; 176a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 177b03ebc13SStefano Zampini PetscInt *corners,*cedges; 178637e8532SStefano Zampini PetscInt *ecount,**eneighs,*vcount,**vneighs; 179b03ebc13SStefano Zampini #if defined(PETSC_USE_DEBUG) 180b03ebc13SStefano Zampini PetscInt *emarks; 181b03ebc13SStefano Zampini #endif 1821e0482f5SStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,global; 183a13144ffSStefano Zampini PetscErrorCode ierr; 184a13144ffSStefano Zampini 185a13144ffSStefano Zampini PetscFunctionBegin; 186a13144ffSStefano Zampini /* test variable order code and print debug info TODO: to be removed */ 187a13144ffSStefano Zampini print = PETSC_FALSE; 188a13144ffSStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_print_nedelec",&print,NULL);CHKERRQ(ierr); 189a13144ffSStefano Zampini ierr = PetscOptionsGetInt(NULL,NULL,"-pc_bddc_nedelec_order",&pcbddc->nedorder,NULL);CHKERRQ(ierr); 190a13144ffSStefano Zampini 191a13144ffSStefano Zampini /* Return to caller if there are no edges in the decomposition */ 192a13144ffSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 1931e0482f5SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&al2g,NULL);CHKERRQ(ierr); 1941e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(al2g,&n);CHKERRQ(ierr); 195a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 196a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 197c2151214SStefano Zampini for (i=0;i<n;i++) { 198a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 199a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 200a13144ffSStefano Zampini break; 201a13144ffSStefano Zampini } 202a13144ffSStefano Zampini } 203a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 204a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 205a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 206a13144ffSStefano Zampini 2071e0482f5SStefano Zampini /* If the discrete gradient is defined for a subset of dofs and global is true, 2081e0482f5SStefano Zampini it assumes G is given in global ordering for all the dofs. 2091e0482f5SStefano Zampini Otherwise, the ordering is global for the Nedelec field */ 210a13144ffSStefano Zampini order = pcbddc->nedorder; 211a13144ffSStefano Zampini conforming = pcbddc->conforming; 212c2151214SStefano Zampini field = pcbddc->nedfield; 2131e0482f5SStefano Zampini global = pcbddc->nedglobal; 214c2151214SStefano 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); 215c2151214SStefano Zampini if (pcbddc->n_ISForDofsLocal && field > -1) { 2161e0482f5SStefano Zampini PetscBool setprimal = PETSC_FALSE; 2171e0482f5SStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_nedelec_field_primal",&setprimal,NULL);CHKERRQ(ierr); 218c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 219c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 220c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 2211e0482f5SStefano Zampini if (setprimal) { 222eee23b56SStefano Zampini IS enedfieldlocal; 223eee23b56SStefano Zampini PetscInt *eidxs; 224eee23b56SStefano Zampini 225eee23b56SStefano Zampini ierr = PetscMalloc1(ne,&eidxs);CHKERRQ(ierr); 226eee23b56SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 227eee23b56SStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 228eee23b56SStefano Zampini for (i=0,cum=0;i<ne;i++) { 229eee23b56SStefano Zampini if (PetscRealPart(vals[idxs[i]]) > 2.) { 230eee23b56SStefano Zampini eidxs[cum++] = idxs[i]; 231eee23b56SStefano Zampini } 232eee23b56SStefano Zampini } 233eee23b56SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 234eee23b56SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 235eee23b56SStefano Zampini ierr = ISCreateGeneral(comm,cum,eidxs,PETSC_COPY_VALUES,&enedfieldlocal);CHKERRQ(ierr); 236eee23b56SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,enedfieldlocal);CHKERRQ(ierr); 237eee23b56SStefano Zampini ierr = PetscFree(eidxs);CHKERRQ(ierr); 2381e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 239eee23b56SStefano Zampini ierr = ISDestroy(&enedfieldlocal);CHKERRQ(ierr); 2401e0482f5SStefano Zampini PetscFunctionReturn(0); 2411e0482f5SStefano Zampini } 2421e0482f5SStefano Zampini } else if (!pcbddc->n_ISForDofsLocal) { 243c2151214SStefano Zampini PetscBool testnedfield = PETSC_FALSE; 244c2151214SStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_nedelec_field",&testnedfield,NULL);CHKERRQ(ierr); 245c2151214SStefano Zampini if (!testnedfield) { 246c2151214SStefano Zampini ne = n; 247c2151214SStefano Zampini nedfieldlocal = NULL; 248c2151214SStefano Zampini } else { 249c2151214SStefano Zampini /* ierr = ISCreateStride(comm,n,0,1,&nedfieldlocal);CHKERRQ(ierr); */ 250c2151214SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 251c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 252c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 253c2151214SStefano Zampini for (i=0;i<n;i++) matis->sf_leafdata[i] = 1; 254c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 255c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 256c2151214SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 257c2151214SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 258c2151214SStefano Zampini for (i=0,cum=0;i<n;i++) { 259c2151214SStefano Zampini if (matis->sf_leafdata[i] > 1) { 260c2151214SStefano Zampini matis->sf_leafdata[cum++] = i; 261c2151214SStefano Zampini } 262c2151214SStefano Zampini } 263c2151214SStefano Zampini ierr = ISCreateGeneral(comm,cum,matis->sf_leafdata,PETSC_COPY_VALUES,&nedfieldlocal);CHKERRQ(ierr); 264c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 265c2151214SStefano Zampini } 2661e0482f5SStefano Zampini global = PETSC_TRUE; 2671e0482f5SStefano Zampini } else { 2681e0482f5SStefano Zampini SETERRQ(comm,PETSC_ERR_USER,"When multiple fields are present, the Nedelec field has to be specified"); 269c2151214SStefano Zampini } 270a13144ffSStefano Zampini 271c2151214SStefano Zampini if (nedfieldlocal) { /* merge with previous code when testing is done */ 272c2151214SStefano Zampini IS is; 273c2151214SStefano Zampini 274c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 275c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 2761e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering for the whole dofs*/ 2771e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(al2g,nedfieldlocal,&is);CHKERRQ(ierr); 2781e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&al2g);CHKERRQ(ierr); 2791e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering (for Nedelec only) */ 2801e0482f5SStefano Zampini if (global) { 2811e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 2821e0482f5SStefano Zampini el2g = al2g; 2831e0482f5SStefano Zampini } else { 2841e0482f5SStefano Zampini IS gis; 2851e0482f5SStefano Zampini 2861e0482f5SStefano Zampini ierr = ISRenumber(is,NULL,NULL,&gis);CHKERRQ(ierr); 2871e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gis,&el2g);CHKERRQ(ierr); 2881e0482f5SStefano Zampini ierr = ISDestroy(&gis);CHKERRQ(ierr); 2891e0482f5SStefano Zampini } 290c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 291c2151214SStefano Zampini } else { 2921e0482f5SStefano Zampini /* restore default */ 2931e0482f5SStefano Zampini pcbddc->nedfield = -1; 2941e0482f5SStefano Zampini /* one ref for the destruction of al2g, one for el2g */ 2951e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 2961e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 2971e0482f5SStefano Zampini el2g = al2g; 298c2151214SStefano Zampini fl2g = NULL; 299c2151214SStefano Zampini } 300a13144ffSStefano Zampini 301a13144ffSStefano Zampini /* Sanity checks */ 302a13144ffSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 303a13144ffSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 304a13144ffSStefano 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); 305a13144ffSStefano Zampini 3061e0482f5SStefano Zampini /* Drop connections for interior edges */ 3071e0482f5SStefano Zampini ierr = MatDuplicate(pcbddc->discretegradient,MAT_COPY_VALUES,&G);CHKERRQ(ierr); 3081e0482f5SStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 309c2151214SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 310c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 311c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 312c2151214SStefano Zampini if (nedfieldlocal) { 313c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 314c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 315c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 316c2151214SStefano Zampini } else { 317c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 318c2151214SStefano Zampini } 319c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 320c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 3211e0482f5SStefano Zampini if (global) { 3221e0482f5SStefano Zampini PetscInt rst; 3231e0482f5SStefano Zampini 324c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 325c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 326c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 327c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 328c2151214SStefano Zampini } 329c2151214SStefano Zampini } 330a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 331c2151214SStefano Zampini ierr = MatZeroRows(G,cum,matis->sf_rootdata,0.,NULL,NULL);CHKERRQ(ierr); 3321e0482f5SStefano Zampini } else { 3331e0482f5SStefano Zampini PetscInt *tbz; 3341e0482f5SStefano Zampini 3351e0482f5SStefano Zampini ierr = PetscMalloc1(ne,&tbz);CHKERRQ(ierr); 3361e0482f5SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3371e0482f5SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3381e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3391e0482f5SStefano Zampini for (i=0,cum=0;i<ne;i++) 3401e0482f5SStefano Zampini if (matis->sf_leafdata[idxs[i]] == 1) 3411e0482f5SStefano Zampini tbz[cum++] = i; 3421e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3431e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApply(el2g,cum,tbz,tbz);CHKERRQ(ierr); 3441e0482f5SStefano Zampini ierr = MatZeroRows(G,cum,tbz,0.,NULL,NULL);CHKERRQ(ierr); 3451e0482f5SStefano Zampini ierr = PetscFree(tbz);CHKERRQ(ierr); 3461e0482f5SStefano Zampini } 347a13144ffSStefano Zampini 348a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 349a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 350a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 351a13144ffSStefano Zampini ierr = MatGetSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 352a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 353a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 354a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 355a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 356a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 357a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 358a13144ffSStefano Zampini if (print) { 359a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 360a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 361a13144ffSStefano Zampini } 362a13144ffSStefano Zampini 363a13144ffSStefano Zampini /* SF for nodal communications */ 364c2151214SStefano Zampini ierr = MatGetLocalSize(G,NULL,&Lv);CHKERRQ(ierr); 365a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 366a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 367a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 368a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 369a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 370a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 371a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 372a13144ffSStefano Zampini ierr = PetscMalloc2(nv,&sfvleaves,Lv,&sfvroots);CHKERRQ(ierr); 373a13144ffSStefano Zampini 3741e0482f5SStefano Zampini /* Destroy temporary G created in MATIS format and modified G */ 3751e0482f5SStefano Zampini ierr = MatDestroy(&G);CHKERRQ(ierr); 376a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 377a13144ffSStefano Zampini 3780569b399SStefano Zampini /* Save lG */ 3790569b399SStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGinit);CHKERRQ(ierr); 3800569b399SStefano Zampini 381a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 3824e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 3834e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 384a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 385a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 386a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 3877d871cd7SStefano Zampini ierr = PetscBTCreate(ne,&btbd);CHKERRQ(ierr); 388c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 389a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 390a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 391a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 392c2151214SStefano Zampini IS is; 393c2151214SStefano Zampini 394c2151214SStefano Zampini if (fl2g) { 395c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 396c2151214SStefano Zampini } else { 397c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 398c2151214SStefano Zampini } 399c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 400c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 401a13144ffSStefano Zampini for (i=0;i<cum;i++) { 402a13144ffSStefano Zampini if (idxs[i] >= 0) { 403a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 4047d871cd7SStefano Zampini ierr = PetscBTSet(btbd,idxs[i]);CHKERRQ(ierr); 405a13144ffSStefano Zampini } 406a13144ffSStefano Zampini } 407c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 408c2151214SStefano Zampini if (fl2g) { 409c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 410c2151214SStefano Zampini } 411a13144ffSStefano Zampini } 412a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 413c2151214SStefano Zampini IS is; 414c2151214SStefano Zampini 415c2151214SStefano Zampini if (fl2g) { 416c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 417c2151214SStefano Zampini } else { 418c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 419c2151214SStefano Zampini } 420c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 421c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 422a13144ffSStefano Zampini for (i=0;i<cum;i++) { 423a13144ffSStefano Zampini if (idxs[i] >= 0) { 424a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 425a13144ffSStefano Zampini } 426a13144ffSStefano Zampini } 427c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 428c2151214SStefano Zampini if (fl2g) { 429c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 430a13144ffSStefano Zampini } 431c2151214SStefano Zampini } 432c2151214SStefano Zampini 433637e8532SStefano Zampini /* count neighs per dof */ 434637e8532SStefano Zampini ierr = PetscCalloc1(ne,&ecount);CHKERRQ(ierr); 435637e8532SStefano Zampini ierr = PetscMalloc1(ne,&eneighs);CHKERRQ(ierr); 436637e8532SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 437637e8532SStefano Zampini for (i=1,cum=0;i<n_neigh;i++) { 438637e8532SStefano Zampini cum += n_shared[i]; 439637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 440637e8532SStefano Zampini ecount[shared[i][j]]++; 441637e8532SStefano Zampini } 442637e8532SStefano Zampini } 443637e8532SStefano Zampini if (ne) { 444637e8532SStefano Zampini ierr = PetscMalloc1(cum,&eneighs[0]);CHKERRQ(ierr); 445637e8532SStefano Zampini } 446637e8532SStefano Zampini for (i=1;i<ne;i++) eneighs[i] = eneighs[i-1] + ecount[i-1]; 447637e8532SStefano Zampini ierr = PetscMemzero(ecount,ne*sizeof(PetscInt));CHKERRQ(ierr); 448637e8532SStefano Zampini for (i=1;i<n_neigh;i++) { 449637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 450637e8532SStefano Zampini PetscInt k = shared[i][j]; 451637e8532SStefano Zampini eneighs[k][ecount[k]] = neigh[i]; 452637e8532SStefano Zampini ecount[k]++; 453637e8532SStefano Zampini } 454637e8532SStefano Zampini } 455637e8532SStefano Zampini for (i=0;i<ne;i++) { 456637e8532SStefano Zampini ierr = PetscSortRemoveDupsInt(&ecount[i],eneighs[i]);CHKERRQ(ierr); 457637e8532SStefano Zampini } 458637e8532SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 459637e8532SStefano Zampini ierr = PetscCalloc1(nv,&vcount);CHKERRQ(ierr); 460637e8532SStefano Zampini ierr = PetscMalloc1(nv,&vneighs);CHKERRQ(ierr); 461637e8532SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 462637e8532SStefano Zampini for (i=1,cum=0;i<n_neigh;i++) { 463637e8532SStefano Zampini cum += n_shared[i]; 464637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 465637e8532SStefano Zampini vcount[shared[i][j]]++; 466637e8532SStefano Zampini } 467637e8532SStefano Zampini } 468637e8532SStefano Zampini if (nv) { 469637e8532SStefano Zampini ierr = PetscMalloc1(cum,&vneighs[0]);CHKERRQ(ierr); 470637e8532SStefano Zampini } 471637e8532SStefano Zampini for (i=1;i<nv;i++) vneighs[i] = vneighs[i-1] + vcount[i-1]; 472637e8532SStefano Zampini ierr = PetscMemzero(vcount,nv*sizeof(PetscInt));CHKERRQ(ierr); 473637e8532SStefano Zampini for (i=1;i<n_neigh;i++) { 474637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 475637e8532SStefano Zampini PetscInt k = shared[i][j]; 476637e8532SStefano Zampini vneighs[k][vcount[k]] = neigh[i]; 477637e8532SStefano Zampini vcount[k]++; 478637e8532SStefano Zampini } 479637e8532SStefano Zampini } 480637e8532SStefano Zampini for (i=0;i<nv;i++) { 481637e8532SStefano Zampini ierr = PetscSortRemoveDupsInt(&vcount[i],vneighs[i]);CHKERRQ(ierr); 482637e8532SStefano Zampini } 483637e8532SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 484637e8532SStefano Zampini 4857d871cd7SStefano Zampini /* need to remove coarse faces' dofs and coarse edges' dirichlet dofs 4867d871cd7SStefano Zampini for proper detection of coarse edges' endpoints */ 48762b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 48862b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 4897d871cd7SStefano Zampini if ((ecount[i] > 1 && !PetscBTLookup(btbd,i)) || (ecount[i] == 1 && PetscBTLookup(btb,i))) { 49062b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 49162b0c6f7SStefano Zampini } 49262b0c6f7SStefano Zampini } 493637e8532SStefano Zampini ierr = PetscMalloc1(ne,&marks);CHKERRQ(ierr); 49462b0c6f7SStefano Zampini if (!conforming) { 49562b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 49662b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 49762b0c6f7SStefano Zampini } 4984e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 499dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 50062b0c6f7SStefano Zampini cum = 0; 501a13144ffSStefano Zampini for (i=0;i<ne;i++) { 502dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 50362b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 504a13144ffSStefano Zampini marks[cum++] = i; 505dec27d64SStefano Zampini continue; 506dec27d64SStefano Zampini } 507dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 50862b0c6f7SStefano Zampini if (!conforming) { 50962b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 510a13144ffSStefano Zampini marks[cum++] = i; 511a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 512a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 513a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 514a13144ffSStefano Zampini } 51562b0c6f7SStefano Zampini } else { 51662b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 51762b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 51862b0c6f7SStefano Zampini - at most 2 endpoints 51962b0c6f7SStefano Zampini - order-1 interior nodal dofs 52062b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 52162b0c6f7SStefano Zampini */ 52262b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 52362b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 52462b0c6f7SStefano Zampini PetscInt v = jj[j],k; 52562b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 52662b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 52762b0c6f7SStefano Zampini if (nconn > order) ends++; 52862b0c6f7SStefano Zampini else if (nconn == order) ints++; 52962b0c6f7SStefano Zampini else undef++; 53062b0c6f7SStefano Zampini } 53162b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 53262b0c6f7SStefano Zampini marks[cum++] = i; 53362b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 53462b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 53562b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 53662b0c6f7SStefano Zampini } 53762b0c6f7SStefano Zampini } 53862b0c6f7SStefano Zampini } 539a13144ffSStefano Zampini } 540dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 541dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 542dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 543dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 544a13144ffSStefano Zampini } 545dec27d64SStefano Zampini } 54662b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 547dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 5484e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 54962b0c6f7SStefano Zampini if (!conforming) { 55062b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 55162b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 55262b0c6f7SStefano Zampini } 5534e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 554637e8532SStefano Zampini 555b03ebc13SStefano Zampini /* identify splitpoints and corner candidates */ 5564e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 557a13144ffSStefano Zampini if (print) { 5584e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 5594e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 5604e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 561a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 562a13144ffSStefano Zampini } 563a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 564dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 565a13144ffSStefano Zampini for (i=0;i<nv;i++) { 566637e8532SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i], vc = vcount[i]; 5677d871cd7SStefano Zampini PetscBool sneighs = PETSC_TRUE, bdir = PETSC_FALSE; 568b03ebc13SStefano Zampini if (!order) { /* variable order */ 569dec27d64SStefano Zampini PetscReal vorder = 0.; 570dec27d64SStefano Zampini 571dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 572dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 573dec27d64SStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%d)",vorder,test); 574dec27d64SStefano Zampini ord = 1; 575dec27d64SStefano Zampini } 576a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 577dec27d64SStefano 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); 578a13144ffSStefano Zampini #endif 579637e8532SStefano Zampini for (j=ii[i];j<ii[i+1] && sneighs;j++) { 5807d871cd7SStefano Zampini if (PetscBTLookup(btbd,jj[j])) { 5817d871cd7SStefano Zampini bdir = PETSC_TRUE; 5827d871cd7SStefano Zampini break; 5837d871cd7SStefano Zampini } 584637e8532SStefano Zampini if (vc != ecount[jj[j]]) { 585637e8532SStefano Zampini sneighs = PETSC_FALSE; 586637e8532SStefano Zampini } else { 587637e8532SStefano Zampini PetscInt k,*vn = vneighs[i], *en = eneighs[jj[j]]; 588637e8532SStefano Zampini for (k=0;k<vc;k++) { 589637e8532SStefano Zampini if (vn[k] != en[k]) { 590637e8532SStefano Zampini sneighs = PETSC_FALSE; 591637e8532SStefano Zampini break; 592637e8532SStefano Zampini } 593637e8532SStefano Zampini } 594637e8532SStefano Zampini } 595637e8532SStefano Zampini } 5967d871cd7SStefano Zampini if (!sneighs || test >= 3*ord || bdir) { /* splitpoints */ 5977d871cd7SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d (%d %d %d)\n",i,!sneighs,test >= 3*ord,bdir); 598a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 599dec27d64SStefano Zampini } else if (test == ord) { 600b03ebc13SStefano Zampini if (order == 1 || (!order && ii[i+1]-ii[i] == 1)) { 601a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 602a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 603a13144ffSStefano Zampini } else { 604a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 605a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 606a13144ffSStefano Zampini } 607a13144ffSStefano Zampini } 608a13144ffSStefano Zampini } 609637e8532SStefano Zampini ierr = PetscFree(ecount);CHKERRQ(ierr); 610637e8532SStefano Zampini ierr = PetscFree(vcount);CHKERRQ(ierr); 611637e8532SStefano Zampini if (ne) { 612637e8532SStefano Zampini ierr = PetscFree(eneighs[0]);CHKERRQ(ierr); 613637e8532SStefano Zampini } 614637e8532SStefano Zampini if (nv) { 615637e8532SStefano Zampini ierr = PetscFree(vneighs[0]);CHKERRQ(ierr); 616637e8532SStefano Zampini } 617637e8532SStefano Zampini ierr = PetscFree(eneighs);CHKERRQ(ierr); 618637e8532SStefano Zampini ierr = PetscFree(vneighs);CHKERRQ(ierr); 6197d871cd7SStefano Zampini ierr = PetscBTDestroy(&btbd);CHKERRQ(ierr); 620b03ebc13SStefano Zampini 621b03ebc13SStefano Zampini /* a candidate is valid if it is connected to another candidate via a non-primal edge dof */ 622b03ebc13SStefano Zampini if (order != 1) { 623b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSPECTING CANDIDATES\n"); 624b03ebc13SStefano Zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 625b03ebc13SStefano Zampini for (i=0;i<nv;i++) { 626b03ebc13SStefano Zampini if (PetscBTLookup(btvcand,i)) { 627b03ebc13SStefano Zampini PetscBool found = PETSC_FALSE; 628b03ebc13SStefano Zampini for (j=ii[i];j<ii[i+1] && !found;j++) { 629b03ebc13SStefano Zampini PetscInt k,e = jj[j]; 630b03ebc13SStefano Zampini if (PetscBTLookup(bte,e)) continue; 631b03ebc13SStefano Zampini for (k=iit[e];k<iit[e+1];k++) { 632b03ebc13SStefano Zampini PetscInt v = jjt[k]; 633b03ebc13SStefano Zampini if (v != i && PetscBTLookup(btvcand,v)) { 634b03ebc13SStefano Zampini found = PETSC_TRUE; 635b03ebc13SStefano Zampini break; 636b03ebc13SStefano Zampini } 637b03ebc13SStefano Zampini } 638b03ebc13SStefano Zampini } 639b03ebc13SStefano Zampini if (!found) { 640b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d CLEARED\n",i); 641b03ebc13SStefano Zampini ierr = PetscBTClear(btvcand,i);CHKERRQ(ierr); 642b03ebc13SStefano Zampini } else { 643b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d ACCEPTED\n",i); 644b03ebc13SStefano Zampini } 645b03ebc13SStefano Zampini } 646b03ebc13SStefano Zampini } 647b03ebc13SStefano Zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 648b03ebc13SStefano Zampini } 649dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 650a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 651b03ebc13SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 652a13144ffSStefano Zampini 653a13144ffSStefano Zampini /* Get the local G^T explicitly */ 6540569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 655a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 6564e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 657a13144ffSStefano Zampini 6584e64d54eSstefano_zampini /* Mark interior nodal dofs */ 659a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6604e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 661a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 662a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 6634e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 664a13144ffSStefano Zampini } 665a13144ffSStefano Zampini } 666a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 667a13144ffSStefano Zampini 668a13144ffSStefano Zampini /* communicate corners and splitpoints */ 669a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 670a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 671a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 672a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 673a13144ffSStefano Zampini 674a13144ffSStefano Zampini if (print) { 675a13144ffSStefano Zampini IS tbz; 676a13144ffSStefano Zampini 677a13144ffSStefano Zampini cum = 0; 678a13144ffSStefano Zampini for (i=0;i<nv;i++) 679a13144ffSStefano Zampini if (sfvleaves[i]) 680a13144ffSStefano Zampini vmarks[cum++] = i; 681a13144ffSStefano Zampini 682a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 683a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 684a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 685a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 686a13144ffSStefano Zampini } 687a13144ffSStefano Zampini 688a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 689a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 690a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 691a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 692a13144ffSStefano Zampini 6934e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 6944e64d54eSstefano_zampini and interior nodal dofs */ 695a13144ffSStefano Zampini cum = 0; 696a13144ffSStefano Zampini for (i=0;i<nv;i++) { 697a13144ffSStefano Zampini if (sfvleaves[i]) { 698a13144ffSStefano Zampini vmarks[cum++] = i; 699a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 700a13144ffSStefano Zampini } 7014e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 702a13144ffSStefano Zampini } 7034e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 704a13144ffSStefano Zampini if (print) { 705a13144ffSStefano Zampini IS tbz; 706a13144ffSStefano Zampini 707a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 7084e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 709a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 710a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 711a13144ffSStefano Zampini } 712a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 713a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 714a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 715a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 716a13144ffSStefano Zampini 717a13144ffSStefano Zampini /* Recompute G */ 718a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 719a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 720a13144ffSStefano Zampini if (print) { 721a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 722a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 723a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 724a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 725a13144ffSStefano Zampini } 726a13144ffSStefano Zampini 727a13144ffSStefano Zampini /* Get primal dofs (if any) */ 728a13144ffSStefano Zampini cum = 0; 729a13144ffSStefano Zampini for (i=0;i<ne;i++) { 730a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 731a13144ffSStefano Zampini } 732c2151214SStefano Zampini if (fl2g) { 733c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 734c2151214SStefano Zampini } 735a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 736a13144ffSStefano Zampini if (print) { 737a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 738a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 739a13144ffSStefano Zampini } 740a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 741c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 742a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 743a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 744a13144ffSStefano Zampini 745a13144ffSStefano Zampini /* Compute edge connectivity */ 746a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 747a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 748a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 749c2151214SStefano Zampini if (fl2g) { 750c2151214SStefano Zampini PetscBT btf; 751c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 752c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 753c2151214SStefano Zampini 754c2151214SStefano Zampini /* create CSR for all local dofs */ 755c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 756c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 757c2151214SStefano 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); 758c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 759c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 760c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 761c2151214SStefano Zampini rest = PETSC_TRUE; 762c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 763c2151214SStefano Zampini } else { 764c2151214SStefano Zampini free = PETSC_TRUE; 765c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 766c2151214SStefano Zampini iiu[0] = 0; 767c2151214SStefano Zampini for (i=0;i<n;i++) { 768c2151214SStefano Zampini iiu[i+1] = i+1; 769c2151214SStefano Zampini jju[i] = -1; 770d904f53bSStefano Zampini } 771c2151214SStefano Zampini } 772c2151214SStefano Zampini 773c2151214SStefano Zampini /* import sizes of CSR */ 774c2151214SStefano Zampini iia[0] = 0; 775c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 776c2151214SStefano Zampini 777c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 778c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 779c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 780c2151214SStefano Zampini for (i=0;i<ne;i++) { 781c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 782c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 783c2151214SStefano Zampini } 784c2151214SStefano Zampini 785c2151214SStefano Zampini /* iia in CSR */ 786c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 787c2151214SStefano Zampini 788c2151214SStefano Zampini /* jja in CSR */ 789c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 790c2151214SStefano Zampini for (i=0;i<n;i++) 791c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 792c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 793c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 794c2151214SStefano Zampini 795c2151214SStefano Zampini /* map edge dofs connectivity */ 7961e0482f5SStefano Zampini if (jj) { 797c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 798c2151214SStefano Zampini for (i=0;i<ne;i++) { 799c2151214SStefano Zampini PetscInt e = idxs[i]; 800c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 801c2151214SStefano Zampini } 8021e0482f5SStefano Zampini } 803c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 804c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 805c2151214SStefano Zampini if (rest) { 806c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 807c2151214SStefano Zampini } 808c2151214SStefano Zampini if (free) { 809c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 810c2151214SStefano Zampini } 811c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 812c2151214SStefano Zampini } else { 8131e0482f5SStefano Zampini if (jj) { 814c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 815c2151214SStefano Zampini } 816c2151214SStefano Zampini } 817c2151214SStefano Zampini 818a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 819a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 820a13144ffSStefano Zampini 821a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 822c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 823a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 824a13144ffSStefano Zampini 825c2151214SStefano Zampini if (fl2g) { 826c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 827c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 828c2151214SStefano Zampini for (i=0;i<nee;i++) { 829c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 830c2151214SStefano Zampini } 831c2151214SStefano Zampini } else { 832c2151214SStefano Zampini eedges = alleedges; 833c2151214SStefano Zampini primals = allprimals; 834c2151214SStefano Zampini } 835c2151214SStefano Zampini 836a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 837a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 838c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 839c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 840c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 841c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 842c2151214SStefano Zampini if (print) { 843c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 844c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 845c2151214SStefano Zampini } 846c2151214SStefano Zampini 847c2151214SStefano Zampini maxsize = 0; 848a13144ffSStefano Zampini for (i=0;i<nee;i++) { 849a13144ffSStefano Zampini PetscInt size,mark = i+1; 850a13144ffSStefano Zampini 851a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 852a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 853a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 854a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 855a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 856a13144ffSStefano Zampini } 857a13144ffSStefano Zampini 858a13144ffSStefano Zampini /* Find coarse edge endpoints */ 859a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 860a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 861a13144ffSStefano Zampini for (i=0;i<nee;i++) { 862a13144ffSStefano Zampini PetscInt mark = i+1,size; 863a13144ffSStefano Zampini 864a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8651e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8661e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 867a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 868a13144ffSStefano Zampini if (print) { 869a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 870a13144ffSStefano Zampini ISView(eedges[i],NULL); 871a13144ffSStefano Zampini } 872a13144ffSStefano Zampini for (j=0;j<size;j++) { 873a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 874a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 875a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 876a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 877a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 878a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 879a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 880a13144ffSStefano Zampini PetscInt k2; 881a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 882a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 883c2151214SStefano 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])); 884c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 885c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 886c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 887a13144ffSStefano Zampini corner = PETSC_TRUE; 888a13144ffSStefano Zampini break; 889a13144ffSStefano Zampini } 890a13144ffSStefano Zampini } 891a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 892a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 893a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 894a13144ffSStefano Zampini } else { 895a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 896a13144ffSStefano Zampini } 897a13144ffSStefano Zampini } 898a13144ffSStefano Zampini } 899a13144ffSStefano Zampini } 900a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 901a13144ffSStefano Zampini } 902a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 903a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 904c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 905a13144ffSStefano Zampini 906a13144ffSStefano Zampini /* Reset marked primal dofs */ 907a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 908a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 909a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 910a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 911a13144ffSStefano Zampini 9120569b399SStefano Zampini /* Now use the initial lG */ 9130569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 9140569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 9150569b399SStefano Zampini lG = lGinit; 9160569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 9170569b399SStefano Zampini 918a13144ffSStefano Zampini /* Compute extended cols indices */ 919b03ebc13SStefano Zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 920b03ebc13SStefano Zampini ierr = PetscBTCreate(nee,&bter);CHKERRQ(ierr); 921a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 922a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 923a13144ffSStefano Zampini i *= maxsize; 924b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 925a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 926a13144ffSStefano Zampini eerr = PETSC_FALSE; 927a13144ffSStefano Zampini for (i=0;i<nee;i++) { 928b03ebc13SStefano Zampini PetscInt size,found = 0; 929a13144ffSStefano Zampini 930a13144ffSStefano Zampini cum = 0; 931a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 9321e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 9331e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 934a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 935b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 936a13144ffSStefano Zampini for (j=0;j<size;j++) { 937a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 938b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 939b03ebc13SStefano Zampini PetscInt vv = jj[k]; 940b03ebc13SStefano Zampini if (!PetscBTLookup(btv,vv)) extrow[cum++] = vv; 941b03ebc13SStefano Zampini else if (!PetscBTLookupSet(btvc,vv)) found++; 942b03ebc13SStefano Zampini } 943a13144ffSStefano Zampini } 944a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 945a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 946a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 947a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 948a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 949a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 950a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 951b03ebc13SStefano Zampini if (cum != size -1 || found != 2) { 952b03ebc13SStefano Zampini ierr = PetscBTSet(bter,i);CHKERRQ(ierr); 953a13144ffSStefano Zampini if (print) { 954a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 955a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 956a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 957a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 958a13144ffSStefano Zampini } 959a13144ffSStefano Zampini eerr = PETSC_TRUE; 960a13144ffSStefano Zampini } 961a13144ffSStefano Zampini } 9624e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 963a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 964a13144ffSStefano Zampini if (done) { 965a13144ffSStefano Zampini PetscInt *newprimals; 966a13144ffSStefano Zampini 967a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 968a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 969a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 970a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 971a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 9720569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 973b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"DOING SECOND PASS (eerr %d)\n",eerr); 974a13144ffSStefano Zampini for (i=0;i<nee;i++) { 975b03ebc13SStefano Zampini PetscBool has_candidates = PETSC_FALSE; 976b03ebc13SStefano Zampini if (PetscBTLookup(bter,i)) { 977a13144ffSStefano Zampini PetscInt size,mark = i+1; 978a13144ffSStefano Zampini 979a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 980a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 981c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 982a13144ffSStefano Zampini for (j=0;j<size;j++) { 983a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 984b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"Inspecting edge dof %d [%d %d)\n",ee,ii[ee],ii[ee+1]); 985a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 986a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 987a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 988a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 989b03ebc13SStefano Zampini has_candidates = PETSC_TRUE; 990b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Candidate set to vertex %d\n",vv); 991a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 992a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 993a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 994a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 995a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 996b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected edge dof set to primal %d\n",ee2); 997a13144ffSStefano Zampini newprimals[cum++] = ee2; 998a13144ffSStefano Zampini /* finally set the new corners */ 999a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 1000b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected nodal dof set to vertex %d\n",jj[k3]); 1001a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 1002a13144ffSStefano Zampini } 1003a13144ffSStefano Zampini } 1004a13144ffSStefano Zampini } 1005b03ebc13SStefano Zampini } else { 1006b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Not a candidate vertex %d\n",jj[k]); 1007a13144ffSStefano Zampini } 1008a13144ffSStefano Zampini } 1009a13144ffSStefano Zampini } 1010b03ebc13SStefano Zampini if (!has_candidates) { /* circular edge */ 1011b03ebc13SStefano Zampini PetscInt k, ee = idxs[0],*tmarks; 1012b03ebc13SStefano Zampini 1013b03ebc13SStefano Zampini ierr = PetscCalloc1(ne,&tmarks);CHKERRQ(ierr); 1014b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Circular edge %d\n",i); 1015b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 1016b03ebc13SStefano Zampini PetscInt k2; 1017b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Set to corner %d\n",jj[k]); 1018b03ebc13SStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 1019b03ebc13SStefano Zampini for (k2=iit[jj[k]];k2<iit[jj[k]+1];k2++) tmarks[jjt[k2]]++; 1020b03ebc13SStefano Zampini } 1021b03ebc13SStefano Zampini for (j=0;j<size;j++) { 1022b03ebc13SStefano Zampini if (tmarks[idxs[j]] > 1) { 1023b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Edge dof set to primal %d\n",idxs[j]); 1024b03ebc13SStefano Zampini newprimals[cum++] = idxs[j]; 1025b03ebc13SStefano Zampini } 1026b03ebc13SStefano Zampini } 1027b03ebc13SStefano Zampini ierr = PetscFree(tmarks);CHKERRQ(ierr); 1028b03ebc13SStefano Zampini } 1029a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1030a13144ffSStefano Zampini } 1031a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 1032a13144ffSStefano Zampini } 1033b03ebc13SStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 10340569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 1035a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 1036c2151214SStefano Zampini if (fl2g) { 1037c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 1038c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1039c2151214SStefano Zampini for (i=0;i<nee;i++) { 1040c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1041c2151214SStefano Zampini } 1042c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1043c2151214SStefano Zampini } 1044c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1045a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 1046a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 1047a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 1048a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1049a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 1050c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1051c2151214SStefano Zampini if (fl2g) { 1052c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 1053c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 1054c2151214SStefano Zampini for (i=0;i<nee;i++) { 1055c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 1056c2151214SStefano Zampini } 1057c2151214SStefano Zampini } else { 1058c2151214SStefano Zampini eedges = alleedges; 1059c2151214SStefano Zampini primals = allprimals; 1060c2151214SStefano Zampini } 1061b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 1062a13144ffSStefano Zampini 1063a13144ffSStefano Zampini /* Mark again */ 1064a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 1065a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1066a13144ffSStefano Zampini PetscInt size,mark = i+1; 1067a13144ffSStefano Zampini 1068a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1069a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1070a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 1071a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1072a13144ffSStefano Zampini } 1073a13144ffSStefano Zampini if (print) { 1074a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 1075a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 1076a13144ffSStefano Zampini } 1077a13144ffSStefano Zampini 1078a13144ffSStefano Zampini /* Recompute extended cols */ 1079a13144ffSStefano Zampini eerr = PETSC_FALSE; 1080a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1081a13144ffSStefano Zampini PetscInt size; 1082a13144ffSStefano Zampini 1083a13144ffSStefano Zampini cum = 0; 1084a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 10851e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 10861e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 1087a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1088a13144ffSStefano Zampini for (j=0;j<size;j++) { 1089a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 10901e0482f5SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 1091a13144ffSStefano Zampini } 1092a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1093a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 1094a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 1095a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 1096a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 1097a13144ffSStefano Zampini if (cum != size -1) { 1098a13144ffSStefano Zampini if (print) { 1099a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 1100a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 1101a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 1102a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 1103a13144ffSStefano Zampini } 1104a13144ffSStefano Zampini eerr = PETSC_TRUE; 1105a13144ffSStefano Zampini } 1106a13144ffSStefano Zampini } 1107a13144ffSStefano Zampini } 1108a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1109a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 1110b03ebc13SStefano Zampini ierr = PetscBTDestroy(&bter);CHKERRQ(ierr); 11117d871cd7SStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 1112a13144ffSStefano Zampini /* an error should not occur at this point */ 1113a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 1114a13144ffSStefano Zampini 11154e64d54eSstefano_zampini /* Check the number of endpoints */ 11160569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1117b03ebc13SStefano Zampini ierr = PetscMalloc1(2*nee,&corners);CHKERRQ(ierr); 1118b03ebc13SStefano Zampini ierr = PetscMalloc1(nee,&cedges);CHKERRQ(ierr); 11194e64d54eSstefano_zampini for (i=0;i<nee;i++) { 1120b03ebc13SStefano Zampini PetscInt size, found = 0, gc[2]; 11214e64d54eSstefano_zampini 1122b03ebc13SStefano Zampini /* init with defaults */ 1123b03ebc13SStefano Zampini cedges[i] = corners[i*2] = corners[i*2+1] = -1; 11244e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 11251e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 11261e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 11274e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1128b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 11294e64d54eSstefano_zampini for (j=0;j<size;j++) { 11304e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 11314e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 11324e64d54eSstefano_zampini PetscInt vv = jj[k]; 11334e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 1134b03ebc13SStefano Zampini if (found == 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found more then two corners for edge %d\n",i); 1135b03ebc13SStefano Zampini corners[i*2+found++] = vv; 11364e64d54eSstefano_zampini } 11374e64d54eSstefano_zampini } 11384e64d54eSstefano_zampini } 1139b03ebc13SStefano Zampini if (found != 2) { 1140b03ebc13SStefano Zampini PetscInt e; 1141b03ebc13SStefano Zampini if (fl2g) { 1142b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,1,idxs,&e);CHKERRQ(ierr); 1143b03ebc13SStefano Zampini } else { 1144b03ebc13SStefano Zampini e = idxs[0]; 1145b03ebc13SStefano Zampini } 1146b03ebc13SStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %d corners for edge %d (astart %d, estart %d)\n",found,i,e,idxs[0]); 1147b03ebc13SStefano Zampini } 1148eee23b56SStefano Zampini 1149eee23b56SStefano Zampini /* get primal dof index on this coarse edge */ 1150b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,2,corners+2*i,gc);CHKERRQ(ierr); 1151b03ebc13SStefano Zampini if (gc[0] > gc[1]) { 1152b03ebc13SStefano Zampini PetscInt swap = corners[2*i]; 1153b03ebc13SStefano Zampini corners[2*i] = corners[2*i+1]; 1154b03ebc13SStefano Zampini corners[2*i+1] = swap; 1155b03ebc13SStefano Zampini } 1156eee23b56SStefano Zampini cedges[i] = idxs[size-1]; 11574e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1158b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"EDGE %d: ce %d, corners (%d,%d)\n",i,cedges[i],corners[2*i],corners[2*i+1]); 11594e64d54eSstefano_zampini } 11600569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 11614e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 11624e64d54eSstefano_zampini 1163a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 1164a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 1165a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 1166a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 1167a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1168a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1169a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 1170a13144ffSStefano Zampini 1171a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1172a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 1173a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 1174a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 1175a13144ffSStefano Zampini if (emax < emarks[j]) { 1176a13144ffSStefano Zampini emax = emarks[j]; 1177a13144ffSStefano Zampini eemax = j; 1178a13144ffSStefano Zampini } 1179a13144ffSStefano Zampini } 1180a13144ffSStefano Zampini /* not relevant for edges */ 1181a13144ffSStefano Zampini if (!eemax) continue; 1182a13144ffSStefano Zampini 1183a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 1184a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 1185c2151214SStefano 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]); 1186a13144ffSStefano Zampini } 1187a13144ffSStefano Zampini } 1188a13144ffSStefano Zampini } 1189a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 1190a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1191a13144ffSStefano Zampini #endif 1192a13144ffSStefano Zampini 1193a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 1194a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1195a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 1196a13144ffSStefano Zampini extmem *= maxsize; 1197a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 1198a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 1199a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 1200a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1201a13144ffSStefano Zampini PetscInt mark = 0,size,start; 1202a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1203a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 1204a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 1205a13144ffSStefano Zampini mark = marks[jj[j]]; 1206a13144ffSStefano Zampini 1207a13144ffSStefano Zampini /* not relevant */ 1208a13144ffSStefano Zampini if (!mark) continue; 1209a13144ffSStefano Zampini 1210a13144ffSStefano Zampini /* import extended row */ 1211a13144ffSStefano Zampini mark--; 1212a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 1213a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 1214a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 1215a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 1216a13144ffSStefano Zampini extrowcum[mark] += size; 1217a13144ffSStefano Zampini } 1218a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1219a13144ffSStefano Zampini cum = 0; 1220a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1221a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 1222a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 1223a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 1224a13144ffSStefano Zampini cum = PetscMax(cum,size); 1225a13144ffSStefano Zampini } 1226a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 1227a13144ffSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 1228a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 1229a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 1230a13144ffSStefano Zampini 1231a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 1232a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 1233a13144ffSStefano Zampini 1234a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 1235a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1236c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 1237c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 1238a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 1239a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 1240a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 12411e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(T,al2g,al2g);CHKERRQ(ierr); 1242a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 1243a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1244a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 1245a13144ffSStefano Zampini 1246a13144ffSStefano Zampini /* Defaults to identity */ 1247c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 1248a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 1249a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 1250a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 1251a13144ffSStefano Zampini 12521e0482f5SStefano Zampini /* Create discrete gradient for the coarser level if needed */ 12531e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 12541e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 12551e0482f5SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 12561e0482f5SStefano Zampini ISLocalToGlobalMapping cel2g,cvl2g; 12571e0482f5SStefano Zampini IS wis,gwis; 12581e0482f5SStefano Zampini PetscInt cnv,cne; 12591e0482f5SStefano Zampini 12601e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,nee,cedges,PETSC_COPY_VALUES,&wis);CHKERRQ(ierr); 12611e0482f5SStefano Zampini if (fl2g) { 12621e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(fl2g,wis,&pcbddc->nedclocal);CHKERRQ(ierr); 12631e0482f5SStefano Zampini } else { 12641e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)wis);CHKERRQ(ierr); 12651e0482f5SStefano Zampini pcbddc->nedclocal = wis; 12661e0482f5SStefano Zampini } 12671e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,wis,&gwis);CHKERRQ(ierr); 12681e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12691e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cne,&wis);CHKERRQ(ierr); 12701e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cel2g);CHKERRQ(ierr); 12711e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12721e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12731e0482f5SStefano Zampini 12741e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,2*nee,corners,PETSC_USE_POINTER,&wis);CHKERRQ(ierr); 12751e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(vl2g,wis,&gwis);CHKERRQ(ierr); 12761e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12771e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cnv,&wis);CHKERRQ(ierr); 12781e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cvl2g);CHKERRQ(ierr); 12791e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12801e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12811e0482f5SStefano Zampini 12821e0482f5SStefano Zampini ierr = MatCreate(comm,&pcbddc->nedcG);CHKERRQ(ierr); 12831e0482f5SStefano Zampini ierr = MatSetSizes(pcbddc->nedcG,PETSC_DECIDE,PETSC_DECIDE,cne,cnv);CHKERRQ(ierr); 12841e0482f5SStefano Zampini ierr = MatSetType(pcbddc->nedcG,MATAIJ);CHKERRQ(ierr); 12851e0482f5SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->nedcG,2,NULL);CHKERRQ(ierr); 12861e0482f5SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->nedcG,2,NULL,2,NULL);CHKERRQ(ierr); 12871e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->nedcG,cel2g,cvl2g);CHKERRQ(ierr); 12881e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cel2g);CHKERRQ(ierr); 12891e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cvl2g);CHKERRQ(ierr); 12901e0482f5SStefano Zampini } 12911e0482f5SStefano Zampini 12921e0482f5SStefano Zampini #if defined(PRINT_GDET) 12931e0482f5SStefano Zampini inc = 0; 12941e0482f5SStefano Zampini lev = pcbddc->current_level; 12951e0482f5SStefano Zampini #endif 1296a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1297a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 12981e0482f5SStefano Zampini IS cornersis = NULL; 12991e0482f5SStefano Zampini PetscScalar cvals[2]; 1300a13144ffSStefano Zampini 13011e0482f5SStefano Zampini if (pcbddc->nedcG) { 13021e0482f5SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners+2*i,PETSC_USE_POINTER,&cornersis);CHKERRQ(ierr); 13031e0482f5SStefano Zampini } 13041e0482f5SStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],cornersis,&Gins,&GKins,cvals,work,rwork);CHKERRQ(ierr); 1305a13144ffSStefano Zampini if (Gins && GKins) { 1306a13144ffSStefano Zampini PetscScalar *data; 1307a13144ffSStefano Zampini const PetscInt *rows,*cols; 1308a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 1309a13144ffSStefano Zampini 1310a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 1311a13144ffSStefano Zampini /* H1 */ 1312a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 1313a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 1314a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 1315a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 1316a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 1317a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 1318a13144ffSStefano Zampini /* complement */ 1319a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 13201e0482f5SStefano Zampini if (!ncc) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Constant function has not been generated for coarse edge %d",i); 1321a13144ffSStefano 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); 13221e0482f5SStefano Zampini if (ncc != 1 && pcbddc->nedcG) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot generate the dicrete gradient for the next level with ncc %d",ncc); 1323a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 1324a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 1325a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 13261e0482f5SStefano Zampini 13271e0482f5SStefano Zampini /* coarse discrete gradient */ 13281e0482f5SStefano Zampini if (pcbddc->nedcG) { 13291e0482f5SStefano Zampini PetscInt cols[2]; 13301e0482f5SStefano Zampini 13311e0482f5SStefano Zampini cols[0] = 2*i; 13321e0482f5SStefano Zampini cols[1] = 2*i+1; 13331e0482f5SStefano Zampini ierr = MatSetValuesLocal(pcbddc->nedcG,1,&i,2,cols,cvals,INSERT_VALUES);CHKERRQ(ierr); 13341e0482f5SStefano Zampini } 1335a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1336a13144ffSStefano Zampini } 1337a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1338a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 13391e0482f5SStefano Zampini ierr = ISDestroy(&cornersis);CHKERRQ(ierr); 1340a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1341a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1342a13144ffSStefano Zampini } 1343a13144ffSStefano Zampini 1344a13144ffSStefano Zampini /* Start assembling */ 1345a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13461e0482f5SStefano Zampini if (pcbddc->nedcG) { 13471e0482f5SStefano Zampini ierr = MatAssemblyBegin(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13481e0482f5SStefano Zampini } 1349a13144ffSStefano Zampini 1350a13144ffSStefano Zampini /* Free */ 1351c2151214SStefano Zampini if (fl2g) { 1352c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1353c2151214SStefano Zampini for (i=0;i<nee;i++) { 1354c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1355c2151214SStefano Zampini } 1356c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1357c2151214SStefano Zampini } 1358eee23b56SStefano Zampini 1359eee23b56SStefano Zampini /* hack mat_graph with primal dofs on the coarse edges */ 1360eee23b56SStefano Zampini { 1361eee23b56SStefano Zampini PCBDDCGraph graph = pcbddc->mat_graph; 1362eee23b56SStefano Zampini PetscInt *oqueue = graph->queue; 1363eee23b56SStefano Zampini PetscInt *ocptr = graph->cptr; 1364eee23b56SStefano Zampini PetscInt ncc,*idxs; 1365eee23b56SStefano Zampini 1366eee23b56SStefano Zampini /* find first primal edge */ 1367eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1368eee23b56SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1369eee23b56SStefano Zampini } else { 1370eee23b56SStefano Zampini if (fl2g) { 1371eee23b56SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,nee,cedges,cedges);CHKERRQ(ierr); 1372eee23b56SStefano Zampini } 1373eee23b56SStefano Zampini idxs = cedges; 1374eee23b56SStefano Zampini } 1375eee23b56SStefano Zampini cum = 0; 1376eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1377eee23b56SStefano Zampini 1378eee23b56SStefano Zampini /* adapt connected components */ 1379eee23b56SStefano Zampini ierr = PetscMalloc2(graph->nvtxs+1,&graph->cptr,ocptr[graph->ncc],&graph->queue);CHKERRQ(ierr); 1380eee23b56SStefano Zampini graph->cptr[0] = 0; 1381eee23b56SStefano Zampini for (i=0,ncc=0;i<graph->ncc;i++) { 1382eee23b56SStefano Zampini PetscInt lc = ocptr[i+1]-ocptr[i]; 1383eee23b56SStefano Zampini if (cum != nee && oqueue[ocptr[i+1]-1] == cedges[cum]) { /* this cc has a primal dof */ 1384eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc]+1; 1385eee23b56SStefano Zampini graph->queue[graph->cptr[ncc]] = cedges[cum]; 1386eee23b56SStefano Zampini ncc++; 1387eee23b56SStefano Zampini lc--; 1388eee23b56SStefano Zampini cum++; 1389eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1390eee23b56SStefano Zampini } 1391eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc] + lc; 1392eee23b56SStefano Zampini for (j=0;j<lc;j++) graph->queue[graph->cptr[ncc]+j] = oqueue[ocptr[i]+j]; 1393eee23b56SStefano Zampini ncc++; 1394eee23b56SStefano Zampini } 1395eee23b56SStefano Zampini graph->ncc = ncc; 1396eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1397eee23b56SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1398eee23b56SStefano Zampini } 1399eee23b56SStefano Zampini ierr = PetscFree2(ocptr,oqueue);CHKERRQ(ierr); 1400eee23b56SStefano Zampini } 1401c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1402c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1403eee23b56SStefano Zampini 1404eee23b56SStefano Zampini 1405c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1406a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1407a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 1408c2151214SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 14091e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&al2g);CHKERRQ(ierr); 1410c2151214SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1411a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1412b03ebc13SStefano Zampini ierr = PetscFree(corners);CHKERRQ(ierr); 1413b03ebc13SStefano Zampini ierr = PetscFree(cedges);CHKERRQ(ierr); 1414a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1415a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1416a13144ffSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1417a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1418a13144ffSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1419a13144ffSStefano Zampini 1420a13144ffSStefano Zampini /* Complete assembling */ 1421a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14221e0482f5SStefano Zampini if (pcbddc->nedcG) { 14231e0482f5SStefano Zampini ierr = MatAssemblyEnd(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14241e0482f5SStefano Zampini #if 0 14251e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->nedcG,"coarse_G");CHKERRQ(ierr); 14261e0482f5SStefano Zampini ierr = MatView(pcbddc->nedcG,NULL);CHKERRQ(ierr); 14271e0482f5SStefano Zampini #endif 14281e0482f5SStefano Zampini } 1429a13144ffSStefano Zampini 1430a13144ffSStefano Zampini /* set change of basis */ 1431a13144ffSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,PETSC_FALSE);CHKERRQ(ierr); 14321e0482f5SStefano Zampini #if 0 14331e0482f5SStefano Zampini if (pcbddc->current_level) { 14341e0482f5SStefano Zampini PetscViewer viewer; 14351e0482f5SStefano Zampini char filename[256]; 14361e0482f5SStefano Zampini Mat Tned; 14371e0482f5SStefano Zampini IS sub; 14381e0482f5SStefano Zampini PetscInt rst; 14391e0482f5SStefano Zampini 14401e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 14411e0482f5SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 14421e0482f5SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 14431e0482f5SStefano Zampini if (nedfieldlocal) { 14441e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 14451e0482f5SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 14461e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 14471e0482f5SStefano Zampini } else { 14481e0482f5SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 14491e0482f5SStefano Zampini } 14501e0482f5SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 14511e0482f5SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 14521e0482f5SStefano Zampini ierr = MatGetOwnershipRange(pc->pmat,&rst,NULL);CHKERRQ(ierr); 14531e0482f5SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 14541e0482f5SStefano Zampini if (matis->sf_rootdata[i]) { 14551e0482f5SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 14561e0482f5SStefano Zampini } 14571e0482f5SStefano Zampini } 14581e0482f5SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%D] LEVEL %d MY ne %d cum %d\n",PetscGlobalRank,pcbddc->current_level,ne,cum); 14591e0482f5SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),cum,matis->sf_rootdata,PETSC_USE_POINTER,&sub);CHKERRQ(ierr); 14601e0482f5SStefano Zampini ierr = MatGetSubMatrix(T,sub,sub,MAT_INITIAL_MATRIX,&Tned);CHKERRQ(ierr); 14611e0482f5SStefano Zampini ierr = ISDestroy(&sub);CHKERRQ(ierr); 14621e0482f5SStefano Zampini 14631e0482f5SStefano Zampini sprintf(filename,"Change_l%d.m",pcbddc->current_level); 14641e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)Tned),filename,&viewer);CHKERRQ(ierr); 14651e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 14661e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)Tned,"T");CHKERRQ(ierr); 14671e0482f5SStefano Zampini ierr = MatView(Tned,viewer);CHKERRQ(ierr); 14681e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 14691e0482f5SStefano Zampini ierr = MatDestroy(&Tned);CHKERRQ(ierr); 14701e0482f5SStefano Zampini } 14711e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 14721e0482f5SStefano Zampini #endif 1473a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1474a13144ffSStefano Zampini 1475a13144ffSStefano Zampini PetscFunctionReturn(0); 1476a13144ffSStefano Zampini } 1477a13144ffSStefano Zampini 1478d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1479d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1480d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1481d8203eabSStefano Zampini #undef __FUNCT__ 1482d8203eabSStefano Zampini #define __FUNCT__ "PCBDDCNullSpaceCreate" 1483d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1484d8203eabSStefano Zampini { 1485d8203eabSStefano Zampini PetscErrorCode ierr; 1486d8203eabSStefano Zampini PetscInt i; 1487d8203eabSStefano Zampini 1488d8203eabSStefano Zampini PetscFunctionBegin; 1489d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1490d8203eabSStefano Zampini PetscInt first,last; 1491d8203eabSStefano Zampini 1492d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 149386fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1494d8203eabSStefano Zampini if (i>=first && i < last) { 1495d8203eabSStefano Zampini PetscScalar *data; 1496d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1497d8203eabSStefano Zampini if (!has_const) { 1498d8203eabSStefano Zampini data[i-first] = 1.; 1499d8203eabSStefano Zampini } else { 150086fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 150186fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1502d8203eabSStefano Zampini } 1503d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1504d8203eabSStefano Zampini } 1505d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1506d8203eabSStefano Zampini } 1507d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1508d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1509d8203eabSStefano Zampini PetscInt first,last; 1510d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1511d8203eabSStefano Zampini if (i>=first && i < last) { 1512d8203eabSStefano Zampini PetscScalar *data; 1513d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1514d8203eabSStefano Zampini if (!has_const) { 1515d8203eabSStefano Zampini data[i-first] = 0.; 1516d8203eabSStefano Zampini } else { 151786fa73c5SStefano Zampini data[2*i-first] = 0.; 151886fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1519d8203eabSStefano Zampini } 1520d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1521d8203eabSStefano Zampini } 1522d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1523d8203eabSStefano Zampini } 1524d8203eabSStefano Zampini PetscFunctionReturn(0); 1525d8203eabSStefano Zampini } 1526d8203eabSStefano Zampini 1527669cc0f4SStefano Zampini #undef __FUNCT__ 1528669cc0f4SStefano Zampini #define __FUNCT__ "PCBDDCComputeNoNetFlux" 15298ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1530669cc0f4SStefano Zampini { 1531a198735bSStefano Zampini Mat loc_divudotp; 1532fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 15338ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1534669cc0f4SStefano Zampini IS *faces,*edges; 1535669cc0f4SStefano Zampini PetscScalar *vals; 1536669cc0f4SStefano Zampini const PetscScalar *array; 1537669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 15381ae86dd6SStefano Zampini PetscMPIInt rank; 1539a198735bSStefano Zampini PetscErrorCode ierr; 1540669cc0f4SStefano Zampini 1541669cc0f4SStefano Zampini PetscFunctionBegin; 1542669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1543669cc0f4SStefano Zampini if (graph->twodim) { 1544669cc0f4SStefano Zampini lmaxneighs = 2; 1545669cc0f4SStefano Zampini } else { 1546669cc0f4SStefano Zampini lmaxneighs = 1; 1547669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1548669cc0f4SStefano Zampini const PetscInt *idxs; 1549669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1550669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 1551669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1552669cc0f4SStefano Zampini } 1553669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 1554669cc0f4SStefano Zampini } 1555669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 1556669cc0f4SStefano Zampini maxsize = 0; 1557669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1558669cc0f4SStefano Zampini PetscInt nn; 1559669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1560669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1561669cc0f4SStefano Zampini } 1562669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1563669cc0f4SStefano Zampini PetscInt nn; 1564669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1565669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1566669cc0f4SStefano Zampini } 1567669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1568669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1569669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 15708ae0ca82SStefano Zampini if (!transpose) { 15718ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 15728ae0ca82SStefano Zampini } else { 15738ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 15748ae0ca82SStefano Zampini } 1575669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 15761ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1577d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1578669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 15798ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1580669cc0f4SStefano Zampini } 1581d8203eabSStefano Zampini 1582669cc0f4SStefano Zampini /* compute local quad vec */ 1583a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 15848ae0ca82SStefano Zampini if (!transpose) { 1585a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 15868ae0ca82SStefano Zampini } else { 15878ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 15888ae0ca82SStefano Zampini } 1589669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 15908ae0ca82SStefano Zampini if (!transpose) { 1591a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 15928ae0ca82SStefano Zampini } else { 15938ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 15948ae0ca82SStefano Zampini } 1595fa23a32eSStefano Zampini if (vl2l) { 1596fa23a32eSStefano Zampini ierr = VecGetSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1597fa23a32eSStefano Zampini } else { 1598fa23a32eSStefano Zampini vins = v; 1599fa23a32eSStefano Zampini } 1600fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1601669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 16029a962809SStefano Zampini 16031ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 16041ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1605669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1606669cc0f4SStefano Zampini const PetscInt *idxs; 1607669cc0f4SStefano Zampini PetscInt idx,nn,j; 1608669cc0f4SStefano Zampini 1609669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 1610669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1611669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 16121ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1613669cc0f4SStefano Zampini idx = -(idx+1); 1614669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1615669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 1616669cc0f4SStefano Zampini } 1617669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1618669cc0f4SStefano Zampini const PetscInt *idxs; 1619669cc0f4SStefano Zampini PetscInt idx,nn,j; 1620669cc0f4SStefano Zampini 1621669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1622669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1623669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 16241ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1625669cc0f4SStefano Zampini idx = -(idx+1); 1626669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1627669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1628669cc0f4SStefano Zampini } 1629c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1630fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1631fa23a32eSStefano Zampini if (vl2l) { 1632fa23a32eSStefano Zampini ierr = VecRestoreSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1633fa23a32eSStefano Zampini } 1634669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1635669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1636669cc0f4SStefano Zampini 1637669cc0f4SStefano Zampini /* assemble near null space */ 1638669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1639669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1640669cc0f4SStefano Zampini } 1641669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1642669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 1643669cc0f4SStefano Zampini } 1644669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1645669cc0f4SStefano Zampini PetscFunctionReturn(0); 1646669cc0f4SStefano Zampini } 1647669cc0f4SStefano Zampini 1648669cc0f4SStefano Zampini 1649a3df083aSStefano Zampini #undef __FUNCT__ 16501f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 16511f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 16521f4df5f7SStefano Zampini { 16531f4df5f7SStefano Zampini PetscErrorCode ierr; 16541f4df5f7SStefano Zampini Vec local,global; 16551f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16561f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 16571f4df5f7SStefano Zampini 16581f4df5f7SStefano Zampini PetscFunctionBegin; 16591f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 16601f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 16611f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 16621f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 16631f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 16641f4df5f7SStefano Zampini PetscInt i; 16651f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16661f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 16671f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16681f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 16691f4df5f7SStefano Zampini } 16701f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 16711f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 16721f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 16731f4df5f7SStefano Zampini } 16741f4df5f7SStefano Zampini } else { 1675986cdee1SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering if bs > 1 */ 16761f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1677986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 1678986cdee1SStefano Zampini if (i > 1) { 1679986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 16801f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16811f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16821f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16831f4df5f7SStefano Zampini } 16841f4df5f7SStefano Zampini } 16851f4df5f7SStefano Zampini } 1686986cdee1SStefano Zampini } 16871f4df5f7SStefano Zampini 16881f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 16891f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16901f4df5f7SStefano Zampini } 16911f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 16921f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16931f4df5f7SStefano Zampini } 16941f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 16951f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 16961f4df5f7SStefano Zampini } 16971f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 16981f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 16991f4df5f7SStefano Zampini PetscFunctionReturn(0); 17001f4df5f7SStefano Zampini } 17011f4df5f7SStefano Zampini 17021f4df5f7SStefano Zampini #undef __FUNCT__ 17033e589ea0SStefano Zampini #define __FUNCT__ "PCBDDCBenignRemoveInterior" 17043e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 17053e589ea0SStefano Zampini { 17063e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 17073e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 17083e589ea0SStefano Zampini PetscErrorCode ierr; 17093e589ea0SStefano Zampini 17103e589ea0SStefano Zampini PetscFunctionBegin; 17113e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 17123e589ea0SStefano Zampini PetscFunctionReturn(0); 17133e589ea0SStefano Zampini } 17143e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 17153e589ea0SStefano Zampini Vec swap; 17163e589ea0SStefano Zampini 17173e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 17183e589ea0SStefano Zampini swap = pcbddc->work_change; 17193e589ea0SStefano Zampini pcbddc->work_change = r; 17203e589ea0SStefano Zampini r = swap; 17213e589ea0SStefano Zampini } 17223e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17233e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17243e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 17253e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 17263e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17273e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17283e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1729f913dca9SStefano Zampini pcbddc->work_change = r; 17303e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 17313e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 17323e589ea0SStefano Zampini } 17333e589ea0SStefano Zampini PetscFunctionReturn(0); 17343e589ea0SStefano Zampini } 17353e589ea0SStefano Zampini 17363e589ea0SStefano Zampini #undef __FUNCT__ 1737a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 1738a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1739a3df083aSStefano Zampini { 1740a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1741a3df083aSStefano Zampini PetscErrorCode ierr; 1742a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1743a3df083aSStefano Zampini 1744a3df083aSStefano Zampini PetscFunctionBegin; 1745a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1746a3df083aSStefano Zampini if (transpose) { 1747a3df083aSStefano Zampini apply_right = ctx->apply_left; 1748a3df083aSStefano Zampini apply_left = ctx->apply_right; 1749a3df083aSStefano Zampini } else { 1750a3df083aSStefano Zampini apply_right = ctx->apply_right; 1751a3df083aSStefano Zampini apply_left = ctx->apply_left; 1752a3df083aSStefano Zampini } 1753a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1754a3df083aSStefano Zampini if (apply_right) { 1755a3df083aSStefano Zampini const PetscScalar *ax; 1756a3df083aSStefano Zampini PetscInt nl,i; 1757a3df083aSStefano Zampini 1758a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1759a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1760a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1761a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1762a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1763a3df083aSStefano Zampini PetscScalar sum,val; 1764a3df083aSStefano Zampini const PetscInt *idxs; 1765a3df083aSStefano Zampini PetscInt nz,j; 1766a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1767a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1768a3df083aSStefano Zampini sum = 0.; 1769a3df083aSStefano Zampini if (ctx->apply_p0) { 1770a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1771a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1772a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1773a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1774a3df083aSStefano Zampini } 1775a3df083aSStefano Zampini } else { 1776a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1777a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1778a3df083aSStefano Zampini } 1779a3df083aSStefano Zampini } 1780a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1781a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1782a3df083aSStefano Zampini } 1783a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1784a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1785a3df083aSStefano Zampini } 1786a3df083aSStefano Zampini if (transpose) { 1787a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1788a3df083aSStefano Zampini } else { 1789a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1790a3df083aSStefano Zampini } 1791a3df083aSStefano Zampini if (reset_x) { 1792a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1793a3df083aSStefano Zampini } 1794a3df083aSStefano Zampini if (apply_left) { 1795a3df083aSStefano Zampini PetscScalar *ay; 1796a3df083aSStefano Zampini PetscInt i; 1797a3df083aSStefano Zampini 1798a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1799a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1800a3df083aSStefano Zampini PetscScalar sum,val; 1801a3df083aSStefano Zampini const PetscInt *idxs; 1802a3df083aSStefano Zampini PetscInt nz,j; 1803a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1804a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1805a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1806a3df083aSStefano Zampini if (ctx->apply_p0) { 1807a3df083aSStefano Zampini sum = 0.; 1808a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1809a3df083aSStefano Zampini sum += ay[idxs[j]]; 1810a3df083aSStefano Zampini ay[idxs[j]] += val; 1811a3df083aSStefano Zampini } 1812a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1813a3df083aSStefano Zampini } else { 1814a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1815a3df083aSStefano Zampini ay[idxs[j]] += val; 1816a3df083aSStefano Zampini } 1817a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1818a3df083aSStefano Zampini } 1819a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1820a3df083aSStefano Zampini } 1821a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1822a3df083aSStefano Zampini } 1823a3df083aSStefano Zampini PetscFunctionReturn(0); 1824a3df083aSStefano Zampini } 1825a3df083aSStefano Zampini 1826a3df083aSStefano Zampini #undef __FUNCT__ 1827a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 1828a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1829a3df083aSStefano Zampini { 1830a3df083aSStefano Zampini PetscErrorCode ierr; 1831a3df083aSStefano Zampini 1832a3df083aSStefano Zampini PetscFunctionBegin; 1833a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1834a3df083aSStefano Zampini PetscFunctionReturn(0); 1835a3df083aSStefano Zampini } 1836a3df083aSStefano Zampini 1837a3df083aSStefano Zampini #undef __FUNCT__ 1838a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 1839a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1840a3df083aSStefano Zampini { 1841a3df083aSStefano Zampini PetscErrorCode ierr; 1842a3df083aSStefano Zampini 1843a3df083aSStefano Zampini PetscFunctionBegin; 1844a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1845a3df083aSStefano Zampini PetscFunctionReturn(0); 1846a3df083aSStefano Zampini } 1847a3df083aSStefano Zampini 1848a3df083aSStefano Zampini #undef __FUNCT__ 1849a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 1850a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1851a3df083aSStefano Zampini { 1852a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1853a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1854a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1855a3df083aSStefano Zampini PetscErrorCode ierr; 1856a3df083aSStefano Zampini 1857a3df083aSStefano Zampini PetscFunctionBegin; 1858a3df083aSStefano Zampini if (!restore) { 18591dd7afcfSStefano Zampini Mat A_IB,A_BI; 1860a3df083aSStefano Zampini PetscScalar *work; 1861b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1862a3df083aSStefano Zampini 18639a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 18649a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1865a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1866a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1867a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1868a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1869a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1870a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1871a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 1872a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 1873a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 1874a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 1875a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 1876a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 1877059032f7SStefano Zampini if (reuse) { 1878a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 18791dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 1880059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 1881059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 1882059032f7SStefano Zampini PetscInt i; 1883059032f7SStefano Zampini 1884059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 1885059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1886059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1887059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1888059032f7SStefano Zampini } 1889059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 18901dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 1891059032f7SStefano Zampini } 1892a3df083aSStefano Zampini ctx->A = pcis->A_IB; 1893a3df083aSStefano Zampini ctx->work = work; 1894a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 1895a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1896a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1897a3df083aSStefano Zampini pcis->A_IB = A_IB; 1898a3df083aSStefano Zampini 1899a3df083aSStefano Zampini /* A_BI as A_IB^T */ 1900a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 1901a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 1902a3df083aSStefano Zampini pcis->A_BI = A_BI; 1903a3df083aSStefano Zampini } else { 19041dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 19051dd7afcfSStefano Zampini PetscFunctionReturn(0); 19061dd7afcfSStefano Zampini } 1907a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 1908a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1909a3df083aSStefano Zampini pcis->A_IB = ctx->A; 19101dd7afcfSStefano Zampini ctx->A = NULL; 19111dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 19121dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 19131dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 19141dd7afcfSStefano Zampini if (ctx->free) { 1915059032f7SStefano Zampini PetscInt i; 19161dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1917059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1918059032f7SStefano Zampini } 1919059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1920059032f7SStefano Zampini } 1921a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 1922a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 1923a3df083aSStefano Zampini } 1924a3df083aSStefano Zampini PetscFunctionReturn(0); 1925a3df083aSStefano Zampini } 1926a3df083aSStefano Zampini 1927a3df083aSStefano Zampini /* used just in bddc debug mode */ 1928a3df083aSStefano Zampini #undef __FUNCT__ 1929a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 1930a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 1931a3df083aSStefano Zampini { 1932a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1933a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1934a3df083aSStefano Zampini Mat An; 1935a3df083aSStefano Zampini PetscErrorCode ierr; 1936a3df083aSStefano Zampini 1937a3df083aSStefano Zampini PetscFunctionBegin; 1938a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 1939a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 1940a3df083aSStefano Zampini if (is1) { 1941a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 1942a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 1943a3df083aSStefano Zampini } else { 1944a3df083aSStefano Zampini *B = An; 1945a3df083aSStefano Zampini } 1946a3df083aSStefano Zampini PetscFunctionReturn(0); 1947a3df083aSStefano Zampini } 1948a3df083aSStefano Zampini 19491cf9b237SStefano Zampini /* TODO: add reuse flag */ 19501cf9b237SStefano Zampini #undef __FUNCT__ 19511cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 19521cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 19531cf9b237SStefano Zampini { 19541cf9b237SStefano Zampini Mat Bt; 19551cf9b237SStefano Zampini PetscScalar *a,*bdata; 19561cf9b237SStefano Zampini const PetscInt *ii,*ij; 19571cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 19581cf9b237SStefano Zampini PetscBool flg_row; 19591cf9b237SStefano Zampini PetscErrorCode ierr; 19601cf9b237SStefano Zampini 19611cf9b237SStefano Zampini PetscFunctionBegin; 19621cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 19631cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 19641cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 19651cf9b237SStefano Zampini nnz = n; 19661cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 19671cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 19681cf9b237SStefano Zampini } 19691cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 19701cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 19711cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 19721cf9b237SStefano Zampini nnz = 0; 19731cf9b237SStefano Zampini bii[0] = 0; 19741cf9b237SStefano Zampini for (i=0;i<n;i++) { 19751cf9b237SStefano Zampini PetscInt j; 19761cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 19771cf9b237SStefano Zampini PetscScalar entry = a[j]; 19781cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 19791cf9b237SStefano Zampini bij[nnz] = ij[j]; 19801cf9b237SStefano Zampini bdata[nnz] = entry; 19811cf9b237SStefano Zampini nnz++; 19821cf9b237SStefano Zampini } 19831cf9b237SStefano Zampini } 19841cf9b237SStefano Zampini bii[i+1] = nnz; 19851cf9b237SStefano Zampini } 19861cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 19871cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 19881cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 19891cf9b237SStefano Zampini { 19901cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 19911cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 19921cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 19931cf9b237SStefano Zampini } 19941cf9b237SStefano Zampini *B = Bt; 19951cf9b237SStefano Zampini PetscFunctionReturn(0); 19961cf9b237SStefano Zampini } 19971cf9b237SStefano Zampini 1998674ae819SStefano Zampini #undef __FUNCT__ 19994f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 20004f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 20014f1b2e48SStefano Zampini { 20024f1b2e48SStefano Zampini Mat B; 20034f1b2e48SStefano Zampini IS is_dummy,*cc_n; 20044f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 20054f1b2e48SStefano Zampini PCBDDCGraph graph; 20064f1b2e48SStefano Zampini PetscInt i,n; 20074f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 20084f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 20094f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 20104f1b2e48SStefano Zampini PetscErrorCode ierr; 20114f1b2e48SStefano Zampini 20124f1b2e48SStefano Zampini PetscFunctionBegin; 201363c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 201463c961adSStefano Zampini *ncc = 0; 201563c961adSStefano Zampini *cc = NULL; 201663c961adSStefano Zampini PetscFunctionReturn(0); 201763c961adSStefano Zampini } 20184f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 20194f1b2e48SStefano Zampini if (!isseqaij && filter) { 20201cf9b237SStefano Zampini PetscBool isseqdense; 20211cf9b237SStefano Zampini 20221cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 20231cf9b237SStefano Zampini if (!isseqdense) { 20244f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 20251cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 20261cf9b237SStefano Zampini PetscScalar *array; 20271cf9b237SStefano Zampini PetscReal chop=1.e-6; 20281cf9b237SStefano Zampini 20291cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 20301cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 20311cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 20321cf9b237SStefano Zampini for (i=0;i<n;i++) { 20331cf9b237SStefano Zampini PetscInt j; 20341cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 20351cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 20361cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 20371cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 20381cf9b237SStefano Zampini } 20391cf9b237SStefano Zampini } 20401cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 20419d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 20421cf9b237SStefano Zampini } 20434f1b2e48SStefano Zampini } else { 20444f1b2e48SStefano Zampini B = A; 20454f1b2e48SStefano Zampini } 20464f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 20474f1b2e48SStefano Zampini 20484f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 20494f1b2e48SStefano Zampini if (filter) { 20504f1b2e48SStefano Zampini PetscScalar *data; 20514f1b2e48SStefano Zampini PetscInt j,cum; 20524f1b2e48SStefano Zampini 20534f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 20544f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 20554f1b2e48SStefano Zampini cum = 0; 20564f1b2e48SStefano Zampini for (i=0;i<n;i++) { 20574f1b2e48SStefano Zampini PetscInt t; 20584f1b2e48SStefano Zampini 20594f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 20604f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 20614f1b2e48SStefano Zampini continue; 20624f1b2e48SStefano Zampini } 20634f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 20644f1b2e48SStefano Zampini } 20654f1b2e48SStefano Zampini t = xadj_filtered[i]; 20664f1b2e48SStefano Zampini xadj_filtered[i] = cum; 20674f1b2e48SStefano Zampini cum += t; 20684f1b2e48SStefano Zampini } 20694f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 20704f1b2e48SStefano Zampini } else { 20714f1b2e48SStefano Zampini xadj_filtered = NULL; 20724f1b2e48SStefano Zampini adjncy_filtered = NULL; 20734f1b2e48SStefano Zampini } 20744f1b2e48SStefano Zampini 20754f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 20764f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 20774f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 20784f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 20794f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 2080be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 20814f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 20824f1b2e48SStefano Zampini if (xadj_filtered) { 20834f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 20844f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 20854f1b2e48SStefano Zampini } else { 20864f1b2e48SStefano Zampini graph->xadj = xadj; 20874f1b2e48SStefano Zampini graph->adjncy = adjncy; 20884f1b2e48SStefano Zampini } 20894f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 20904f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 20914f1b2e48SStefano Zampini /* partial clean up */ 20924f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 20934f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 20941cf9b237SStefano Zampini if (A != B) { 20954f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 20964f1b2e48SStefano Zampini } 20974f1b2e48SStefano Zampini 20984f1b2e48SStefano Zampini /* get back data */ 20991cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 21001cf9b237SStefano Zampini if (cc) { 21014f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 21024f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 21034f1b2e48SStefano 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); 21044f1b2e48SStefano Zampini } 21054f1b2e48SStefano Zampini *cc = cc_n; 21061cf9b237SStefano Zampini } 21074f1b2e48SStefano Zampini /* clean up graph */ 21084f1b2e48SStefano Zampini graph->xadj = 0; 21094f1b2e48SStefano Zampini graph->adjncy = 0; 21104f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 21114f1b2e48SStefano Zampini PetscFunctionReturn(0); 21124f1b2e48SStefano Zampini } 21134f1b2e48SStefano Zampini 21144f1b2e48SStefano Zampini #undef __FUNCT__ 21155408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 21165408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 21175408967cSStefano Zampini { 21185408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 21195408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2120dee84bffSStefano Zampini IS dirIS = NULL; 21214f1b2e48SStefano Zampini PetscInt i; 21225408967cSStefano Zampini PetscErrorCode ierr; 21235408967cSStefano Zampini 21245408967cSStefano Zampini PetscFunctionBegin; 2125dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 21265408967cSStefano Zampini if (zerodiag) { 21275408967cSStefano Zampini Mat A; 21285408967cSStefano Zampini Vec vec3_N; 21295408967cSStefano Zampini PetscScalar *vals; 21305408967cSStefano Zampini const PetscInt *idxs; 2131d12d3064SStefano Zampini PetscInt nz,*count; 21325408967cSStefano Zampini 21335408967cSStefano Zampini /* p0 */ 21345408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 21355408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 21365408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 21375408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 21384f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 21395408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 21405408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 21415408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 21425408967cSStefano Zampini /* v_I */ 21435408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 21445408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 21455408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 21465408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 21475408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 21485408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 21495408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 21505408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 21515408967cSStefano Zampini if (dirIS) { 21525408967cSStefano Zampini PetscInt n; 21535408967cSStefano Zampini 21545408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 21555408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 21565408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 21575408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 21585408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 21595408967cSStefano Zampini } 21605408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 21615408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 21625408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 21635408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2164669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 21655408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 21665408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 21679a962809SStefano 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])); 21685408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 21695408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2170d12d3064SStefano Zampini 2171d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2172d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2173d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2174d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2175d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2176d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 21779a962809SStefano 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]); 2178d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2179d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 21805408967cSStefano Zampini } 2181dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 21825408967cSStefano Zampini 21835408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 21845408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 21854f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 21865408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 21874f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 21885408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2189f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2190f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 2191f2a566d8SStefano 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); 2192f2a566d8SStefano Zampini } 21935408967cSStefano Zampini PetscFunctionReturn(0); 21945408967cSStefano Zampini } 21955408967cSStefano Zampini 21965408967cSStefano Zampini #undef __FUNCT__ 2197339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 2198339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 2199339f8db1SStefano Zampini { 2200339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 22014f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 2202b0f5fe93SStefano Zampini PetscInt nz,n; 22031f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 22044f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 2205339f8db1SStefano Zampini PetscErrorCode ierr; 2206339f8db1SStefano Zampini 2207339f8db1SStefano Zampini PetscFunctionBegin; 22089f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 22099f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2210a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2211a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2212a3df083aSStefano Zampini } 2213a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2214a3df083aSStefano Zampini pcbddc->benign_n = 0; 22151ae86dd6SStefano Zampini /* if a local info on dofs is present, assumes that the last field represents "pressures" 22164f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 22174f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 22184f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 22191ae86dd6SStefano Zampini since the local Schur complements are already SPD 22204f1b2e48SStefano Zampini */ 22214f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 22224f1b2e48SStefano Zampini have_null = PETSC_TRUE; 222340fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 22244f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 22254f1b2e48SStefano Zampini 22264f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 22274f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 22284f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 22294f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 2230ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 223140fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 223240fa8d13SStefano Zampini if (!sorted) { 223340fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 223440fa8d13SStefano Zampini } 223540fa8d13SStefano Zampini } else { 223640fa8d13SStefano Zampini pressures = NULL; 223740fa8d13SStefano Zampini } 223897d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 223997d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 224027b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 224197d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2242339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2243339f8db1SStefano Zampini if (!sorted) { 2244339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2245339f8db1SStefano Zampini } 2246339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 22474f1b2e48SStefano Zampini if (!nz) { 22484f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 22494f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 225040fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 225140fa8d13SStefano Zampini } 22524f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 22534f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 22544f1b2e48SStefano Zampini zerodiag_subs = NULL; 22554f1b2e48SStefano Zampini pcbddc->benign_n = 0; 22561f4df5f7SStefano Zampini n_interior_dofs = 0; 22571f4df5f7SStefano Zampini interior_dofs = NULL; 22581f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 22591f4df5f7SStefano Zampini PetscInt n,i,j; 22601f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 22611f4df5f7SStefano Zampini PetscInt *iwork; 22621f4df5f7SStefano Zampini 22631f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 22641f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 22651f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 22661f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 226790648384SStefano Zampini for (i=1;i<n_neigh;i++) 22681f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 22691f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 22701f4df5f7SStefano Zampini for (i=0;i<n;i++) 22711f4df5f7SStefano Zampini if (!iwork[i]) 22721f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 22731f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 22741f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 22751f4df5f7SStefano Zampini } 22764f1b2e48SStefano Zampini if (has_null_pressures) { 22774f1b2e48SStefano Zampini IS *subs; 22781f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 22791f4df5f7SStefano Zampini const PetscInt *idxs; 22801f4df5f7SStefano Zampini PetscScalar *array; 22811f4df5f7SStefano Zampini Vec *work; 22821f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 22834f1b2e48SStefano Zampini 22844f1b2e48SStefano Zampini subs = pcbddc->local_subs; 22854f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 22861f4df5f7SStefano 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) */ 22871f4df5f7SStefano Zampini if (pcbddc->current_level) { 22881f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 22891f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 22901f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 22911f4df5f7SStefano Zampini /* work[0] = 1_p */ 22921f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 22931f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 22941f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 22951f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 22961f4df5f7SStefano Zampini /* work[0] = 1_v */ 22971f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 22981f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 22991f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 23001f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 23011f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 23021f4df5f7SStefano Zampini } 23034f1b2e48SStefano Zampini if (nsubs > 1) { 23044f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 23054f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 23064f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 23074f1b2e48SStefano Zampini IS t_zerodiag_subs; 23084f1b2e48SStefano Zampini PetscInt nl; 23094f1b2e48SStefano Zampini 23104f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 23114f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 23124f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 23134f1b2e48SStefano Zampini if (nl) { 23144f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 23154f1b2e48SStefano Zampini 23161f4df5f7SStefano Zampini if (pcbddc->current_level) { 23171f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 23181f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 23191f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 23201f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 23211f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 23221f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 23231f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 23241f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 23251f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 23261f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 23271f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 23281f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 23291f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 23301f4df5f7SStefano Zampini valid = PETSC_FALSE; 23311f4df5f7SStefano Zampini break; 23321f4df5f7SStefano Zampini } 23331f4df5f7SStefano Zampini } 23341f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 23351f4df5f7SStefano Zampini } 23361f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 23371f4df5f7SStefano Zampini IS t_bc; 23381f4df5f7SStefano Zampini PetscInt nzb; 23391f4df5f7SStefano Zampini 23401f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 23411f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 23421f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 23431f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 23441f4df5f7SStefano Zampini } 23451f4df5f7SStefano Zampini if (valid && pressures) { 23464f1b2e48SStefano Zampini IS t_pressure_subs; 23474f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 23484f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 23494f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 23504f1b2e48SStefano Zampini } 23514f1b2e48SStefano Zampini if (valid) { 23524f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 23534f1b2e48SStefano Zampini pcbddc->benign_n++; 23544f1b2e48SStefano Zampini } else { 23554f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 23564f1b2e48SStefano Zampini } 23574f1b2e48SStefano Zampini } 23584f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 23594f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 23604f1b2e48SStefano Zampini } 23614f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 23624f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 23631f4df5f7SStefano Zampini 23641f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 23651f4df5f7SStefano Zampini PetscInt nzb; 23661f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 23671f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 23681f4df5f7SStefano Zampini } 23691f4df5f7SStefano Zampini if (valid && pressures) { 23704f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 23714f1b2e48SStefano Zampini } 23721f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 23731f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 23741f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 23751f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 23761f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 23771f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 23781f4df5f7SStefano Zampini valid = PETSC_FALSE; 23791f4df5f7SStefano Zampini break; 23801f4df5f7SStefano Zampini } 23811f4df5f7SStefano Zampini } 23821f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 23831f4df5f7SStefano Zampini } 23844f1b2e48SStefano Zampini if (valid) { 23854f1b2e48SStefano Zampini pcbddc->benign_n = 1; 2386ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 23874f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 23884f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 23894f1b2e48SStefano Zampini } 23904f1b2e48SStefano Zampini } 23911f4df5f7SStefano Zampini if (pcbddc->current_level) { 23921f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 23934f1b2e48SStefano Zampini } 23941f4df5f7SStefano Zampini } 23951f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 23964f1b2e48SStefano Zampini 23974f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2398b9b0e38cSStefano Zampini PetscInt n; 2399b9b0e38cSStefano Zampini 24004f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 24014f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2402b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2403b9b0e38cSStefano Zampini if (n) { 24044f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 24054f1b2e48SStefano Zampini have_null = PETSC_FALSE; 24064f1b2e48SStefano Zampini } 2407b9b0e38cSStefano Zampini } 24084f1b2e48SStefano Zampini 24094f1b2e48SStefano Zampini /* final check for null pressures */ 24104f1b2e48SStefano Zampini if (zerodiag && pressures) { 24114f1b2e48SStefano Zampini PetscInt nz,np; 24124f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 24134f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 24144f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 24154f1b2e48SStefano Zampini } 24164f1b2e48SStefano Zampini 24174f1b2e48SStefano Zampini if (recompute_zerodiag) { 24184f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 24194f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 24204f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 24214f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 24224f1b2e48SStefano Zampini } else { 24234f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 24244f1b2e48SStefano Zampini 24254f1b2e48SStefano Zampini nzn = 0; 24264f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 24274f1b2e48SStefano Zampini PetscInt ns; 24284f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 24294f1b2e48SStefano Zampini nzn += ns; 24304f1b2e48SStefano Zampini } 24314f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 24324f1b2e48SStefano Zampini nzn = 0; 24334f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 24344f1b2e48SStefano Zampini PetscInt ns,*idxs; 24354f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 24364f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 24374f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 24384f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 24394f1b2e48SStefano Zampini nzn += ns; 24404f1b2e48SStefano Zampini } 24414f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 24424f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 24434f1b2e48SStefano Zampini } 24444f1b2e48SStefano Zampini have_null = PETSC_FALSE; 24454f1b2e48SStefano Zampini } 24464f1b2e48SStefano Zampini 2447669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2448a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2449a198735bSStefano Zampini Mat A,loc_divudotp; 2450a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2451a198735bSStefano Zampini IS row,col,isused = NULL; 2452a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2453a198735bSStefano Zampini 24541f4df5f7SStefano Zampini if (pressures) { 24551f4df5f7SStefano Zampini isused = pressures; 24561f4df5f7SStefano Zampini } else { 24571f4df5f7SStefano Zampini isused = zerodiag; 24581f4df5f7SStefano Zampini } 2459a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2460669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 24611ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 24621ae86dd6SStefano 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"); 2463a198735bSStefano Zampini n_isused = 0; 2464a198735bSStefano Zampini if (isused) { 2465a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2466a198735bSStefano Zampini } 2467a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2468a198735bSStefano Zampini st = st-n_isused; 24691ae86dd6SStefano Zampini if (n) { 2470a198735bSStefano Zampini const PetscInt *gidxs; 2471a198735bSStefano Zampini 2472a198735bSStefano Zampini ierr = MatGetSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2473a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2474a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2475a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2476a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2477a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 24781ae86dd6SStefano Zampini } else { 2479a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2480a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2481a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2482a198735bSStefano Zampini } 2483a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2484a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2485a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2486a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2487a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2488a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2489a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2490a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2491a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2492a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2493a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2494a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2495a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2496a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 24971ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24981ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24991ae86dd6SStefano Zampini } 2500b3afcdbeSStefano Zampini 2501b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 25024f1b2e48SStefano Zampini if (has_null_pressures) { 25034f1b2e48SStefano Zampini IS zerodiagc; 25044f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 25054f1b2e48SStefano Zampini PetscInt i,s,*nnz; 25064f1b2e48SStefano Zampini 25074f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2508339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 2509339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 2510339f8db1SStefano Zampini /* local change of basis for pressures */ 2511339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 251297d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2513339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2514339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2515339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 25164f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 25174f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 25184f1b2e48SStefano Zampini PetscInt nzs,j; 25194f1b2e48SStefano Zampini 25204f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 25214f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 25224f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 25234f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 25244f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 25254f1b2e48SStefano Zampini } 2526339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2527339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2528339f8db1SStefano Zampini /* set identity on velocities */ 2529339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 2530339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 2531339f8db1SStefano Zampini } 25324f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 25334f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 25349f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 25354f1b2e48SStefano 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); 2536339f8db1SStefano Zampini /* set change on pressures */ 25374f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 25384f1b2e48SStefano Zampini PetscScalar *array; 25394f1b2e48SStefano Zampini PetscInt nzs; 25404f1b2e48SStefano Zampini 25414f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 25424f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 25434f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2544339f8db1SStefano Zampini PetscScalar vals[2]; 2545339f8db1SStefano Zampini PetscInt cols[2]; 2546339f8db1SStefano Zampini 2547339f8db1SStefano Zampini cols[0] = idxs[i]; 25484f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2549339f8db1SStefano Zampini vals[0] = 1.; 2550b0f5fe93SStefano Zampini vals[1] = 1.; 25514f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2552339f8db1SStefano Zampini } 25534f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 25544f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 25554f1b2e48SStefano Zampini array[nzs-1] = 1.; 25564f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 25574f1b2e48SStefano Zampini /* store local idxs for p0 */ 25584f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 25594f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2560339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 25614f1b2e48SStefano Zampini } 2562339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2563339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2564a3df083aSStefano Zampini /* project if needed */ 2565a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 25661dd7afcfSStefano Zampini Mat M; 25671dd7afcfSStefano Zampini 25681dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2569339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 25701dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 25711dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2572a3df083aSStefano Zampini } 25734f1b2e48SStefano Zampini /* store global idxs for p0 */ 25744f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2575339f8db1SStefano Zampini } 2576ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 25774f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 2578b0f5fe93SStefano Zampini 2579b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 2580b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 258127b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 258227b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2583339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2584339f8db1SStefano Zampini PetscFunctionReturn(0); 2585339f8db1SStefano Zampini } 2586339f8db1SStefano Zampini 2587339f8db1SStefano Zampini #undef __FUNCT__ 2588015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 2589015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2590efc2fbd9SStefano Zampini { 2591efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2592de9d7bd0SStefano Zampini PetscScalar *array; 2593efc2fbd9SStefano Zampini PetscErrorCode ierr; 2594efc2fbd9SStefano Zampini 2595efc2fbd9SStefano Zampini PetscFunctionBegin; 2596efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2597efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 25984f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2599efc2fbd9SStefano Zampini } 2600de9d7bd0SStefano Zampini if (get) { 2601efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 26024f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 26034f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2604efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2605de9d7bd0SStefano Zampini } else { 2606de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2607de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2608de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2609de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2610efc2fbd9SStefano Zampini } 2611efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2612efc2fbd9SStefano Zampini } 2613efc2fbd9SStefano Zampini 2614efc2fbd9SStefano Zampini #undef __FUNCT__ 2615c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 2616c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2617c263805aSStefano Zampini { 2618c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2619c263805aSStefano Zampini PetscErrorCode ierr; 2620c263805aSStefano Zampini 2621c263805aSStefano Zampini PetscFunctionBegin; 2622c263805aSStefano Zampini /* TODO: add error checking 2623c263805aSStefano Zampini - avoid nested pop (or push) calls. 2624c263805aSStefano Zampini - cannot push before pop. 26251c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2626c263805aSStefano Zampini */ 26274f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2628efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2629efc2fbd9SStefano Zampini } 2630c263805aSStefano Zampini if (pop) { 2631a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 26324f1b2e48SStefano Zampini IS is_p0; 26334f1b2e48SStefano Zampini MatReuse reuse; 2634c263805aSStefano Zampini 2635c263805aSStefano Zampini /* extract B_0 */ 26364f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 26374f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 26384f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 26394f1b2e48SStefano Zampini } 26404f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 26414f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2642c263805aSStefano Zampini /* remove rows and cols from local problem */ 2643c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 264497d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 26454f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 26464f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2647a3df083aSStefano Zampini } else { 2648a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2649a3df083aSStefano Zampini PetscScalar *vals; 2650a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2651a3df083aSStefano Zampini 2652a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2653a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2654a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 26550b5adadeSStefano Zampini PetscInt *nnz; 2656a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2657a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2658a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2659331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2660331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2661331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2662331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2663331e053bSStefano Zampini } 2664331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2665331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2666331e053bSStefano Zampini } 2667a3df083aSStefano Zampini 2668a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2669a3df083aSStefano Zampini PetscScalar *array; 2670a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2671a3df083aSStefano Zampini 2672a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2673a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2674a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2675a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2676a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2677a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2678a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2679a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2680a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2681a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2682a3df083aSStefano Zampini cum = 0; 2683a3df083aSStefano Zampini for (j=0;j<n;j++) { 268422db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2685a3df083aSStefano Zampini vals[cum] = array[j]; 2686a3df083aSStefano Zampini idxs_ins[cum] = j; 2687a3df083aSStefano Zampini cum++; 2688a3df083aSStefano Zampini } 2689a3df083aSStefano Zampini } 2690a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2691a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2692a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2693a3df083aSStefano Zampini } 2694a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2695a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2696a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2697a3df083aSStefano Zampini } 2698c263805aSStefano Zampini } else { /* push */ 2699a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 27004f1b2e48SStefano Zampini PetscInt i; 27014f1b2e48SStefano Zampini 27024f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 27034f1b2e48SStefano Zampini PetscScalar *B0_vals; 27044f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 27054f1b2e48SStefano Zampini 27064f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 27074f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 27087b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 27094f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 27104f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 27114f1b2e48SStefano Zampini } 2712c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2713c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2714a3df083aSStefano Zampini } else { 2715a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2716a3df083aSStefano Zampini } 2717c263805aSStefano Zampini } 2718c263805aSStefano Zampini PetscFunctionReturn(0); 2719c263805aSStefano Zampini } 2720c263805aSStefano Zampini 2721c263805aSStefano Zampini #undef __FUNCT__ 2722b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 272308122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2724b1b3d7a2SStefano Zampini { 2725b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 272608122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 272708122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 272808122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 272908122e43SStefano Zampini PetscScalar *work,lwork; 273008122e43SStefano Zampini PetscScalar *St,*S,*eigv; 273108122e43SStefano Zampini PetscScalar *Sarray,*Starray; 273208122e43SStefano Zampini PetscReal *eigs,thresh; 27331b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2734f6f667cfSStefano Zampini PetscBool allocated_S_St; 273508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 273608122e43SStefano Zampini PetscReal *rwork; 273708122e43SStefano Zampini #endif 2738b1b3d7a2SStefano Zampini PetscErrorCode ierr; 2739b1b3d7a2SStefano Zampini 2740b1b3d7a2SStefano Zampini PetscFunctionBegin; 2741b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 2742af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 2743af25d912SStefano 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); 274406a4e24aSStefano Zampini 2745fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2746fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2747fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2748fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 27491575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2750fd14bc51SStefano Zampini } 2751fd14bc51SStefano Zampini 2752e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 2753e496cd5dSStefano 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); 2754e496cd5dSStefano Zampini } 2755e496cd5dSStefano Zampini 275608122e43SStefano Zampini /* max size of subsets */ 275708122e43SStefano Zampini mss = 0; 275808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 275908122e43SStefano Zampini PetscInt subset_size; 2760862806e4SStefano Zampini 276108122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 276208122e43SStefano Zampini mss = PetscMax(mss,subset_size); 276308122e43SStefano Zampini } 276408122e43SStefano Zampini 276508122e43SStefano Zampini /* min/max and threshold */ 276608122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 2767f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 276808122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 2769f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 2770f6f667cfSStefano Zampini if (nmin) { 2771f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 2772f6f667cfSStefano Zampini } 277308122e43SStefano Zampini 277408122e43SStefano Zampini /* allocate lapack workspace */ 277508122e43SStefano Zampini cum = cum2 = 0; 277608122e43SStefano Zampini maxneigs = 0; 277708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 277808122e43SStefano Zampini PetscInt n,subset_size; 2779f6f667cfSStefano Zampini 278008122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 278108122e43SStefano Zampini n = PetscMin(subset_size,nmax); 27829162d606SStefano Zampini cum += subset_size; 27839162d606SStefano Zampini cum2 += subset_size*n; 278408122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 278508122e43SStefano Zampini } 278608122e43SStefano Zampini if (mss) { 27879ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 278808122e43SStefano Zampini PetscBLASInt B_itype = 1; 278908122e43SStefano Zampini PetscBLASInt B_N = mss; 27904c6709b3SStefano Zampini PetscReal zero = 0.0; 27914c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 279208122e43SStefano Zampini 279308122e43SStefano Zampini B_lwork = -1; 279408122e43SStefano Zampini S = NULL; 279508122e43SStefano Zampini St = NULL; 2796a58a30b4SStefano Zampini eigs = NULL; 2797a58a30b4SStefano Zampini eigv = NULL; 2798a58a30b4SStefano Zampini B_iwork = NULL; 2799a58a30b4SStefano Zampini B_ifail = NULL; 2800d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2801d1710679SStefano Zampini rwork = NULL; 2802d1710679SStefano Zampini #endif 28038bec7fa6SStefano Zampini thresh = 1.0; 280408122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 280508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 280608122e43SStefano 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)); 280708122e43SStefano Zampini #else 280808122e43SStefano 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)); 280908122e43SStefano Zampini #endif 281008122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 281108122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 281208122e43SStefano Zampini } else { 281308122e43SStefano Zampini /* TODO */ 281408122e43SStefano Zampini } 281508122e43SStefano Zampini } else { 281608122e43SStefano Zampini lwork = 0; 281708122e43SStefano Zampini } 281808122e43SStefano Zampini 281908122e43SStefano Zampini nv = 0; 2820d62866d3SStefano 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) */ 2821d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 282208122e43SStefano Zampini } 28234c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 2824f6f667cfSStefano Zampini if (allocated_S_St) { 2825f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 2826f6f667cfSStefano Zampini } 2827f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 282808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 282908122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 283008122e43SStefano Zampini #endif 28319162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 28329162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 28339162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 283408122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 28359162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 283608122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 283708122e43SStefano Zampini 283808122e43SStefano Zampini maxneigs = 0; 283972b8c272SStefano Zampini cum = cumarray = 0; 28409162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 28419162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 2842d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 284308122e43SStefano Zampini const PetscInt *idxs; 284408122e43SStefano Zampini 2845d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 284608122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 284708122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 284808122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 284908122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 28509162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 28519162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 285208122e43SStefano Zampini } 2853d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 285408122e43SStefano Zampini } 285508122e43SStefano Zampini 285608122e43SStefano Zampini if (mss) { /* multilevel */ 285708122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 285808122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 285908122e43SStefano Zampini } 286008122e43SStefano Zampini 2861ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 286208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 286308122e43SStefano Zampini const PetscInt *idxs; 28649d54b7f4SStefano Zampini PetscReal upper,lower; 2865862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 286608122e43SStefano Zampini PetscBLASInt B_N; 2867aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 286808122e43SStefano Zampini 28699d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 28709d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 28719d54b7f4SStefano Zampini lower = thresh; 28729d54b7f4SStefano Zampini } else { 28739d54b7f4SStefano Zampini upper = 1./thresh; 28749d54b7f4SStefano Zampini lower = 0.; 28759d54b7f4SStefano Zampini } 2876862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 2877ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 2878f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 2879f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 28809ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 2881aff50787SStefano Zampini PetscInt j,k; 2882aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 2883aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 2884aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 288508122e43SStefano Zampini } 288608122e43SStefano Zampini for (j=0;j<subset_size;j++) { 2887aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 2888aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 2889aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 2890aff50787SStefano Zampini } 289108122e43SStefano Zampini } 289208122e43SStefano Zampini } else { 289308122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 289408122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 289508122e43SStefano Zampini } 28968bec7fa6SStefano Zampini } else { 2897f6f667cfSStefano Zampini S = Sarray + cumarray; 2898f6f667cfSStefano Zampini St = Starray + cumarray; 28998bec7fa6SStefano Zampini } 2900aff50787SStefano Zampini /* see if we can save some work */ 2901b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 2902aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 2903aff50787SStefano Zampini } 2904aff50787SStefano Zampini 2905b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 2906aff50787SStefano Zampini B_neigs = 0; 2907aff50787SStefano Zampini } else { 29089ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 290908122e43SStefano Zampini PetscBLASInt B_itype = 1; 2910f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 29114c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 29129552c7c7SStefano Zampini PetscInt nmin_s; 2913b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 291408122e43SStefano Zampini 2915fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2916eee23b56SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %d/%d size %d count %d fid %d.\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]+1,pcbddc->mat_graph->which_dof[idxs[0]]); 2917fd14bc51SStefano Zampini } 2918d16cbb6bSStefano Zampini 2919b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 2920b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 2921b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 2922b7ab4a40SStefano Zampini } 2923b7ab4a40SStefano Zampini 292408122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2925b7ab4a40SStefano Zampini if (compute_range) { 2926d16cbb6bSStefano Zampini 2927d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 292808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 29299d54b7f4SStefano 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)); 293008122e43SStefano Zampini #else 29319d54b7f4SStefano 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)); 293208122e43SStefano Zampini #endif 2933b7ab4a40SStefano Zampini } else if (!same_data) { 2934d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 2935d16cbb6bSStefano Zampini B_IL = 1; 2936d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 29379d54b7f4SStefano 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)); 2938d16cbb6bSStefano Zampini #else 29399d54b7f4SStefano 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)); 2940d16cbb6bSStefano Zampini #endif 2941b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 2942b7ab4a40SStefano Zampini PetscInt k; 2943b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 2944b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 2945b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 2946b7ab4a40SStefano Zampini nmin = nmax; 2947b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 2948b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 2949b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 2950b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 2951b7ab4a40SStefano Zampini } 2952d16cbb6bSStefano Zampini } 295308122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 295408122e43SStefano Zampini if (B_ierr) { 29556c4ed002SBarry 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); 29566c4ed002SBarry 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); 29576c4ed002SBarry 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); 295808122e43SStefano Zampini } 295908122e43SStefano Zampini 296008122e43SStefano Zampini if (B_neigs > nmax) { 2961fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2962fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 2963fd14bc51SStefano Zampini } 29649d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 296508122e43SStefano Zampini B_neigs = nmax; 296608122e43SStefano Zampini } 296708122e43SStefano Zampini 29689552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 29699552c7c7SStefano Zampini if (B_neigs < nmin_s) { 297008122e43SStefano Zampini PetscBLASInt B_neigs2; 297108122e43SStefano Zampini 29729d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2973f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 29749d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 29759d54b7f4SStefano Zampini } else { 29769d54b7f4SStefano Zampini B_IL = B_neigs + 1; 29779d54b7f4SStefano Zampini B_IU = nmin_s; 29789d54b7f4SStefano Zampini } 2979fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2980fd14bc51SStefano 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); 2981fd14bc51SStefano Zampini } 29829ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 29831ae86dd6SStefano Zampini PetscInt j,k; 298408122e43SStefano Zampini for (j=0;j<subset_size;j++) { 29851ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 29861ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 29871ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 298808122e43SStefano Zampini } 298908122e43SStefano Zampini } 299008122e43SStefano Zampini } else { 299108122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 299208122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 299308122e43SStefano Zampini } 299408122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 299508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 29969d54b7f4SStefano 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)); 299708122e43SStefano Zampini #else 29989d54b7f4SStefano 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)); 299908122e43SStefano Zampini #endif 300008122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 300108122e43SStefano Zampini B_neigs += B_neigs2; 300208122e43SStefano Zampini } 300308122e43SStefano Zampini if (B_ierr) { 30046c4ed002SBarry 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); 30056c4ed002SBarry 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); 30066c4ed002SBarry 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); 300708122e43SStefano Zampini } 3008fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3009ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 301008122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 301108122e43SStefano Zampini if (eigs[j] == 0.0) { 3012ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 301308122e43SStefano Zampini } else { 30149d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3015ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 30169d54b7f4SStefano Zampini } else { 30179d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 30189d54b7f4SStefano Zampini } 3019fd14bc51SStefano Zampini } 302008122e43SStefano Zampini } 302108122e43SStefano Zampini } 302208122e43SStefano Zampini } else { 302308122e43SStefano Zampini /* TODO */ 302408122e43SStefano Zampini } 3025aff50787SStefano Zampini } 30266c3e6151SStefano Zampini /* change the basis back to the original one */ 30276c3e6151SStefano Zampini if (sub_schurs->change) { 302872b8c272SStefano Zampini Mat change,phi,phit; 30296c3e6151SStefano Zampini 30306c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 30316c3e6151SStefano Zampini PetscInt ii; 30326c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 30336c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 30346c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 3035684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3036684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 3037684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 3038684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3039684229deSStefano Zampini #else 30406c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 3041684229deSStefano Zampini #endif 30426c3e6151SStefano Zampini } 30436c3e6151SStefano Zampini } 30446c3e6151SStefano Zampini } 304572b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 30466c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 304772b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 30486c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 30496c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 30506c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 30516c3e6151SStefano Zampini } 30528bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 30538bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 30549162d606SStefano Zampini if (B_neigs) { 30559162d606SStefano 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); 3056fd14bc51SStefano Zampini 3057fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 30589552c7c7SStefano Zampini PetscInt ii; 30599552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 3060ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 30619552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 3062ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3063ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3064ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3065ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3066ac47001eSStefano Zampini #else 3067ac47001eSStefano 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); 3068ac47001eSStefano Zampini #endif 30699552c7c7SStefano Zampini } 30709552c7c7SStefano Zampini } 3071fd14bc51SStefano Zampini } 30729162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 30739162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 30749162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 30759162d606SStefano Zampini cum++; 307608122e43SStefano Zampini } 307708122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 307808122e43SStefano Zampini /* shift for next computation */ 307908122e43SStefano Zampini cumarray += subset_size*subset_size; 308008122e43SStefano Zampini } 3081fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3082fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3083fd14bc51SStefano Zampini } 308408122e43SStefano Zampini 308508122e43SStefano Zampini if (mss) { 308608122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 308708122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3088f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3089f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3090f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 309108122e43SStefano Zampini } 3092f6f667cfSStefano Zampini if (allocated_S_St) { 3093f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3094f6f667cfSStefano Zampini } 3095f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 309608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 309708122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 309808122e43SStefano Zampini #endif 309908122e43SStefano Zampini if (pcbddc->dbg_flag) { 31001b968477SStefano Zampini PetscInt maxneigs_r; 3101b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 31029b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 310308122e43SStefano Zampini } 310408122e43SStefano Zampini PetscFunctionReturn(0); 310508122e43SStefano Zampini } 3106b1b3d7a2SStefano Zampini 3107674ae819SStefano Zampini #undef __FUNCT__ 3108c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 3109c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3110c8587f34SStefano Zampini { 31118629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3112c8587f34SStefano Zampini PetscErrorCode ierr; 3113c8587f34SStefano Zampini 3114c8587f34SStefano Zampini PetscFunctionBegin; 3115f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 31165e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3117c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3118c8587f34SStefano Zampini 3119684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 31200fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3121684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3122c8587f34SStefano Zampini 31238629588bSStefano Zampini /* 31248629588bSStefano Zampini Setup local correction and local part of coarse basis. 31258629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 31268629588bSStefano Zampini */ 312747f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 31288629588bSStefano Zampini 31298629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 31308629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 31318629588bSStefano Zampini 31328629588bSStefano Zampini /* free */ 31338629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3134c8587f34SStefano Zampini PetscFunctionReturn(0); 3135c8587f34SStefano Zampini } 3136c8587f34SStefano Zampini 3137c8587f34SStefano Zampini #undef __FUNCT__ 3138674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 3139674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3140674ae819SStefano Zampini { 3141674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3142674ae819SStefano Zampini PetscErrorCode ierr; 3143674ae819SStefano Zampini 3144674ae819SStefano Zampini PetscFunctionBegin; 3145674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 314630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3147674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3148785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3149674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3150f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3151f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3152785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 315363602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 315463602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3155674ae819SStefano Zampini PetscFunctionReturn(0); 3156674ae819SStefano Zampini } 3157674ae819SStefano Zampini 3158674ae819SStefano Zampini #undef __FUNCT__ 3159674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 3160674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3161674ae819SStefano Zampini { 3162674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 31634f1b2e48SStefano Zampini PetscInt i; 3164674ae819SStefano Zampini PetscErrorCode ierr; 3165674ae819SStefano Zampini 3166674ae819SStefano Zampini PetscFunctionBegin; 31671e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 31681e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3169a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3170b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3171674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 317216909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 31731dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3174674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3175669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3176fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 3177a13144ffSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 3178674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 31794f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 31804f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 31814f1b2e48SStefano Zampini } 31824f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3183b334f244SStefano Zampini if (pcbddc->sub_schurs) { 3184b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 3185b334f244SStefano Zampini } 3186c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 31878af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 3188674ae819SStefano Zampini PetscFunctionReturn(0); 3189674ae819SStefano Zampini } 3190674ae819SStefano Zampini 3191674ae819SStefano Zampini #undef __FUNCT__ 3192674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 3193674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3194674ae819SStefano Zampini { 3195674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3196674ae819SStefano Zampini PetscErrorCode ierr; 3197674ae819SStefano Zampini 3198674ae819SStefano Zampini PetscFunctionBegin; 3199674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 320058da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3201ca92afb2SStefano Zampini PetscScalar *array; 320206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 320306656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 320458da7f69SStefano Zampini } 3205674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3206674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 320715aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 320815aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3209674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3210674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3211674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 321206656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3213674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3214674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 32158ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3216674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3217674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3218674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 3219f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 3220f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 3221f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 3222f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3223727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 32240e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3225f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 322670cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 322781d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 32280369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 32291dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 32304f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 32318b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3232ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3233ca92afb2SStefano Zampini PetscInt i; 3234ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3235ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3236ca92afb2SStefano Zampini } 3237ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3238ca92afb2SStefano Zampini } 32394f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3240674ae819SStefano Zampini PetscFunctionReturn(0); 3241674ae819SStefano Zampini } 3242674ae819SStefano Zampini 3243674ae819SStefano Zampini #undef __FUNCT__ 3244f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 3245f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 32466bfb1811SStefano Zampini { 32476bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 32486bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 32496bfb1811SStefano Zampini VecType impVecType; 32504f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 32516bfb1811SStefano Zampini PetscErrorCode ierr; 32526bfb1811SStefano Zampini 32536bfb1811SStefano Zampini PetscFunctionBegin; 32544f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3255b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 32566bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3257e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3258e7b262bdSStefano Zampini /* R nodes */ 3259e7b262bdSStefano Zampini old_size = -1; 3260e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3261e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3262e7b262bdSStefano Zampini } 3263e7b262bdSStefano Zampini if (n_R != old_size) { 3264e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3265e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 32666bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 32676bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 32686bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 32696bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3270e7b262bdSStefano Zampini } 3271e7b262bdSStefano Zampini /* local primal dofs */ 3272e7b262bdSStefano Zampini old_size = -1; 3273e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3274e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3275e7b262bdSStefano Zampini } 3276e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3277e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 327883b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3279e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 32806bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3281e7b262bdSStefano Zampini } 3282e7b262bdSStefano Zampini /* local explicit constraints */ 3283e7b262bdSStefano Zampini old_size = -1; 3284e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3285e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3286e7b262bdSStefano Zampini } 3287e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3288e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 328983b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 329083b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 329183b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 329283b7ccabSStefano Zampini } 32936bfb1811SStefano Zampini PetscFunctionReturn(0); 32946bfb1811SStefano Zampini } 32956bfb1811SStefano Zampini 32966bfb1811SStefano Zampini #undef __FUNCT__ 329747f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 329847f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 329988ebb749SStefano Zampini { 330025084f0cSStefano Zampini PetscErrorCode ierr; 330125084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 330288ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 330388ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3304d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 330525084f0cSStefano Zampini /* submatrices of local problem */ 330680677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 330706656605SStefano Zampini /* submatrices of local coarse problem */ 330806656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 330925084f0cSStefano Zampini /* working matrices */ 331006656605SStefano Zampini Mat C_CR; 331125084f0cSStefano Zampini /* additional working stuff */ 331206656605SStefano Zampini PC pc_R; 33134f1b2e48SStefano Zampini Mat F; 33145cbda25cSStefano Zampini Vec dummy_vec; 3315a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 331625084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 331706656605SStefano Zampini PetscScalar *work; 331806656605SStefano Zampini PetscInt *idx_V_B; 3319ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 332006656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 3321ffd830a3SStefano Zampini 332225084f0cSStefano Zampini /* some shortcuts to scalars */ 332306656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 332488ebb749SStefano Zampini 332588ebb749SStefano Zampini PetscFunctionBegin; 33269a962809SStefano 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"); 3327ffd830a3SStefano Zampini 3328ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3329b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 33304f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3331b371cd4fSStefano Zampini n_B = pcis->n_B; 3332b371cd4fSStefano Zampini n_D = pcis->n - n_B; 333388ebb749SStefano Zampini n_R = pcis->n - n_vertices; 333488ebb749SStefano Zampini 333588ebb749SStefano Zampini /* vertices in boundary numbering */ 3336785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 33370e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 33386c4ed002SBarry 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); 333988ebb749SStefano Zampini 334006656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3341019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 334206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 334306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 334406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 334506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 334606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 334706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 334806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 334906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 335006656605SStefano Zampini 335106656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 335206656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 335306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 335406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 335506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3356ffd830a3SStefano Zampini lda_rhs = n_R; 3357a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 335806656605SStefano Zampini if (isLU || isILU || isCHOL) { 335906656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3360b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3361df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3362d62866d3SStefano Zampini MatFactorType type; 3363d62866d3SStefano Zampini 3364df4d28bfSStefano Zampini F = reuse_solver->F; 33656816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3366d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 3367ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 336822db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 336906656605SStefano Zampini } else { 337006656605SStefano Zampini F = NULL; 337106656605SStefano Zampini } 337206656605SStefano Zampini 3373ffd830a3SStefano Zampini /* allocate workspace */ 3374ffd830a3SStefano Zampini n = 0; 3375ffd830a3SStefano Zampini if (n_constraints) { 3376ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3377ffd830a3SStefano Zampini } 3378ffd830a3SStefano Zampini if (n_vertices) { 3379ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3380ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3381ffd830a3SStefano Zampini } 3382ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3383ffd830a3SStefano Zampini 33845cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 33855cbda25cSStefano Zampini dummy_vec = NULL; 33865cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 33875cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 33885cbda25cSStefano Zampini } 33895cbda25cSStefano Zampini 339088ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 339188ebb749SStefano Zampini if (n_constraints) { 339272b8c272SStefano Zampini Mat M1,M2,M3,C_B; 339306656605SStefano Zampini IS is_aux; 339480677318SStefano Zampini PetscScalar *array,*array2; 339506656605SStefano Zampini 3396f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 339780677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 339888ebb749SStefano Zampini 339925084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 340025084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 34018ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 340272b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 340388ebb749SStefano Zampini 340480677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 340580677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 3406ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 340788ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 340806656605SStefano Zampini const PetscScalar *row_cmat_values; 340906656605SStefano Zampini const PetscInt *row_cmat_indices; 341006656605SStefano Zampini PetscInt size_of_constraint,j; 341188ebb749SStefano Zampini 341206656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 341306656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 3414ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 341506656605SStefano Zampini } 341606656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 341706656605SStefano Zampini } 3418ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 341906656605SStefano Zampini if (F) { 342006656605SStefano Zampini Mat B; 342106656605SStefano Zampini 3422ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 3423a3df083aSStefano Zampini if (need_benign_correction) { 3424df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3425a3df083aSStefano Zampini 342672b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 342772b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 3428a3df083aSStefano Zampini } 342980677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 3430a3df083aSStefano Zampini if (need_benign_correction) { 3431a3df083aSStefano Zampini PetscScalar *marr; 3432df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3433a3df083aSStefano Zampini 3434a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 34355cbda25cSStefano Zampini if (lda_rhs != n_R) { 34365cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 34375cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 34385cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 34395cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 34405cbda25cSStefano Zampini } 34415cbda25cSStefano Zampini } else { 3442a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 3443a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 34445cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3445a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3446a3df083aSStefano Zampini } 34475cbda25cSStefano Zampini } 3448a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 3449a3df083aSStefano Zampini } 345006656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 345106656605SStefano Zampini } else { 345280677318SStefano Zampini PetscScalar *marr; 345380677318SStefano Zampini 345480677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 345506656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3456ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3457ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 345806656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 345906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 346006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 346106656605SStefano Zampini } 346280677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 346306656605SStefano Zampini } 346480677318SStefano Zampini if (!pcbddc->switch_static) { 346580677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 346680677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 346780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 346880677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3469ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 347080677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 347180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 347280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 347380677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 347480677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 347580677318SStefano Zampini } 347680677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 347780677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 347872b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 347980677318SStefano Zampini } else { 3480ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3481ffd830a3SStefano Zampini IS dummy; 3482ffd830a3SStefano Zampini 3483ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 348472b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3485ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3486ffd830a3SStefano Zampini } else { 348780677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 348880677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3489ffd830a3SStefano Zampini } 349025084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 349180677318SStefano Zampini } 349280677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 349380677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 349480677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 349506656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 349606656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 349780677318SStefano Zampini if (isCHOL) { 349880677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 349980677318SStefano Zampini } else { 350025084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 350180677318SStefano Zampini } 350280677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 350306656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 350425084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 350525084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 350625084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 350780677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 350872b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 350972b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 351006656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 351106656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 3512f4ddd8eeSStefano Zampini } 3513fc227af8SStefano Zampini 3514fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 351588ebb749SStefano Zampini if (n_vertices) { 351606656605SStefano Zampini IS is_aux; 35173a50541eSStefano Zampini 3518b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 35196816873aSStefano Zampini IS tis; 35206816873aSStefano Zampini 35216816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 35226816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 35236816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 35246816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 35256816873aSStefano Zampini } else { 35263a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 35276816873aSStefano Zampini } 35289577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 35299577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 353004708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 353125084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 353288ebb749SStefano Zampini } 353388ebb749SStefano Zampini 353488ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 3535f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 353606656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 353706656605SStefano Zampini if (pcbddc->coarse_phi_D) { 353806656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 353906656605SStefano Zampini } 3540f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 354106656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 354206656605SStefano Zampini PetscScalar *marray; 354306656605SStefano Zampini 354406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 354506656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 3546f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3547f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3548f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3549f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3550f4ddd8eeSStefano Zampini } 3551f4ddd8eeSStefano Zampini } 355206656605SStefano Zampini 3553f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 355406656605SStefano Zampini PetscScalar *marray; 355588ebb749SStefano Zampini 355606656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 35578eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 355806656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 355988ebb749SStefano Zampini } 35603301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 356106656605SStefano Zampini n *= 2; 356288ebb749SStefano Zampini } 356306656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 356406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 356506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 35668eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 356706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 356806656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 356988ebb749SStefano Zampini } 35703301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 357106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 35728eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 357306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 357406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 357588ebb749SStefano Zampini } 357688ebb749SStefano Zampini } else { 3577c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 3578c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 35791b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3580c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 3581c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 3582c0553b1fSStefano Zampini } 358388ebb749SStefano Zampini } 358406656605SStefano Zampini } 3585019a44ceSStefano Zampini 358606656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 35874f1b2e48SStefano Zampini p0_lidx_I = NULL; 35884f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 3589d12edf2fSStefano Zampini const PetscInt *idxs; 3590d12edf2fSStefano Zampini 3591d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 35924f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 35934f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 35944f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 35954f1b2e48SStefano Zampini } 3596d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 3597d12edf2fSStefano Zampini } 3598d16cbb6bSStefano Zampini 359906656605SStefano Zampini /* vertices */ 360006656605SStefano Zampini if (n_vertices) { 360116f15bc4SStefano Zampini 3602af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 360304708bb6SStefano Zampini 360416f15bc4SStefano Zampini if (n_R) { 360514393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 360606656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 360716f15bc4SStefano Zampini PetscScalar *x,*y; 360804708bb6SStefano Zampini PetscBool isseqaij; 360906656605SStefano Zampini 361021eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 361114393ed6SStefano Zampini if (need_benign_correction) { 361214393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 361314393ed6SStefano Zampini IS is_p0; 361414393ed6SStefano Zampini PetscInt *idxs_p0,n; 361514393ed6SStefano Zampini 361614393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 361714393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 361814393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 3619af25d912SStefano 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); 362014393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 362114393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 362214393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 362314393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 362414393ed6SStefano Zampini } 362514393ed6SStefano Zampini 3626ffd830a3SStefano Zampini if (lda_rhs == n_R) { 3627af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3628ffd830a3SStefano Zampini } else { 3629ca92afb2SStefano Zampini PetscScalar *av,*array; 3630ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 3631ca92afb2SStefano Zampini PetscInt n; 3632ca92afb2SStefano Zampini PetscBool flg_row; 3633ffd830a3SStefano Zampini 3634ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 3635ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 36369d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3637ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3638ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 3639ca92afb2SStefano Zampini for (i=0;i<n;i++) { 3640ca92afb2SStefano Zampini PetscInt j; 3641ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 3642ffd830a3SStefano Zampini } 3643ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3644ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3645ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 3646ffd830a3SStefano Zampini } 3647ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3648a3df083aSStefano Zampini if (need_benign_correction) { 3649df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3650a3df083aSStefano Zampini PetscScalar *marr; 3651a3df083aSStefano Zampini 3652a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 365314393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 365414393ed6SStefano Zampini 365514393ed6SStefano Zampini | 0 0 0 | (V) 365614393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 365714393ed6SStefano Zampini | 0 0 -1 | (p0) 365814393ed6SStefano Zampini 365914393ed6SStefano Zampini */ 3660df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 366114393ed6SStefano Zampini const PetscScalar *vals; 366214393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 366314393ed6SStefano Zampini PetscInt n,j,nz; 366414393ed6SStefano Zampini 3665df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3666df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 366714393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 366814393ed6SStefano Zampini for (j=0;j<n;j++) { 366914393ed6SStefano Zampini PetscScalar val = vals[j]; 367014393ed6SStefano Zampini PetscInt k,col = idxs[j]; 367114393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 367214393ed6SStefano Zampini } 367314393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3674df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 367514393ed6SStefano Zampini } 367672b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 367772b8c272SStefano Zampini } 367872b8c272SStefano Zampini if (F) { 367914393ed6SStefano Zampini /* need to correct the rhs */ 368072b8c272SStefano Zampini if (need_benign_correction) { 368172b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 368272b8c272SStefano Zampini PetscScalar *marr; 368372b8c272SStefano Zampini 368472b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 36855cbda25cSStefano Zampini if (lda_rhs != n_R) { 36865cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 36875cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 36885cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 36895cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 36905cbda25cSStefano Zampini } 36915cbda25cSStefano Zampini } else { 3692a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3693a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 36945cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3695a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3696a3df083aSStefano Zampini } 36975cbda25cSStefano Zampini } 3698a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 3699a3df083aSStefano Zampini } 370006656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 370114393ed6SStefano Zampini /* need to correct the solution */ 3702a3df083aSStefano Zampini if (need_benign_correction) { 3703df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3704a3df083aSStefano Zampini PetscScalar *marr; 3705a3df083aSStefano Zampini 3706a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 37075cbda25cSStefano Zampini if (lda_rhs != n_R) { 37085cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 37095cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 37105cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 37115cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 37125cbda25cSStefano Zampini } 37135cbda25cSStefano Zampini } else { 3714a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3715a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 37165cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3717a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3718a3df083aSStefano Zampini } 37195cbda25cSStefano Zampini } 3720a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 3721a3df083aSStefano Zampini } 372206656605SStefano Zampini } else { 372306656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 372406656605SStefano Zampini for (i=0;i<n_vertices;i++) { 3725ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 3726ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 372706656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 372806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 372906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 373006656605SStefano Zampini } 373106656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 373206656605SStefano Zampini } 373380677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3734ffd830a3SStefano Zampini /* S_VV and S_CV */ 373506656605SStefano Zampini if (n_constraints) { 373606656605SStefano Zampini Mat B; 373780677318SStefano Zampini 3738ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 373980677318SStefano Zampini for (i=0;i<n_vertices;i++) { 3740ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3741ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 374280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 374380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 374480677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 374580677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 374680677318SStefano Zampini } 3747ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 374880677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 374980677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 3750ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 375180677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 375206656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 3753ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 3754ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 375506656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 375606656605SStefano Zampini } 375704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 375804708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 3759511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 376004708bb6SStefano Zampini } 3761ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3762ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 3763ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3764ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 3765ffd830a3SStefano Zampini } 376606656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 376714393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 376814393ed6SStefano Zampini if (need_benign_correction) { 3769df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 377014393ed6SStefano Zampini PetscScalar *marr,*sums; 377114393ed6SStefano Zampini 377214393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 3773f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 3774df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 377514393ed6SStefano Zampini const PetscScalar *vals; 377614393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 377714393ed6SStefano Zampini PetscInt n,j,nz; 377814393ed6SStefano Zampini 3779df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3780df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 378114393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 378214393ed6SStefano Zampini PetscInt k; 378314393ed6SStefano Zampini sums[j] = 0.; 378414393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 378514393ed6SStefano Zampini } 378614393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 378714393ed6SStefano Zampini for (j=0;j<n;j++) { 378814393ed6SStefano Zampini PetscScalar val = vals[j]; 378914393ed6SStefano Zampini PetscInt k; 379014393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 379114393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 379214393ed6SStefano Zampini } 379314393ed6SStefano Zampini } 379414393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3795df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 379614393ed6SStefano Zampini } 379714393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 3798f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 379914393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 380014393ed6SStefano Zampini } 380180677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 380206656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 380306656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 380406656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 380506656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 380606656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 380706656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 380806656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3809d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 3810019a44ceSStefano Zampini } else { 3811d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3812d16cbb6bSStefano Zampini } 381321eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 3814d16cbb6bSStefano Zampini 381506656605SStefano Zampini /* coarse basis functions */ 381606656605SStefano Zampini for (i=0;i<n_vertices;i++) { 381716f15bc4SStefano Zampini PetscScalar *y; 381816f15bc4SStefano Zampini 3819ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 382006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 382106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 382206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 382306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 382406656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 382506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 382606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 382706656605SStefano Zampini 382806656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 38294f1b2e48SStefano Zampini PetscInt j; 38304f1b2e48SStefano Zampini 383106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 383206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 383306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 383406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 383506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 38364f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 383706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 383806656605SStefano Zampini } 383906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 384006656605SStefano Zampini } 384104708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 384204708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 384306656605SStefano Zampini } 38445cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 384506656605SStefano Zampini 384606656605SStefano Zampini if (n_constraints) { 384706656605SStefano Zampini Mat B; 384806656605SStefano Zampini 3849ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 385006656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 385180677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 385206656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 385306656605SStefano Zampini if (n_vertices) { 385480677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 385580677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 385680677318SStefano Zampini } else { 385780677318SStefano Zampini Mat S_VCt; 385880677318SStefano Zampini 3859ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3860ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 386172b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 3862ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 3863ffd830a3SStefano Zampini } 386480677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 386580677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 386680677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 386780677318SStefano Zampini } 386806656605SStefano Zampini } 386906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 387006656605SStefano Zampini /* coarse basis functions */ 387106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 387206656605SStefano Zampini PetscScalar *y; 387306656605SStefano Zampini 3874ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 387506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 387606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 387706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 387806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 387906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 388006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 388106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 38824f1b2e48SStefano Zampini PetscInt j; 38834f1b2e48SStefano Zampini 388406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 388506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 388606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 388706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 388806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 38894f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 389006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 389106656605SStefano Zampini } 389206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 389306656605SStefano Zampini } 389406656605SStefano Zampini } 389580677318SStefano Zampini if (n_constraints) { 389680677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 389780677318SStefano Zampini } 38984f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 389972b8c272SStefano Zampini 390072b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 390172b8c272SStefano Zampini if (pcbddc->benign_n) { 390272b8c272SStefano Zampini Mat B0_B,B0_BPHI; 390372b8c272SStefano Zampini IS is_dummy; 390472b8c272SStefano Zampini PetscScalar *data; 390572b8c272SStefano Zampini PetscInt j; 390672b8c272SStefano Zampini 390772b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 390872b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 390972b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 391072b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 391186c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 391272b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 391372b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 391472b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 391572b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 391672b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 391772b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 391872b8c272SStefano Zampini } 391972b8c272SStefano Zampini } 392072b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 392172b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 392272b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 392372b8c272SStefano Zampini } 3924019a44ceSStefano Zampini 392506656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 39263301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3927ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 3928ffd830a3SStefano Zampini PetscScalar *marray; 392906656605SStefano Zampini 393006656605SStefano Zampini if (n_constraints) { 3931ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 393206656605SStefano Zampini 3933af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 393406656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 3935ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 393616f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 393706656605SStefano Zampini if (n_vertices) { 3938ffd830a3SStefano Zampini Mat S_VCT; 393906656605SStefano Zampini 394006656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 3941ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 394216f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 394306656605SStefano Zampini } 3944ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 39455b782168SStefano Zampini } else { 39465b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 394706656605SStefano Zampini } 394816f15bc4SStefano Zampini if (n_vertices && n_R) { 3949ffd830a3SStefano Zampini PetscScalar *av,*marray; 3950ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 3951ffd830a3SStefano Zampini PetscInt n; 3952ffd830a3SStefano Zampini PetscBool flg_row; 395306656605SStefano Zampini 3954ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 3955af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3956ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3957ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 3958ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3959ffd830a3SStefano Zampini for (i=0;i<n;i++) { 3960ffd830a3SStefano Zampini PetscInt j; 3961ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 3962ffd830a3SStefano Zampini } 3963ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 3964ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3965ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 396606656605SStefano Zampini } 396706656605SStefano Zampini 3968ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 3969ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3970ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 3971ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 3972ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 397306656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 397406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 397506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 397606656605SStefano Zampini } 3977ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 39785b782168SStefano Zampini if (B_C) { 3979ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 3980ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 3981ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 3982ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 3983ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 3984ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3985ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 398606656605SStefano Zampini } 3987ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 39885b782168SStefano Zampini } 398906656605SStefano Zampini /* coarse basis functions */ 399006656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 399106656605SStefano Zampini PetscScalar *y; 399206656605SStefano Zampini 3993ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 399406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 399506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 399606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 399706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 399806656605SStefano Zampini if (i<n_vertices) { 399906656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 400006656605SStefano Zampini } 400106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 400206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 400306656605SStefano Zampini 400406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 400506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 400606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 400706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 400806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 400906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 401006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 401106656605SStefano Zampini } 401206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 401306656605SStefano Zampini } 4014ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 4015ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 401606656605SStefano Zampini } 4017d62866d3SStefano Zampini /* free memory */ 401888ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 401906656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 402006656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 402106656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 402206656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 4023d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4024d62866d3SStefano Zampini if (n_vertices) { 4025d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 4026d62866d3SStefano Zampini } 4027d62866d3SStefano Zampini if (n_constraints) { 4028d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 4029d62866d3SStefano Zampini } 403088ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 403188ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 403288ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 4033d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 403488ebb749SStefano Zampini Mat coarse_sub_mat; 403525084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 403688ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 403788ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 403888ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 40398bec7fa6SStefano Zampini Mat C_B,CPHI; 40408bec7fa6SStefano Zampini IS is_dummy; 40418bec7fa6SStefano Zampini Vec mones; 404288ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 404388ebb749SStefano Zampini PetscReal real_value; 404488ebb749SStefano Zampini 4045a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 4046a3df083aSStefano Zampini Mat A; 4047a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 4048a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 4049a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 4050a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 4051a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4052a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 4053a3df083aSStefano Zampini } else { 405488ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 405588ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 405688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 405788ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4058a3df083aSStefano Zampini } 405988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 406088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 4061ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 406288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 406388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 406488ebb749SStefano Zampini } 406588ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 406688ebb749SStefano Zampini 406725084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 40683301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 406925084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4070ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 407188ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 407288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 407388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 407488ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 407588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 407688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 407788ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 407888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 407988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 408088ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 408188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 408288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 408388ebb749SStefano Zampini } else { 408488ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 408588ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 408688ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 408788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 408888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 408988ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 409088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 409188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 409288ebb749SStefano Zampini } 409388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 409488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 409588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4096511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 40974f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4098fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 4099d12edf2fSStefano Zampini PetscScalar *data,*data2; 41004f1b2e48SStefano Zampini PetscInt j; 4101d12edf2fSStefano Zampini 41024f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 4103fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4104d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 410586c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4106d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 4107d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 41084f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 41094f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4110d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 41114f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 41124f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 41134f1b2e48SStefano Zampini } 4114d12edf2fSStefano Zampini } 4115d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 4116d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 4117d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4118d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4119d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4120d12edf2fSStefano Zampini } 4121d12edf2fSStefano Zampini #if 0 4122d12edf2fSStefano Zampini { 4123d12edf2fSStefano Zampini PetscViewer viewer; 4124d12edf2fSStefano Zampini char filename[256]; 4125ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4126d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4127d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4128ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4129ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4130ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4131d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 413272b8c272SStefano Zampini if (save_change) { 413372b8c272SStefano Zampini Mat phi_B; 413472b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 413572b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 413672b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 413772b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 413872b8c272SStefano Zampini } else { 4139ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4140ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 414172b8c272SStefano Zampini } 4142ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4143ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4144ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4145ffd830a3SStefano Zampini } 4146ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4147ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4148ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4149ffd830a3SStefano Zampini } 415072b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4151ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4152ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4153ffd830a3SStefano Zampini } 4154d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4155d12edf2fSStefano Zampini } 4156d12edf2fSStefano Zampini #endif 415781d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 41588bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 41591575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 416006656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 41618bec7fa6SStefano Zampini 41628bec7fa6SStefano Zampini /* check constraints */ 4163a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 4164a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 41654f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 41668bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4167a00504b5SStefano Zampini } else { 4168a00504b5SStefano Zampini PetscScalar *data; 4169a00504b5SStefano Zampini Mat tmat; 4170a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4171a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4172a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4173a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4174a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4175a00504b5SStefano Zampini } 41768bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 41778bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 41788bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 41798bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4180bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4181ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4182bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4183bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4184bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4185bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4186bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 418788ebb749SStefano Zampini } 41888bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 41898bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 41908bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 41918bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 419225084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 419388ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 419488ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 419588ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 419688ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 419788ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 419888ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 419988ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 420088ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 420188ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 420288ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4203ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 420488ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 420588ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 420688ebb749SStefano Zampini } 420788ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 420888ebb749SStefano Zampini } 42098629588bSStefano Zampini /* get back data */ 42108629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 421188ebb749SStefano Zampini PetscFunctionReturn(0); 421288ebb749SStefano Zampini } 421388ebb749SStefano Zampini 421488ebb749SStefano Zampini #undef __FUNCT__ 4215d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 4216d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4217aa0d41d4SStefano Zampini { 4218d65f70fdSStefano Zampini Mat *work_mat; 4219d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4220d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4221c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4222aa0d41d4SStefano Zampini PetscErrorCode ierr; 4223aa0d41d4SStefano Zampini 4224aa0d41d4SStefano Zampini PetscFunctionBegin; 4225d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4226d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4227d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4228d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4229aa0d41d4SStefano Zampini 4230d65f70fdSStefano Zampini if (!rsorted) { 4231906d46d4SStefano Zampini const PetscInt *idxs; 4232906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4233aa0d41d4SStefano Zampini 4234d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4235d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4236d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4237d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4238aa0d41d4SStefano Zampini } 4239d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4240d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4241d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4242d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4243aa0d41d4SStefano Zampini } 4244d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4245d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4246d65f70fdSStefano Zampini } else { 4247d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4248d65f70fdSStefano Zampini isrow_s = isrow; 4249aa0d41d4SStefano Zampini } 4250906d46d4SStefano Zampini 4251d65f70fdSStefano Zampini if (!csorted) { 4252d65f70fdSStefano Zampini if (isrow == iscol) { 4253d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4254d65f70fdSStefano Zampini iscol_s = isrow_s; 4255d65f70fdSStefano Zampini } else { 4256d65f70fdSStefano Zampini const PetscInt *idxs; 4257d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4258906d46d4SStefano Zampini 4259d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4260d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4261d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4262d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4263d65f70fdSStefano Zampini } 4264d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4265d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4266d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4267d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4268d65f70fdSStefano Zampini } 4269d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4270d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4271d65f70fdSStefano Zampini } 4272d65f70fdSStefano Zampini } else { 4273d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4274d65f70fdSStefano Zampini iscol_s = iscol; 4275d65f70fdSStefano Zampini } 4276d65f70fdSStefano Zampini 4277d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4278d65f70fdSStefano Zampini 4279d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4280906d46d4SStefano Zampini Mat new_mat; 4281d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4282906d46d4SStefano Zampini 4283d65f70fdSStefano Zampini if (!rsorted) { 4284d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4285d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4286d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4287d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4288906d46d4SStefano Zampini } 4289d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4290d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 4291d65f70fdSStefano Zampini } else { 4292d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 4293906d46d4SStefano Zampini } 4294d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 4295d65f70fdSStefano Zampini 4296d65f70fdSStefano Zampini if (!csorted) { 4297d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 4298d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 4299d65f70fdSStefano Zampini is_perm_c = is_perm_r; 4300d65f70fdSStefano Zampini } else { 4301d65f70fdSStefano Zampini PetscInt *idxs_c,i; 4302f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 4303d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 4304d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4305d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 4306d65f70fdSStefano Zampini } 4307d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 4308d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 4309d65f70fdSStefano Zampini } 4310d65f70fdSStefano Zampini } else { 4311d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 4312d65f70fdSStefano Zampini } 4313d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 4314d65f70fdSStefano Zampini 4315d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 4316d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 4317d65f70fdSStefano Zampini work_mat[0] = new_mat; 4318d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 4319d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 4320d65f70fdSStefano Zampini } 4321d65f70fdSStefano Zampini 4322d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 4323d65f70fdSStefano Zampini *B = work_mat[0]; 4324d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 4325d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 4326d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 4327d65f70fdSStefano Zampini PetscFunctionReturn(0); 4328d65f70fdSStefano Zampini } 4329d65f70fdSStefano Zampini 4330d65f70fdSStefano Zampini #undef __FUNCT__ 43315e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 43325e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 4333aa0d41d4SStefano Zampini { 4334aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 43355e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4336d65f70fdSStefano Zampini Mat new_mat; 43375e8657edSStefano Zampini IS is_local,is_global; 4338d65f70fdSStefano Zampini PetscInt local_size; 4339d65f70fdSStefano Zampini PetscBool isseqaij; 4340aa0d41d4SStefano Zampini PetscErrorCode ierr; 4341aa0d41d4SStefano Zampini 4342aa0d41d4SStefano Zampini PetscFunctionBegin; 4343aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 43445e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 43455e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 4346b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 4347aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 4348d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 4349aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 4350906d46d4SStefano Zampini 4351906d46d4SStefano Zampini /* check */ 4352906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4353906d46d4SStefano Zampini Vec x,x_change; 4354906d46d4SStefano Zampini PetscReal error; 4355906d46d4SStefano Zampini 43565e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 4357906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 43585e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 4359e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4360e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4361d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 436288428137SStefano Zampini if (!pcbddc->change_interior) { 436388428137SStefano Zampini const PetscScalar *x,*y,*v; 436488428137SStefano Zampini PetscReal lerror = 0.; 436588428137SStefano Zampini PetscInt i; 436688428137SStefano Zampini 436788428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 436888428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 436988428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 437088428137SStefano Zampini for (i=0;i<local_size;i++) 437188428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 437288428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 437388428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 437488428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 437588428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 437688428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4377637e8532SStefano Zampini if (error > PETSC_SMALL) { 4378637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4379637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on I: %1.6e\n",error); 4380637e8532SStefano Zampini } else { 4381637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on I: %1.6e\n",error); 4382637e8532SStefano Zampini } 4383637e8532SStefano Zampini } 438488428137SStefano Zampini } 4385e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4386e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4387906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4388906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4389637e8532SStefano Zampini if (error > PETSC_SMALL) { 4390637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4391637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 4392637e8532SStefano Zampini } else { 4393637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on N: %1.6e\n",error); 4394637e8532SStefano Zampini } 4395637e8532SStefano Zampini } 4396906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4397906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4398906d46d4SStefano Zampini } 4399906d46d4SStefano Zampini 440022d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 44019b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 440222d5777bSStefano Zampini if (isseqaij) { 4403a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4404a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 4405aa0d41d4SStefano Zampini } else { 4406a00504b5SStefano Zampini Mat work_mat; 44071cf9b237SStefano Zampini 4408a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4409aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4410a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 44111d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 4412aa0d41d4SStefano Zampini } 44133301b35fSStefano Zampini if (matis->A->symmetric_set) { 44143301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 4415e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 44163301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 4417e496cd5dSStefano Zampini #endif 44183301b35fSStefano Zampini } 4419d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 4420aa0d41d4SStefano Zampini PetscFunctionReturn(0); 4421aa0d41d4SStefano Zampini } 4422aa0d41d4SStefano Zampini 4423aa0d41d4SStefano Zampini #undef __FUNCT__ 4424a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 44258ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 4426a64d13efSStefano Zampini { 4427a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4428a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4429d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 443053892102SStefano Zampini PetscInt *idx_R_local=NULL; 44313a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 44323a50541eSStefano Zampini PetscInt vbs,bs; 44336816873aSStefano Zampini PetscBT bitmask=NULL; 4434a64d13efSStefano Zampini PetscErrorCode ierr; 4435a64d13efSStefano Zampini 4436a64d13efSStefano Zampini PetscFunctionBegin; 4437b23d619eSStefano Zampini /* 4438b23d619eSStefano Zampini No need to setup local scatters if 4439b23d619eSStefano Zampini - primal space is unchanged 4440b23d619eSStefano Zampini AND 4441b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 4442b23d619eSStefano Zampini AND 4443b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 4444b23d619eSStefano Zampini */ 4445b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 4446f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 4447f4ddd8eeSStefano Zampini } 4448f4ddd8eeSStefano Zampini /* destroy old objects */ 4449f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 4450f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 4451f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 4452a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 4453b371cd4fSStefano Zampini n_B = pcis->n_B; 4454b371cd4fSStefano Zampini n_D = pcis->n - n_B; 4455b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 44563a50541eSStefano Zampini 4457a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 44586816873aSStefano Zampini 445953892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 4460b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4461854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 4462a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 4463a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 44640e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 4465a64d13efSStefano Zampini } 4466a64d13efSStefano Zampini 4467a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 44684641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 44696816873aSStefano Zampini idx_R_local[n_R++] = i; 4470a64d13efSStefano Zampini } 4471a64d13efSStefano Zampini } 4472df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 4473df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 44746816873aSStefano Zampini 4475df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4476df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 44776816873aSStefano Zampini } 44783a50541eSStefano Zampini 44793a50541eSStefano Zampini /* Block code */ 44803a50541eSStefano Zampini vbs = 1; 44813a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 44823a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 44833a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 44843a50541eSStefano Zampini PetscInt *vary; 4485b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4486785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 44873a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 4488d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 4489d3df7717SStefano 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 */ 44900e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 4491d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 44923a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 44933a50541eSStefano Zampini is_blocked = PETSC_FALSE; 44943a50541eSStefano Zampini break; 44953a50541eSStefano Zampini } 44963a50541eSStefano Zampini } 4497d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 4498d3df7717SStefano Zampini } else { 4499d3df7717SStefano Zampini /* Verify directly the R set */ 4500d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 4501d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 4502d3df7717SStefano Zampini for (j=1; j<bs; j++) { 4503d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 4504d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 4505d3df7717SStefano Zampini break; 4506d3df7717SStefano Zampini } 4507d3df7717SStefano Zampini } 4508d3df7717SStefano Zampini } 4509d3df7717SStefano Zampini } 45103a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 45113a50541eSStefano Zampini vbs = bs; 45123a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 45133a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 45143a50541eSStefano Zampini } 45153a50541eSStefano Zampini } 45163a50541eSStefano Zampini } 45173a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 4518b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4519df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 452053892102SStefano Zampini 4521df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4522df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 452353892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 4524df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 452553892102SStefano Zampini } else { 45263a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 452753892102SStefano Zampini } 4528a64d13efSStefano Zampini 4529a64d13efSStefano Zampini /* print some info if requested */ 4530a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 4531a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4532a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 45331575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4534a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 4535a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 45364f1b2e48SStefano 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); 4537a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4538a64d13efSStefano Zampini } 4539a64d13efSStefano Zampini 4540a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 4541b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 45426816873aSStefano Zampini IS is_aux1,is_aux2; 45436816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 45446816873aSStefano Zampini 45453a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4546854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 4547854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 4548a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 45494641a718SStefano Zampini for (i=0; i<n_D; i++) { 45504641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 45514641a718SStefano Zampini } 4552a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4553a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 45544641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 45554641a718SStefano Zampini aux_array1[j++] = i; 4556a64d13efSStefano Zampini } 4557a64d13efSStefano Zampini } 4558a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4559a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4560a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 45614641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 45624641a718SStefano Zampini aux_array2[j++] = i; 4563a64d13efSStefano Zampini } 4564a64d13efSStefano Zampini } 4565a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4566a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 4567a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 4568a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4569a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 4570a64d13efSStefano Zampini 45718eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4572785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 4573a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 45744641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 45754641a718SStefano Zampini aux_array1[j++] = i; 4576a64d13efSStefano Zampini } 4577a64d13efSStefano Zampini } 4578a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4579a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 4580a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4581a64d13efSStefano Zampini } 45824641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 45833a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4584d62866d3SStefano Zampini } else { 4585df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 45866816873aSStefano Zampini IS tis; 45876816873aSStefano Zampini PetscInt schur_size; 45886816873aSStefano Zampini 4589df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 45906816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 4591df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 45926816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 45936816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 45946816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 45956816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 45966816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 4597d62866d3SStefano Zampini } 4598d62866d3SStefano Zampini } 4599a64d13efSStefano Zampini PetscFunctionReturn(0); 4600a64d13efSStefano Zampini } 4601a64d13efSStefano Zampini 4602304d26faSStefano Zampini 4603304d26faSStefano Zampini #undef __FUNCT__ 4604304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 4605684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 4606304d26faSStefano Zampini { 4607304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4608304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4609304d26faSStefano Zampini PC pc_temp; 4610304d26faSStefano Zampini Mat A_RR; 4611f4ddd8eeSStefano Zampini MatReuse reuse; 4612304d26faSStefano Zampini PetscScalar m_one = -1.0; 4613304d26faSStefano Zampini PetscReal value; 461404708bb6SStefano Zampini PetscInt n_D,n_R; 4615c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 4616304d26faSStefano Zampini PetscErrorCode ierr; 4617e604994aSStefano Zampini /* prefixes stuff */ 4618312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 4619e604994aSStefano Zampini size_t len; 4620304d26faSStefano Zampini 4621304d26faSStefano Zampini PetscFunctionBegin; 4622304d26faSStefano Zampini 4623e604994aSStefano Zampini /* compute prefixes */ 4624e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 4625e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 4626e604994aSStefano Zampini if (!pcbddc->current_level) { 4627e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4628e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4629e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4630e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4631e604994aSStefano Zampini } else { 4632e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4633312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4634e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4635e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 4636312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4637312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 463834d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 463934d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4640e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4641e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4642e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 4643e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 4644e604994aSStefano Zampini } 4645e604994aSStefano Zampini 4646304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 4647684f6988SStefano Zampini if (dirichlet) { 4648d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4649450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 46509a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 4651450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 4652a3df083aSStefano Zampini Mat A_IIn; 4653a3df083aSStefano Zampini 4654a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 4655a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 4656a3df083aSStefano Zampini pcis->A_II = A_IIn; 4657a3df083aSStefano Zampini } 4658450f8f5eSStefano Zampini } 46593301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 46603301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 4661964fefecSStefano Zampini } 4662ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 4663964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 4664304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 4665304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 4666304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 4667304d26faSStefano Zampini /* default */ 4668304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 4669e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 46709577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 4671304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 46729577ea80SStefano Zampini if (issbaij) { 46739577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 46749577ea80SStefano Zampini } else { 4675304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 46769577ea80SStefano Zampini } 4677304d26faSStefano Zampini /* Allow user's customization */ 4678304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 4679304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4680304d26faSStefano Zampini } 4681d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 4682b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4683df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4684d62866d3SStefano Zampini 4685df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 4686d5574798SStefano Zampini } 4687304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4688304d26faSStefano Zampini if (!n_D) { 4689304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 4690304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4691304d26faSStefano Zampini } 4692304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 4693304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 4694304d26faSStefano Zampini /* set ksp_D into pcis data */ 4695304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 4696304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 4697304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 4698684f6988SStefano Zampini } 4699304d26faSStefano Zampini 4700304d26faSStefano Zampini /* NEUMANN PROBLEM */ 4701684f6988SStefano Zampini A_RR = 0; 4702684f6988SStefano Zampini if (neumann) { 4703d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 470404708bb6SStefano Zampini PetscInt ibs,mbs; 470504708bb6SStefano Zampini PetscBool issbaij; 470604708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4707f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 47088ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 4709f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 4710f4ddd8eeSStefano Zampini PetscInt nn_R; 471181d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 4712f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4713f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 4714f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 4715f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 4716f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4717f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4718f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 4719727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 4720f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4721f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4722f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 4723f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 4724f4ddd8eeSStefano Zampini } 4725f4ddd8eeSStefano Zampini } 4726f4ddd8eeSStefano Zampini /* last check */ 4727d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 4728f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4729f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4730f4ddd8eeSStefano Zampini } 4731f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 4732f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4733f4ddd8eeSStefano Zampini } 4734a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 4735af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 4736af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 473704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 473804708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 473904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 474004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 474104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 4742af732b37SStefano Zampini } else { 4743511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 47446816873aSStefano Zampini } 474504708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 474604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 474704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 474804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 474904708bb6SStefano Zampini } else { 4750511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 475104708bb6SStefano Zampini } 475204708bb6SStefano Zampini } 4753a00504b5SStefano Zampini /* extract A_RR */ 4754b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4755a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4756a00504b5SStefano Zampini 4757a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 475816e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4759a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 476016e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 476116e386b8SStefano Zampini } else { 4762a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 4763a00504b5SStefano Zampini } 4764a00504b5SStefano Zampini } else { 4765a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4766a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 4767a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4768a00504b5SStefano Zampini } 4769a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 4770f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 477116e386b8SStefano Zampini } 47723301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 47733301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 47746816873aSStefano Zampini } 4775f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 4776304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 4777304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 4778304d26faSStefano Zampini /* default */ 4779304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 4780e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 4781304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 47829577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 47839577ea80SStefano Zampini if (issbaij) { 47849577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 47859577ea80SStefano Zampini } else { 4786304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 47879577ea80SStefano Zampini } 4788304d26faSStefano Zampini /* Allow user's customization */ 4789304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 4790304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4791304d26faSStefano Zampini } 4792304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4793304d26faSStefano Zampini if (!n_R) { 4794304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 4795304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4796304d26faSStefano Zampini } 47975cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 4798df4d28bfSStefano Zampini /* Reuse solver if it is present */ 4799b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4800df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4801d62866d3SStefano Zampini 4802df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 4803d62866d3SStefano Zampini } 4804304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 4805304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 4806684f6988SStefano Zampini } 4807304d26faSStefano Zampini 4808684f6988SStefano Zampini if (pcbddc->dbg_flag) { 4809684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 48101575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4811684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4812684f6988SStefano Zampini } 4813c7017625SStefano Zampini 4814c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 4815c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 4816c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 4817c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 4818c7017625SStefano Zampini } 4819c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 4820c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 4821c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 4822c7017625SStefano Zampini } 4823c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 4824c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 4825c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 4826c7017625SStefano Zampini } 4827c7017625SStefano Zampini 4828c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 4829c7017625SStefano Zampini if (pcbddc->dbg_flag) { 4830684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 48310fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 48320fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 48330fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 48340fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 48350fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 4836e604994aSStefano 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); 4837c7017625SStefano Zampini if (check_corr[0]) { 4838c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 4839c7017625SStefano Zampini } 4840304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4841304d26faSStefano Zampini } 4842684f6988SStefano Zampini if (neumann) { /* Neumann */ 48430fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 48440fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 48450fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 48460fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 48470fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 4848e604994aSStefano 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); 4849c7017625SStefano Zampini if (check_corr[1]) { 4850c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 4851c7017625SStefano Zampini } 4852304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4853304d26faSStefano Zampini } 4854684f6988SStefano Zampini } 48555cbda25cSStefano Zampini /* free Neumann problem's matrix */ 48565cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4857304d26faSStefano Zampini PetscFunctionReturn(0); 4858304d26faSStefano Zampini } 4859304d26faSStefano Zampini 4860304d26faSStefano Zampini #undef __FUNCT__ 4861ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 486280677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 4863674ae819SStefano Zampini { 4864674ae819SStefano Zampini PetscErrorCode ierr; 4865674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4866be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4867b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 4868674ae819SStefano Zampini 4869674ae819SStefano Zampini PetscFunctionBegin; 4870b334f244SStefano Zampini if (!reuse_solver) { 487180677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 487220c7b377SStefano Zampini } 487380677318SStefano Zampini if (!pcbddc->switch_static) { 487480677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 487580677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 487680677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 487720c7b377SStefano Zampini } 4878b334f244SStefano Zampini if (!reuse_solver) { 487980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 488080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 488120c7b377SStefano Zampini } else { 4882df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4883be83ff47SStefano Zampini 4884df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4885df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 488620c7b377SStefano Zampini } 4887be83ff47SStefano Zampini } else { 488880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 488980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 489080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 489180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 489280677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 489380677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 489480677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 489580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 489680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4897674ae819SStefano Zampini } 4898674ae819SStefano Zampini } 4899b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 490080677318SStefano Zampini if (applytranspose) { 490180677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 490280677318SStefano Zampini } else { 490380677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 490480677318SStefano Zampini } 4905be83ff47SStefano Zampini } else { 4906df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4907be83ff47SStefano Zampini 4908be83ff47SStefano Zampini if (applytranspose) { 4909df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4910be83ff47SStefano Zampini } else { 4911df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4912be83ff47SStefano Zampini } 4913be83ff47SStefano Zampini } 491480677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 491580677318SStefano Zampini if (!pcbddc->switch_static) { 4916b334f244SStefano Zampini if (!reuse_solver) { 491780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 491880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4919be83ff47SStefano Zampini } else { 4920df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4921be83ff47SStefano Zampini 4922df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4923df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4924be83ff47SStefano Zampini } 492580677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 492680677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 492780677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 492880677318SStefano Zampini } 492980677318SStefano Zampini } else { 493080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 493180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 493280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 493380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 493480677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 493580677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 493680677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 493780677318SStefano Zampini } 493880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 493980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 494080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 494180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4942674ae819SStefano Zampini } 4943674ae819SStefano Zampini PetscFunctionReturn(0); 4944674ae819SStefano Zampini } 4945674ae819SStefano Zampini 4946dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 4947674ae819SStefano Zampini #undef __FUNCT__ 4948674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 4949dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 4950674ae819SStefano Zampini { 4951674ae819SStefano Zampini PetscErrorCode ierr; 4952674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4953674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 4954674ae819SStefano Zampini const PetscScalar zero = 0.0; 4955674ae819SStefano Zampini 4956674ae819SStefano Zampini PetscFunctionBegin; 4957dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 49584fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4959dc359a40SStefano Zampini if (applytranspose) { 4960674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 49618eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 4962dc359a40SStefano Zampini } else { 4963674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 4964674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 496515aaf578SStefano Zampini } 49664fee134fSStefano Zampini } else { 49674fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 49684fee134fSStefano Zampini } 4969efc2fbd9SStefano Zampini 4970efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 49714f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4972efc2fbd9SStefano Zampini PetscScalar *array; 49734f1b2e48SStefano Zampini PetscInt j; 4974efc2fbd9SStefano Zampini 4975efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 49764f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 4977efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4978efc2fbd9SStefano Zampini } 4979efc2fbd9SStefano Zampini 498012edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 498112edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 498212edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 498312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 498412edc857SStefano Zampini 49859f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 498612edc857SStefano Zampini if (pcbddc->coarse_ksp) { 498751694757SStefano Zampini Mat coarse_mat; 4988964fefecSStefano Zampini Vec rhs,sol; 498951694757SStefano Zampini MatNullSpace nullsp; 499027b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 4991964fefecSStefano Zampini 499227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 499327b6a85dSStefano Zampini PC coarse_pc; 499427b6a85dSStefano Zampini 499527b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 499627b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 499727b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 499827b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 499927b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 500027b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 50013bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 500227b6a85dSStefano Zampini } 500327b6a85dSStefano Zampini } 5004964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 5005964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 500651694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 500751694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 500851694757SStefano Zampini if (nullsp) { 500951694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 501051694757SStefano Zampini } 501112edc857SStefano Zampini if (applytranspose) { 50129a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 5013964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 50142701bc32SStefano Zampini } else { 50151f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 50162701bc32SStefano Zampini PC coarse_pc; 50172701bc32SStefano Zampini 50182701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 50192701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 50203e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 50212701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 502212edc857SStefano Zampini } else { 5023964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 502412edc857SStefano Zampini } 50252701bc32SStefano Zampini } 50261d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 502727b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 502827b6a85dSStefano Zampini PC coarse_pc; 502927b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 503027b6a85dSStefano Zampini 503127b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 503227b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 503327b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 50343bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 503527b6a85dSStefano Zampini } 503651694757SStefano Zampini if (nullsp) { 503751694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 503851694757SStefano Zampini } 503912edc857SStefano Zampini } 5040674ae819SStefano Zampini 5041674ae819SStefano Zampini /* Local solution on R nodes */ 50424fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 504380677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 50449f00e9b4SStefano Zampini } 50459f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 50469f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 504712edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5048674ae819SStefano Zampini 50494fee134fSStefano Zampini /* Sum contributions from the two levels */ 50504fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5051dc359a40SStefano Zampini if (applytranspose) { 5052dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5053dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5054dc359a40SStefano Zampini } else { 5055674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 50568eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5057dc359a40SStefano Zampini } 5058efc2fbd9SStefano Zampini /* store p0 */ 50594f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5060efc2fbd9SStefano Zampini PetscScalar *array; 50614f1b2e48SStefano Zampini PetscInt j; 5062efc2fbd9SStefano Zampini 5063efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 50644f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 5065efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5066efc2fbd9SStefano Zampini } 50674fee134fSStefano Zampini } else { /* expand the coarse solution */ 50684fee134fSStefano Zampini if (applytranspose) { 50694fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 50704fee134fSStefano Zampini } else { 50714fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 50724fee134fSStefano Zampini } 50734fee134fSStefano Zampini } 5074674ae819SStefano Zampini PetscFunctionReturn(0); 5075674ae819SStefano Zampini } 5076674ae819SStefano Zampini 5077674ae819SStefano Zampini #undef __FUNCT__ 5078674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 507912edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 5080674ae819SStefano Zampini { 5081674ae819SStefano Zampini PetscErrorCode ierr; 5082674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 508358da7f69SStefano Zampini PetscScalar *array; 508412edc857SStefano Zampini Vec from,to; 5085674ae819SStefano Zampini 5086674ae819SStefano Zampini PetscFunctionBegin; 508712edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 508812edc857SStefano Zampini from = pcbddc->coarse_vec; 508912edc857SStefano Zampini to = pcbddc->vec1_P; 509012edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 509112edc857SStefano Zampini Vec tvec; 509258da7f69SStefano Zampini 509358da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 509458da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 509512edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 509658da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 509758da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 509858da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 509912edc857SStefano Zampini } 510012edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 510112edc857SStefano Zampini from = pcbddc->vec1_P; 510212edc857SStefano Zampini to = pcbddc->coarse_vec; 510312edc857SStefano Zampini } 510412edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 5105674ae819SStefano Zampini PetscFunctionReturn(0); 5106674ae819SStefano Zampini } 5107674ae819SStefano Zampini 5108674ae819SStefano Zampini #undef __FUNCT__ 5109674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 511012edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 5111674ae819SStefano Zampini { 5112674ae819SStefano Zampini PetscErrorCode ierr; 5113674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 511458da7f69SStefano Zampini PetscScalar *array; 511512edc857SStefano Zampini Vec from,to; 5116674ae819SStefano Zampini 5117674ae819SStefano Zampini PetscFunctionBegin; 511812edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 511912edc857SStefano Zampini from = pcbddc->coarse_vec; 512012edc857SStefano Zampini to = pcbddc->vec1_P; 512112edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 512212edc857SStefano Zampini from = pcbddc->vec1_P; 512312edc857SStefano Zampini to = pcbddc->coarse_vec; 512412edc857SStefano Zampini } 512512edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 512612edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 512712edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 512812edc857SStefano Zampini Vec tvec; 512958da7f69SStefano Zampini 513012edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 513158da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 513258da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 513358da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 513458da7f69SStefano Zampini } 513558da7f69SStefano Zampini } else { 513658da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 513758da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 513812edc857SStefano Zampini } 513912edc857SStefano Zampini } 5140674ae819SStefano Zampini PetscFunctionReturn(0); 5141674ae819SStefano Zampini } 5142674ae819SStefano Zampini 5143984c4197SStefano Zampini /* uncomment for testing purposes */ 5144984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 5145674ae819SStefano Zampini #undef __FUNCT__ 5146674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 5147674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 5148674ae819SStefano Zampini { 5149674ae819SStefano Zampini PetscErrorCode ierr; 5150674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5151674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5152674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5153984c4197SStefano Zampini /* one and zero */ 5154984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 5155984c4197SStefano Zampini /* space to store constraints and their local indices */ 51569162d606SStefano Zampini PetscScalar *constraints_data; 51579162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 51589162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 51599162d606SStefano Zampini PetscInt *constraints_n; 5160984c4197SStefano Zampini /* iterators */ 5161b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 5162984c4197SStefano Zampini /* BLAS integers */ 5163e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 5164e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 5165c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 5166727cdba6SStefano Zampini /* reuse */ 51670e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 51680e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 5169984c4197SStefano Zampini /* change of basis */ 5170b3d85658SStefano Zampini PetscBool qr_needed; 51719162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 5172984c4197SStefano Zampini /* auxiliary stuff */ 517364efe560SStefano Zampini PetscInt *nnz,*is_indices; 51748a0068c3SStefano Zampini PetscInt ncc; 5175984c4197SStefano Zampini /* some quantities */ 517645a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 5177a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 5178984c4197SStefano Zampini 5179674ae819SStefano Zampini PetscFunctionBegin; 51808e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 51818e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 51828e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 518316909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 5184088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 5185088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 51860e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 51870e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 51880e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 51890e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 51900e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 5191088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5192cf5a6209SStefano Zampini 5193cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 51949162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 5195cf5a6209SStefano Zampini MatNullSpace nearnullsp; 5196cf5a6209SStefano Zampini const Vec *nearnullvecs; 5197cf5a6209SStefano Zampini Vec *localnearnullsp; 5198cf5a6209SStefano Zampini PetscScalar *array; 5199cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 5200cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 5201674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 5202b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 5203674ae819SStefano Zampini PetscScalar *work; 5204674ae819SStefano Zampini PetscReal *singular_vals; 5205674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5206674ae819SStefano Zampini PetscReal *rwork; 5207674ae819SStefano Zampini #endif 5208674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5209674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 5210674ae819SStefano Zampini #else 5211964fefecSStefano Zampini PetscBLASInt dummy_int=1; 5212964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 5213674ae819SStefano Zampini #endif 5214674ae819SStefano Zampini 5215674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 5216d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 5217e4d548c7SStefano Zampini /* print some info */ 52185c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 5219e4d548c7SStefano Zampini PetscInt nv; 5220e4d548c7SStefano Zampini 5221c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5222e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 5223e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5224e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5225e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 5226e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 5227e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 5228e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5229e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5230e4d548c7SStefano Zampini } 5231e4d548c7SStefano Zampini 5232d06fc5fdSStefano Zampini /* free unneeded index sets */ 5233d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 5234d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 5235674ae819SStefano Zampini } 5236d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 5237d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5238d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5239d06fc5fdSStefano Zampini } 5240d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5241d06fc5fdSStefano Zampini n_ISForEdges = 0; 5242d06fc5fdSStefano Zampini } 5243d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 5244d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5245d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5246d06fc5fdSStefano Zampini } 5247d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5248d06fc5fdSStefano Zampini n_ISForFaces = 0; 5249d06fc5fdSStefano Zampini } 525070022509SStefano Zampini 5251674ae819SStefano Zampini /* check if near null space is attached to global mat */ 5252674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 5253674ae819SStefano Zampini if (nearnullsp) { 5254674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 5255f4ddd8eeSStefano Zampini /* remove any stored info */ 5256f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 5257f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5258f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 5259f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 5260f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 5261473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5262f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 5263f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 5264f4ddd8eeSStefano Zampini } 5265984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 5266984c4197SStefano Zampini nnsp_size = 0; 5267674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 5268674ae819SStefano Zampini } 5269984c4197SStefano Zampini /* get max number of constraints on a single cc */ 5270984c4197SStefano Zampini max_constraints = nnsp_size; 5271984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 5272984c4197SStefano Zampini 5273674ae819SStefano Zampini /* 5274674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 52759162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 52769162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 52779162d606SStefano Zampini There can be multiple constraints per connected component 5278674ae819SStefano Zampini */ 5279674ae819SStefano Zampini n_vertices = 0; 5280674ae819SStefano Zampini if (ISForVertices) { 5281674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 5282674ae819SStefano Zampini } 52839162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 52849162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 52859162d606SStefano Zampini 52869162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 52879162d606SStefano Zampini total_counts *= max_constraints; 5288674ae819SStefano Zampini total_counts += n_vertices; 52894641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 52909162d606SStefano Zampini 5291674ae819SStefano Zampini total_counts = 0; 5292674ae819SStefano Zampini max_size_of_constraint = 0; 5293674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 52949162d606SStefano Zampini IS used_is; 5295674ae819SStefano Zampini if (i<n_ISForEdges) { 52969162d606SStefano Zampini used_is = ISForEdges[i]; 5297674ae819SStefano Zampini } else { 52989162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 5299674ae819SStefano Zampini } 53009162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 5301674ae819SStefano Zampini total_counts += j; 5302674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 5303674ae819SStefano Zampini } 53049162d606SStefano 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); 53059162d606SStefano Zampini 5306984c4197SStefano Zampini /* get local part of global near null space vectors */ 5307785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 5308984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5309984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 5310e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5311e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5312984c4197SStefano Zampini } 5313674ae819SStefano Zampini 5314242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 5315242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 5316a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 5317242a89d7SStefano Zampini 5318984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 5319a773dcb8SStefano Zampini if (!skip_lapack) { 5320674ae819SStefano Zampini PetscScalar temp_work; 5321911cabfeSStefano Zampini 5322674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5323984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 5324785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 5325785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 5326785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 5327674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5328785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 5329674ae819SStefano Zampini #endif 5330674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5331c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 5332c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 5333674ae819SStefano Zampini lwork = -1; 5334674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5335674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5336c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 5337674ae819SStefano Zampini #else 5338c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 5339674ae819SStefano Zampini #endif 5340674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5341984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 5342674ae819SStefano Zampini #else /* on missing GESVD */ 5343674ae819SStefano Zampini /* SVD */ 5344674ae819SStefano Zampini PetscInt max_n,min_n; 5345674ae819SStefano Zampini max_n = max_size_of_constraint; 5346984c4197SStefano Zampini min_n = max_constraints; 5347984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 5348674ae819SStefano Zampini min_n = max_size_of_constraint; 5349984c4197SStefano Zampini max_n = max_constraints; 5350674ae819SStefano Zampini } 5351785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 5352674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5353785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 5354674ae819SStefano Zampini #endif 5355674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5356674ae819SStefano Zampini lwork = -1; 5357e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 5358e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 5359b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 5360674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5361674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 53629162d606SStefano 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)); 5363674ae819SStefano Zampini #else 53649162d606SStefano 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)); 5365674ae819SStefano Zampini #endif 5366674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5367984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 5368984c4197SStefano Zampini #endif /* on missing GESVD */ 5369674ae819SStefano Zampini /* Allocate optimal workspace */ 5370674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 5371854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 5372674ae819SStefano Zampini } 5373674ae819SStefano Zampini /* Now we can loop on constraining sets */ 5374674ae819SStefano Zampini total_counts = 0; 53759162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 53769162d606SStefano Zampini constraints_data_ptr[0] = 0; 5377674ae819SStefano Zampini /* vertices */ 53789162d606SStefano Zampini if (n_vertices) { 5379674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 53809162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 5381674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 53829162d606SStefano Zampini constraints_n[total_counts] = 1; 53839162d606SStefano Zampini constraints_data[total_counts] = 1.0; 53849162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 53859162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 5386674ae819SStefano Zampini total_counts++; 5387674ae819SStefano Zampini } 5388674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5389674ae819SStefano Zampini n_vertices = total_counts; 5390674ae819SStefano Zampini } 5391984c4197SStefano Zampini 5392674ae819SStefano Zampini /* edges and faces */ 53939162d606SStefano Zampini total_counts_cc = total_counts; 5394911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 53959162d606SStefano Zampini IS used_is; 53969162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 53979162d606SStefano Zampini 5398911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 53999162d606SStefano Zampini used_is = ISForEdges[ncc]; 5400984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 5401674ae819SStefano Zampini } else { 54029162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 5403984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 5404674ae819SStefano Zampini } 5405674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 54069162d606SStefano Zampini 54079162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 54089162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5409984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 5410984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 5411674ae819SStefano Zampini if (nnsp_has_cnst) { 54125b08dc53SStefano Zampini PetscScalar quad_value; 54139162d606SStefano Zampini 54149162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 54159162d606SStefano Zampini idxs_copied = PETSC_TRUE; 54169162d606SStefano Zampini 5417a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 5418674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 5419a773dcb8SStefano Zampini } else { 5420a773dcb8SStefano Zampini quad_value = 1.0; 5421a773dcb8SStefano Zampini } 5422674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 54239162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 5424674ae819SStefano Zampini } 54259162d606SStefano Zampini temp_constraints++; 5426674ae819SStefano Zampini total_counts++; 5427674ae819SStefano Zampini } 5428674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 5429984c4197SStefano Zampini PetscReal real_value; 54309162d606SStefano Zampini PetscScalar *ptr_to_data; 54319162d606SStefano Zampini 5432984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 54339162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 5434674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 54359162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 5436674ae819SStefano Zampini } 5437984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 5438984c4197SStefano Zampini /* check if array is null on the connected component */ 5439e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 54409162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 54415b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 5442674ae819SStefano Zampini temp_constraints++; 5443674ae819SStefano Zampini total_counts++; 54449162d606SStefano Zampini if (!idxs_copied) { 54459162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 54469162d606SStefano Zampini idxs_copied = PETSC_TRUE; 5447674ae819SStefano Zampini } 5448674ae819SStefano Zampini } 54499162d606SStefano Zampini } 54509162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 545145a1bb75SStefano Zampini valid_constraints = temp_constraints; 5452eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 5453a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 54549162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 54559162d606SStefano Zampini 54569162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5457a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 54589162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 5459a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 54609162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 5461a773dcb8SStefano Zampini } else { /* perform SVD */ 5462984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 54639162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5464674ae819SStefano Zampini 5465674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5466984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 5467984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 5468984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 5469984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 5470984c4197SStefano Zampini from that computed using LAPACKgesvd 5471984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 5472984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 5473984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 5474674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 5475e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5476984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5477674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 5478674ae819SStefano Zampini for (k=0;k<j+1;k++) { 54799162d606SStefano 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)); 5480674ae819SStefano Zampini } 5481674ae819SStefano Zampini } 5482e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 5483e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5484e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 5485674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5486c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 5487674ae819SStefano Zampini #else 5488c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 5489674ae819SStefano Zampini #endif 5490674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5491984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 5492984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 5493674ae819SStefano Zampini j = 0; 5494984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 5495674ae819SStefano Zampini total_counts = total_counts-j; 549645a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 5497e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 5498c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5499c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5500c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 5501c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5502c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 5503c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5504674ae819SStefano Zampini if (j<temp_constraints) { 5505984c4197SStefano Zampini PetscInt ii; 5506984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 5507674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 55089162d606SStefano 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)); 5509674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5510984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 5511674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 55129162d606SStefano 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]; 5513674ae819SStefano Zampini } 5514674ae819SStefano Zampini } 5515674ae819SStefano Zampini } 5516674ae819SStefano Zampini #else /* on missing GESVD */ 5517e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5518e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5519b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5520674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5521674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 55229162d606SStefano 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)); 5523674ae819SStefano Zampini #else 55249162d606SStefano 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)); 5525674ae819SStefano Zampini #endif 5526984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 5527674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5528984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 5529e310c8b4SStefano Zampini k = temp_constraints; 5530e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 5531674ae819SStefano Zampini j = 0; 5532e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 553345a1bb75SStefano Zampini valid_constraints = k-j; 5534911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 5535984c4197SStefano Zampini #endif /* on missing GESVD */ 5536674ae819SStefano Zampini } 5537a773dcb8SStefano Zampini } 55389162d606SStefano Zampini /* update pointers information */ 55399162d606SStefano Zampini if (valid_constraints) { 55409162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 55419162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 55429162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 55439162d606SStefano Zampini /* set change_of_basis flag */ 554445a1bb75SStefano Zampini if (boolforchange) { 5545b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 55469162d606SStefano Zampini } 5547b3d85658SStefano Zampini total_counts_cc++; 554845a1bb75SStefano Zampini } 554945a1bb75SStefano Zampini } 5550984c4197SStefano Zampini /* free workspace */ 55518f1c130eSStefano Zampini if (!skip_lapack) { 5552984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 5553984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5554984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 5555984c4197SStefano Zampini #endif 5556984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 5557984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5558984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 5559984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 5560984c4197SStefano Zampini #endif 5561984c4197SStefano Zampini } 5562984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5563984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 5564984c4197SStefano Zampini } 5565984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 5566cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 5567cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5568cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5569cf5a6209SStefano Zampini } 5570cf5a6209SStefano Zampini if (n_ISForFaces) { 5571cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5572cf5a6209SStefano Zampini } 5573cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5574cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5575cf5a6209SStefano Zampini } 5576cf5a6209SStefano Zampini if (n_ISForEdges) { 5577cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5578cf5a6209SStefano Zampini } 5579cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 558008122e43SStefano Zampini } else { 558108122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5582984c4197SStefano Zampini 558308122e43SStefano Zampini total_counts = 0; 558408122e43SStefano Zampini n_vertices = 0; 5585d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 5586d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 558708122e43SStefano Zampini } 558808122e43SStefano Zampini max_constraints = 0; 55899162d606SStefano Zampini total_counts_cc = 0; 559008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 559108122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 55929162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 559308122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 559408122e43SStefano Zampini } 55959162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 55969162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 55979162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 55989162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 559974d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 56009162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 56019162d606SStefano Zampini total_counts_cc = 0; 56029162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 56039162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 56049162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 560508122e43SStefano Zampini } 560608122e43SStefano Zampini } 56079162d606SStefano Zampini #if 0 56089162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 56099162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 56109162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 56119162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 56129162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 56139162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 56149162d606SStefano Zampini } 56159162d606SStefano Zampini printf("\n"); 56169162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 56179162d606SStefano Zampini } 56181b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 56198bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 56201b968477SStefano Zampini } 56211b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 56228bec7fa6SStefano 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]); 56231b968477SStefano Zampini } 562408122e43SStefano Zampini #endif 562508122e43SStefano Zampini 56268bec7fa6SStefano Zampini max_size_of_constraint = 0; 56279162d606SStefano 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]); 56289162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 562908122e43SStefano Zampini /* Change of basis */ 5630b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 563108122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 563208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 563308122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 5634b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 563508122e43SStefano Zampini } 563608122e43SStefano Zampini } 563708122e43SStefano Zampini } 563808122e43SStefano Zampini } 5639984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 56404f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 564108122e43SStefano Zampini 56429162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 56439162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 5644eee23b56SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for constraints indices %D != %D\n",constraints_idxs_ptr[total_counts_cc],i); 5645674ae819SStefano Zampini 5646674ae819SStefano Zampini /* Create constraint matrix */ 5647674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 564816f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 5649984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 5650984c4197SStefano Zampini 5651984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 5652a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 5653a717540cSStefano Zampini qr_needed = PETSC_FALSE; 565474d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 5655984c4197SStefano Zampini total_primal_vertices=0; 5656b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 56579162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 56589162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 565972b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 56609162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 5661b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 566264efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 56639162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 56649162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 5665a717540cSStefano Zampini } 5666b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 566791af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 5668a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 5669a717540cSStefano Zampini qr_needed = PETSC_TRUE; 5670a717540cSStefano Zampini } 5671fa434743SStefano Zampini } else { 5672b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 5673fa434743SStefano Zampini } 5674a717540cSStefano Zampini } 5675b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 5676b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 5677674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 567870022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 56794f1b2e48SStefano 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); 56800e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 56810e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 5682984c4197SStefano Zampini 5683984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 568474d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 5685785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 5686984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 568774d5cdf7SStefano Zampini 5688984c4197SStefano Zampini j = total_primal_vertices; 568974d5cdf7SStefano Zampini total_counts = total_primal_vertices; 5690b3d85658SStefano Zampini cum = total_primal_vertices; 56919162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 56924641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 5693b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 5694b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 5695b3d85658SStefano Zampini cum++; 56969162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 569774d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 569874d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 569974d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 570074d5cdf7SStefano Zampini } 57019162d606SStefano Zampini j += constraints_n[i]; 5702674ae819SStefano Zampini } 5703674ae819SStefano Zampini } 5704674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 5705674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 5706088faed8SStefano Zampini 5707674ae819SStefano Zampini /* set values in constraint matrix */ 5708984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 57090e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5710674ae819SStefano Zampini } 5711984c4197SStefano Zampini total_counts = total_primal_vertices; 57129162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 57134641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 57149162d606SStefano Zampini PetscInt *cols; 57159162d606SStefano Zampini 57169162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 57179162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 57189162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 57199162d606SStefano Zampini PetscInt row = total_counts+k; 57209162d606SStefano Zampini PetscScalar *vals; 57219162d606SStefano Zampini 57229162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 57239162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 57249162d606SStefano Zampini } 57259162d606SStefano Zampini total_counts += constraints_n[i]; 5726674ae819SStefano Zampini } 5727674ae819SStefano Zampini } 5728674ae819SStefano Zampini /* assembling */ 5729674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5730674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5731088faed8SStefano Zampini 5732984c4197SStefano Zampini /* 57336a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5734984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 5735f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 5736984c4197SStefano Zampini */ 5737674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 5738674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 5739026de310SStefano Zampini /* dual and primal dofs on a single cc */ 5740984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 5741984c4197SStefano Zampini /* working stuff for GEQRF */ 574281d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 5743984c4197SStefano Zampini PetscBLASInt lqr_work; 5744984c4197SStefano Zampini /* working stuff for UNGQR */ 5745984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 5746984c4197SStefano Zampini PetscBLASInt lgqr_work; 5747984c4197SStefano Zampini /* working stuff for TRTRS */ 5748984c4197SStefano Zampini PetscScalar *trs_rhs; 57493f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 5750984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 5751984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 5752984c4197SStefano Zampini PetscScalar *start_vals; 5753984c4197SStefano Zampini /* working stuff for values insertion */ 57544641a718SStefano Zampini PetscBT is_primal; 575564efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 5756906d46d4SStefano Zampini /* matrix sizes */ 5757906d46d4SStefano Zampini PetscInt global_size,local_size; 5758906d46d4SStefano Zampini /* temporary change of basis */ 5759906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 5760cf5a6209SStefano Zampini /* extra space for debugging */ 5761cf5a6209SStefano Zampini PetscScalar *dbg_work; 5762984c4197SStefano Zampini 5763906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 5764906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 576516f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 5766bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 5767906d46d4SStefano Zampini /* nonzeros for local mat */ 5768bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 57691dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5770bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 57711dd7afcfSStefano Zampini } else { 57721dd7afcfSStefano Zampini const PetscInt *ii; 57731dd7afcfSStefano Zampini PetscInt n; 57741dd7afcfSStefano Zampini PetscBool flg_row; 57751dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 57761dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 57771dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 57781dd7afcfSStefano Zampini } 57799162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 5780a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 57819162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 5782a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 57839162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 5784a717540cSStefano Zampini } else { 57859162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 57869162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 5787a717540cSStefano Zampini } 5788a717540cSStefano Zampini } 5789a717540cSStefano Zampini } 5790906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 5791bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 57921dd7afcfSStefano Zampini /* Set interior change in the matrix */ 57931dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5794bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 5795906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 5796a717540cSStefano Zampini } 57971dd7afcfSStefano Zampini } else { 57981dd7afcfSStefano Zampini const PetscInt *ii,*jj; 57991dd7afcfSStefano Zampini PetscScalar *aa; 58001dd7afcfSStefano Zampini PetscInt n; 58011dd7afcfSStefano Zampini PetscBool flg_row; 58021dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 58031dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 58041dd7afcfSStefano Zampini for (i=0;i<n;i++) { 58051dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 58061dd7afcfSStefano Zampini } 58071dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 58081dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 58091dd7afcfSStefano Zampini } 5810a717540cSStefano Zampini 5811a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5812a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5813a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5814a717540cSStefano Zampini } 5815a717540cSStefano Zampini 5816a717540cSStefano Zampini 5817a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 5818a717540cSStefano Zampini /* 5819a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 5820a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 5821a717540cSStefano Zampini 5822a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 5823a717540cSStefano Zampini 5824a6b551f4SStefano 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) 5825a6b551f4SStefano Zampini 5826a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 5827a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 5828a717540cSStefano Zampini | ... | 5829a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 5830a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 5831a717540cSStefano Zampini 5832a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 5833a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 5834a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 5835a6b551f4SStefano Zampini 5836a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 5837a717540cSStefano Zampini */ 5838a717540cSStefano Zampini if (qr_needed) { 5839984c4197SStefano Zampini /* space to store Q */ 5840854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 58414e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 58424e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 5843984c4197SStefano Zampini /* first we issue queries for optimal work */ 58443f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 58453f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 58463f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5847984c4197SStefano Zampini lqr_work = -1; 58483f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 5849984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 5850984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 5851785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 5852984c4197SStefano Zampini lgqr_work = -1; 58533f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 58543f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 58553f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 58563f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 58573f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 58583f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 5859984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 5860984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 5861785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 5862984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 5863785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 5864a717540cSStefano Zampini /* allocating workspace for check */ 5865a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5866cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 5867a717540cSStefano Zampini } 5868a717540cSStefano Zampini } 5869984c4197SStefano Zampini /* array to store whether a node is primal or not */ 58704641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 5871473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 58720e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 5873eee23b56SStefano Zampini if (i != total_primal_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D\n",total_primal_vertices,i); 587439e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 587539e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 587639e2fb2aSStefano Zampini } 587739e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 5878984c4197SStefano Zampini 5879a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 58809162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 58819162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 58824641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 5883984c4197SStefano Zampini /* get constraint info */ 58849162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 5885984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 5886984c4197SStefano Zampini 5887984c4197SStefano Zampini if (pcbddc->dbg_flag) { 58889162d606SStefano 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); 5889674ae819SStefano Zampini } 5890984c4197SStefano Zampini 5891fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 5892a717540cSStefano Zampini 5893a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 5894a717540cSStefano Zampini if (pcbddc->dbg_flag) { 58959162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5896a717540cSStefano Zampini } 5897984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 58989162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5899984c4197SStefano Zampini 5900984c4197SStefano Zampini /* compute QR decomposition of constraints */ 59013f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 59023f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 59033f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5904674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 59053f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 5906984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 5907674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5908984c4197SStefano Zampini 5909984c4197SStefano Zampini /* explictly compute R^-T */ 5910984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 5911984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 59123f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 59133f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 59143f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 59153f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 5916984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 59173f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 5918984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 5919984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5920984c4197SStefano Zampini 5921a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 59223f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 59233f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 59243f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 59253f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5926984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 59273f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 5928984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 5929984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5930984c4197SStefano Zampini 5931984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 5932984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 5933984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 59343f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 59353f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 59363f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 59373f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 59383f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 59393f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5940984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 59419162d606SStefano 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)); 5942984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 59439162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5944984c4197SStefano Zampini 5945984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 59469162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 5947984c4197SStefano Zampini /* insert cols for primal dofs */ 5948984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 5949984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 59509162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5951906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5952984c4197SStefano Zampini } 5953984c4197SStefano Zampini /* insert cols for dual dofs */ 5954984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 59559162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 5956984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 59579162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5958906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5959984c4197SStefano Zampini j++; 5960674ae819SStefano Zampini } 5961674ae819SStefano Zampini } 5962984c4197SStefano Zampini 5963984c4197SStefano Zampini /* check change of basis */ 5964984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5965984c4197SStefano Zampini PetscInt ii,jj; 5966984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 5967c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 5968c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5969c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 5970c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5971c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 5972c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 5973984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5974cf5a6209SStefano 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)); 5975984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5976984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5977984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5978cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 5979cf5a6209SStefano 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; 5980674ae819SStefano Zampini } 5981674ae819SStefano Zampini } 5982984c4197SStefano Zampini if (!valid_qr) { 598322d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 5984984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5985984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5986cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 5987cf5a6209SStefano 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])); 5988674ae819SStefano Zampini } 5989cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 5990cf5a6209SStefano 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])); 5991984c4197SStefano Zampini } 5992984c4197SStefano Zampini } 5993984c4197SStefano Zampini } 5994674ae819SStefano Zampini } else { 599522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 5996674ae819SStefano Zampini } 5997674ae819SStefano Zampini } 5998a717540cSStefano Zampini } else { /* simple transformation block */ 5999a717540cSStefano Zampini PetscInt row,col; 6000a6b551f4SStefano Zampini PetscScalar val,norm; 6001a6b551f4SStefano Zampini 6002a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 60039162d606SStefano 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)); 6004a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 60059162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 60069162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6007bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 60089162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 6009906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 60109162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 6011a717540cSStefano Zampini } else { 6012a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 60139162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6014a717540cSStefano Zampini if (row != col) { 60159162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 6016a717540cSStefano Zampini } else { 60179162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 6018a717540cSStefano Zampini } 6019906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 6020a717540cSStefano Zampini } 6021a717540cSStefano Zampini } 6022a717540cSStefano Zampini } 602398a51de6SStefano Zampini if (pcbddc->dbg_flag) { 602422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 6025a717540cSStefano Zampini } 6026674ae819SStefano Zampini } 6027984c4197SStefano Zampini } else { 6028984c4197SStefano Zampini if (pcbddc->dbg_flag) { 60299162d606SStefano 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); 6030674ae819SStefano Zampini } 6031674ae819SStefano Zampini } 6032674ae819SStefano Zampini } 6033a717540cSStefano Zampini 6034a717540cSStefano Zampini /* free workspace */ 6035a717540cSStefano Zampini if (qr_needed) { 6036984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6037cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 6038984c4197SStefano Zampini } 6039984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 6040984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 6041984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 6042984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 6043984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 6044674ae819SStefano Zampini } 6045a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 6046906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6047906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6048906d46d4SStefano Zampini 6049906d46d4SStefano Zampini /* assembling of global change of variable */ 605088c03ad3SStefano Zampini if (!pcbddc->fake_change) { 6051bbb9e6c6SStefano Zampini Mat tmat; 605216f15bc4SStefano Zampini PetscInt bs; 605316f15bc4SStefano Zampini 6054906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 6055906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 6056bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6057bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 6058bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6059bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 606016f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 606116f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 6062906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 6063bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 6064bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6065bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6066bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6067bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6068e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6069e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6070bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 6071bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 607288c03ad3SStefano Zampini 6073906d46d4SStefano Zampini /* check */ 6074906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 6075906d46d4SStefano Zampini PetscReal error; 6076906d46d4SStefano Zampini Vec x,x_change; 6077906d46d4SStefano Zampini 6078906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 6079906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 6080906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 6081906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 6082e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6083e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6084bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 6085e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6086e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6087906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 6088906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 6089906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 6090637e8532SStefano Zampini if (error > PETSC_SMALL) { 6091637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 6092637e8532SStefano Zampini } 6093906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 6094906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 6095906d46d4SStefano Zampini } 6096b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 6097b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6098b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6099bf3a8328SStefano Zampini 61009a962809SStefano 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); 6101b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6102ac632422SStefano Zampini Mat S_new,tmat; 6103bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6104bbb9e6c6SStefano Zampini 6105bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 61066816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 6107bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6108bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 6109bf3a8328SStefano Zampini IS is_V; 6110b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 6111b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 6112b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 6113b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 6114b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 6115bf3a8328SStefano Zampini } 6116bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 6117ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6118b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 6119ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6120bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6121bf3a8328SStefano Zampini const PetscScalar *array; 6122bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6123bf3a8328SStefano Zampini PetscInt i,n_V; 6124bf3a8328SStefano Zampini 6125b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6126b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6127b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6128b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6129b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6130b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6131b087196eSStefano Zampini PetscScalar val; 6132b087196eSStefano Zampini PetscInt idx; 6133b087196eSStefano Zampini 6134b087196eSStefano Zampini idx = idxs_V[i]; 6135b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6136b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6137b087196eSStefano Zampini } 6138b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6139b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6140bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 6141bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6142bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6143bf3a8328SStefano Zampini } 6144ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 6145ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6146ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 6147ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6148b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 6149ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6150bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6151b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6152bf3a8328SStefano Zampini } 6153ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 6154ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6155ac632422SStefano Zampini } 6156b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 615788c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6158b96c3477SStefano Zampini } 6159c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 6160b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 6161c9db6a07SStefano Zampini PetscInt i; 6162c9db6a07SStefano Zampini 6163c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6164c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 6165c9db6a07SStefano Zampini } 6166c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 6167c9db6a07SStefano Zampini } 6168b96c3477SStefano Zampini } 616916909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 617016909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 617116909a7fSStefano Zampini } else { 6172906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 617316909a7fSStefano Zampini } 61741dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 617527b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 617672b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 617772b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 617872b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 617972b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 618072b8c272SStefano Zampini } 61811dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 618227b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 6183b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 6184b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 6185906d46d4SStefano Zampini } else { 61861dd7afcfSStefano Zampini Mat benign_global = NULL; 618727b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 61881dd7afcfSStefano Zampini Mat tmat; 61891dd7afcfSStefano Zampini 61901dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 61911dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 61921dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 61931dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 61941dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 61951dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 61961dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 61971dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 61981dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 61991dd7afcfSStefano Zampini if (pcbddc->benign_change) { 62001dd7afcfSStefano Zampini Mat M; 62011dd7afcfSStefano Zampini 62021dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 62031dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 62041dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 62051dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 6206906d46d4SStefano Zampini } else { 62071dd7afcfSStefano Zampini Mat eye; 62081dd7afcfSStefano Zampini PetscScalar *array; 62091dd7afcfSStefano Zampini 62101dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 62111dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 62121dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 62131dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 6214906d46d4SStefano Zampini } 62151dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 62161dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 62171dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 62181dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 62191dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 62201dd7afcfSStefano Zampini } 62211dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 62221dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 62231dd7afcfSStefano Zampini } 62241dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 62251dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 62261dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 622727b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 62281dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 62291dd7afcfSStefano Zampini } 62301dd7afcfSStefano Zampini } 623116909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 623216909a7fSStefano Zampini IS is_global; 623316909a7fSStefano Zampini const PetscInt *gidxs; 623416909a7fSStefano Zampini 623516909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 623616909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 623716909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 623816909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 623916909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 624016909a7fSStefano Zampini } 62411dd7afcfSStefano Zampini } 62421dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 62431dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 6244b9b85e73SStefano Zampini } 6245a717540cSStefano Zampini 624672b8c272SStefano Zampini if (!pcbddc->fake_change) { 62474f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 62484f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 62494f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 62504f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 6251019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 6252019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 6253019a44ceSStefano Zampini pcbddc->local_primal_size++; 6254019a44ceSStefano Zampini } 6255019a44ceSStefano Zampini 6256019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 6257727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 6258727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 62599f47a83aSStefano 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); 6260c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 62610e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 62629f47a83aSStefano 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); 6263727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 6264727cdba6SStefano Zampini } 62650e6343abSStefano Zampini } 6266727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 6267b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 626872b8c272SStefano Zampini } 626972b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 6270727cdba6SStefano Zampini 6271a717540cSStefano Zampini /* flush dbg viewer */ 6272b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 6273b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6274b8ffe317SStefano Zampini } 6275a717540cSStefano Zampini 6276e310c8b4SStefano Zampini /* free workspace */ 6277a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 62784641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 627908122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 62809162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 62819162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 628208122e43SStefano Zampini } else { 62839162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 62849162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 62859162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 628608122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 628708122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 62889162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 62899162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 629008122e43SStefano Zampini } 6291674ae819SStefano Zampini PetscFunctionReturn(0); 6292674ae819SStefano Zampini } 6293674ae819SStefano Zampini 6294674ae819SStefano Zampini #undef __FUNCT__ 6295674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 6296674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 6297674ae819SStefano Zampini { 629871582508SStefano Zampini ISLocalToGlobalMapping map; 6299674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6300674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 630114f95afaSStefano Zampini PetscInt ierr,i,N; 6302674ae819SStefano Zampini 6303674ae819SStefano Zampini PetscFunctionBegin; 63048af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 6305b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 63068e61c736SStefano Zampini /* Reset previously computed graph */ 63078e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 6308674ae819SStefano Zampini /* Init local Graph struct */ 63097fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 631071582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 6311be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 6312674ae819SStefano Zampini 6313575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 63149a962809SStefano 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); 63159577ea80SStefano Zampini 6316674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 6317d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 63184d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 63194d379d7bSStefano Zampini PetscInt nvtxs; 6320e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 6321674ae819SStefano Zampini 63222fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 63232fffb893SStefano Zampini if (flg_row) { 63244d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 6325b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 63262fffb893SStefano Zampini } 63272fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 6328674ae819SStefano Zampini } 63299b28b941SStefano Zampini if (pcbddc->dbg_flag) { 63309b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6331674ae819SStefano Zampini } 6332674ae819SStefano Zampini 6333674ae819SStefano Zampini /* Setup of Graph */ 63344b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 633514f95afaSStefano 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); 6336674ae819SStefano Zampini 63374f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 63384f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 63394f1b2e48SStefano Zampini PetscInt *local_subs; 63404f1b2e48SStefano Zampini 63414f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 63424f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 63434f1b2e48SStefano Zampini const PetscInt *idxs; 63444f1b2e48SStefano Zampini PetscInt nl,j; 63454f1b2e48SStefano Zampini 63464f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 63474f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 634871582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 63494f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 63504f1b2e48SStefano Zampini } 63514f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 63524f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 63534f1b2e48SStefano Zampini } 63548af8fcf9SStefano Zampini } 63554f1b2e48SStefano Zampini 6356cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 6357674ae819SStefano Zampini /* Graph's connected components analysis */ 6358674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 635971582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 63608af8fcf9SStefano Zampini } 6361674ae819SStefano Zampini PetscFunctionReturn(0); 6362674ae819SStefano Zampini } 6363674ae819SStefano Zampini 63649a7d3425SStefano Zampini #undef __FUNCT__ 63659a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 63669a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 63679a7d3425SStefano Zampini { 63689a7d3425SStefano Zampini PetscInt i,j; 63699a7d3425SStefano Zampini PetscScalar *alphas; 63709a7d3425SStefano Zampini PetscErrorCode ierr; 63719a7d3425SStefano Zampini 63729a7d3425SStefano Zampini PetscFunctionBegin; 6373785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 63749a7d3425SStefano Zampini for (i=0;i<n;i++) { 63759a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 6376669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 6377669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 6378669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 63799a7d3425SStefano Zampini } 63809a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 63819a7d3425SStefano Zampini PetscFunctionReturn(0); 63829a7d3425SStefano Zampini } 63839a7d3425SStefano Zampini 6384e7931f94SStefano Zampini #undef __FUNCT__ 6385bb360cb4SStefano Zampini #define __FUNCT__ "PCBDDCMatISGetSubassemblingPattern" 6386bb360cb4SStefano Zampini PetscErrorCode PCBDDCMatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 6387e7931f94SStefano Zampini { 638857de7509SStefano Zampini Mat A; 6389e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 6390e7931f94SStefano Zampini PetscMPIInt size,rank,color; 639152e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 639252e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 6393bb360cb4SStefano Zampini PetscInt im_active,active_procs,N,n,i,j,threshold = 2; 639457de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 639527b6a85dSStefano Zampini PetscInt xadj_count,*count; 639627b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 639727b6a85dSStefano Zampini PetscSubcomm psubcomm; 639827b6a85dSStefano Zampini MPI_Comm subcomm; 639952e5ac9dSStefano Zampini PetscErrorCode ierr; 6400a57a6d2fSStefano Zampini 6401e7931f94SStefano Zampini PetscFunctionBegin; 640257de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 640357de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 640457de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 640557de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 640657de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 640757de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 640857de7509SStefano Zampini 640957de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 641057de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 641157de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 641257de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 641357de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 6414bb360cb4SStefano Zampini im_active = !!n; 641557de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 641657de7509SStefano Zampini void_procs = size - active_procs; 641757de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 641857de7509SStefano Zampini if (void_procs) { 641957de7509SStefano Zampini PetscInt ncand; 642057de7509SStefano Zampini 642157de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 642257de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 642357de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 642457de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 642557de7509SStefano Zampini if (!procs_candidates[i]) { 642657de7509SStefano Zampini procs_candidates[ncand++] = i; 642757de7509SStefano Zampini } 642857de7509SStefano Zampini } 642957de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 643057de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 643157de7509SStefano Zampini } 643257de7509SStefano Zampini 6433bb360cb4SStefano Zampini /* number of subdomains requested greater than active processes or matrix size -> just shift the matrix 643414f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 6435bb360cb4SStefano Zampini ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 6436bb360cb4SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1 || N <= *n_subdomains) { 643714f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 643814f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 643914f0bfb9SStefano Zampini else dest = rank; 644057de7509SStefano Zampini if (im_active) { 644157de7509SStefano Zampini issize = 1; 644257de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 644314f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 644457de7509SStefano Zampini } else { 644514f0bfb9SStefano Zampini isidx = dest; 644657de7509SStefano Zampini } 644757de7509SStefano Zampini } else { 644857de7509SStefano Zampini issize = 0; 644957de7509SStefano Zampini isidx = -1; 645057de7509SStefano Zampini } 6451bb360cb4SStefano Zampini if (*n_subdomains != 1) *n_subdomains = active_procs; 645257de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 6453daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 645457de7509SStefano Zampini PetscFunctionReturn(0); 645557de7509SStefano Zampini } 6456c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 6457c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 645827b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 6459e7931f94SStefano Zampini 6460e7931f94SStefano Zampini /* Get info on mapping */ 64613bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6462e7931f94SStefano Zampini 6463e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 6464785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 6465e7931f94SStefano Zampini xadj[0] = 0; 6466e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 6467785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 6468785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 6469bb360cb4SStefano Zampini ierr = PetscCalloc1(n,&count);CHKERRQ(ierr); 647027b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 647127b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 647227b6a85dSStefano Zampini count[shared[i][j]] += 1; 6473e7931f94SStefano Zampini 647427b6a85dSStefano Zampini xadj_count = 0; 64752b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 647627b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 647727b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 6478d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 6479d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 6480d023bfaeSStefano Zampini xadj_count++; 648127b6a85dSStefano Zampini break; 648227b6a85dSStefano Zampini } 6483e7931f94SStefano Zampini } 6484e7931f94SStefano Zampini } 6485d023bfaeSStefano Zampini xadj[1] = xadj_count; 648627b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 64873bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6488e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 6489e7931f94SStefano Zampini 64903837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 6491e7931f94SStefano Zampini 649227b6a85dSStefano Zampini /* Restrict work on active processes only */ 649327b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 649427b6a85dSStefano Zampini if (void_procs) { 649527b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 649627b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 649727b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 649827b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 649927b6a85dSStefano Zampini } else { 650027b6a85dSStefano Zampini psubcomm = NULL; 650127b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 650227b6a85dSStefano Zampini } 650327b6a85dSStefano Zampini 650427b6a85dSStefano Zampini v_wgt = NULL; 650527b6a85dSStefano Zampini if (!color) { 6506e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 6507e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 6508e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6509c8587f34SStefano Zampini } else { 651052e5ac9dSStefano Zampini Mat subdomain_adj; 651152e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 651252e5ac9dSStefano Zampini MatPartitioning partitioner; 651327b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 651452e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 651557de7509SStefano Zampini PetscMPIInt size; 6516b0c7d250SStefano Zampini PetscBool aggregate; 6517b0c7d250SStefano Zampini 651827b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 651927b6a85dSStefano Zampini if (void_procs) { 652027b6a85dSStefano Zampini PetscInt prank = rank; 6521785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 652227b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 6523e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 6524e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 6525c8587f34SStefano Zampini } 6526e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 652727b6a85dSStefano Zampini } else { 652827b6a85dSStefano Zampini oldranks = NULL; 652927b6a85dSStefano Zampini } 6530b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 653127b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 6532b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 6533b0c7d250SStefano Zampini PetscMPIInt nrank; 6534b0c7d250SStefano Zampini PetscScalar *vals; 6535b0c7d250SStefano Zampini 653627b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 6537b0c7d250SStefano Zampini lrows = 0; 6538b0c7d250SStefano Zampini if (nrank<redprocs) { 6539b0c7d250SStefano Zampini lrows = size/redprocs; 6540b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 6541b0c7d250SStefano Zampini } 654227b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 6543b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 6544b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6545b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6546b0c7d250SStefano Zampini row = nrank; 6547b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 6548b0c7d250SStefano Zampini cols = adjncy; 6549b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 6550b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 6551b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 6552b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6553b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 655452e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 655552e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 655652e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6557b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 655827b6a85dSStefano Zampini if (use_vwgt) { 655927b6a85dSStefano Zampini Vec v; 656027b6a85dSStefano Zampini const PetscScalar *array; 656127b6a85dSStefano Zampini PetscInt nl; 656227b6a85dSStefano Zampini 656327b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 6564bb360cb4SStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)n,INSERT_VALUES);CHKERRQ(ierr); 656527b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 656627b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 656727b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 656827b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 656927b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 657022db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 657127b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 657227b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 657327b6a85dSStefano Zampini } 6574b0c7d250SStefano Zampini } else { 657527b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 657627b6a85dSStefano Zampini if (use_vwgt) { 657727b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 6578bb360cb4SStefano Zampini v_wgt[0] = n; 657927b6a85dSStefano Zampini } 6580b0c7d250SStefano Zampini } 658122b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 6582e7931f94SStefano Zampini 6583e7931f94SStefano Zampini /* Partition */ 658427b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 6585e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 658627b6a85dSStefano Zampini if (v_wgt) { 6587e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 6588c8587f34SStefano Zampini } 658957de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 659057de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 6591e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 6592e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 659322b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 6594e7931f94SStefano Zampini 659552e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 65966583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 659752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 659852e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 659957de7509SStefano Zampini if (!aggregate) { 660057de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 660127b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 660227b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 660327b6a85dSStefano Zampini #endif 660457de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 660527b6a85dSStefano Zampini } else if (oldranks) { 6606b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 660727b6a85dSStefano Zampini } else { 660827b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 660957de7509SStefano Zampini } 661028143c3dSStefano Zampini } else { 6611b0c7d250SStefano Zampini PetscInt idxs[1]; 6612b0c7d250SStefano Zampini PetscMPIInt tag; 6613b0c7d250SStefano Zampini MPI_Request *reqs; 6614b0c7d250SStefano Zampini 6615b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 6616b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 6617b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 661827b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 661928143c3dSStefano Zampini } 662027b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 6621b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6622b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 662357de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 662427b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 662527b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 662627b6a85dSStefano Zampini #endif 662757de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 662827b6a85dSStefano Zampini } else if (oldranks) { 6629b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 663027b6a85dSStefano Zampini } else { 663127b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 6632e7931f94SStefano Zampini } 663357de7509SStefano Zampini } 663452e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6635e7931f94SStefano Zampini /* clean up */ 6636e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 663752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 6638e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 6639e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 6640e7931f94SStefano Zampini } 664127b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 664257de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 6643e7931f94SStefano Zampini 6644e7931f94SStefano Zampini /* assemble parallel IS for sends */ 6645e7931f94SStefano Zampini i = 1; 664627b6a85dSStefano Zampini if (!color) i=0; 664757de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 6648e7931f94SStefano Zampini PetscFunctionReturn(0); 6649e7931f94SStefano Zampini } 6650e7931f94SStefano Zampini 6651e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 6652e7931f94SStefano Zampini 6653e7931f94SStefano Zampini #undef __FUNCT__ 66541e0482f5SStefano Zampini #define __FUNCT__ "PCBDDCMatISSubassemble" 66551e0482f5SStefano Zampini PetscErrorCode PCBDDCMatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, PetscBool restrict_full, PetscBool reuse, Mat *mat_n, PetscInt nis, IS isarray[], PetscInt nvecs, Vec nnsp_vec[]) 6656e7931f94SStefano Zampini { 665770cf5478SStefano Zampini Mat local_mat; 6658e7931f94SStefano Zampini IS is_sends_internal; 66599d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 66601ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 66619d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 6662e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 6663e7931f94SStefano Zampini PetscInt* l2gmap_indices; 6664e7931f94SStefano Zampini const PetscInt* is_indices; 6665e7931f94SStefano Zampini MatType new_local_type; 6666e7931f94SStefano Zampini /* buffers */ 6667e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 666828143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 66699d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 6670e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 66711ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 6672e7931f94SStefano Zampini /* MPI */ 667328143c3dSStefano Zampini MPI_Comm comm,comm_n; 667428143c3dSStefano Zampini PetscSubcomm subcomm; 6675e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 667628143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 667728143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 66781ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 66791ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 66801ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 6681e7931f94SStefano Zampini PetscErrorCode ierr; 6682e7931f94SStefano Zampini 6683e7931f94SStefano Zampini PetscFunctionBegin; 668457de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6685e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 668628143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 668757de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 668857de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 668957de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 669057de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 669157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 66921ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 66931ae86dd6SStefano Zampini if (nvecs) { 66941ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 66951ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 66961ae86dd6SStefano Zampini } 669757de7509SStefano Zampini /* further checks */ 6698e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6699e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 6700e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 6701e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 6702e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 670357de7509SStefano Zampini if (reuse && *mat_n) { 670470cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 670557de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 670670cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 670728143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 670870cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 670970cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 671070cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 671170cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 671270cf5478SStefano Zampini } 6713e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 6714e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 671557de7509SStefano Zampini 6716e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 6717e7931f94SStefano Zampini if (!is_sends) { 671828143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 6719bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 6720c8587f34SStefano Zampini } else { 6721e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 6722e7931f94SStefano Zampini is_sends_internal = is_sends; 6723c8587f34SStefano Zampini } 6724e7931f94SStefano Zampini 6725e7931f94SStefano Zampini /* get comm */ 6726a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 6727e7931f94SStefano Zampini 6728e7931f94SStefano Zampini /* compute number of sends */ 6729e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 6730e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 6731e7931f94SStefano Zampini 6732e7931f94SStefano Zampini /* compute number of receives */ 6733e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 6734785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 6735e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 6736e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6737e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 6738e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 6739e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 6740e7931f94SStefano Zampini 674128143c3dSStefano Zampini /* restrict comm if requested */ 674228143c3dSStefano Zampini subcomm = 0; 674328143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 674428143c3dSStefano Zampini if (restrict_comm) { 6745779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 6746779c1cceSStefano Zampini 674728143c3dSStefano Zampini color = 0; 674853a05cb3SStefano Zampini if (restrict_full) { 674953a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 675053a05cb3SStefano Zampini } else { 675153a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 675253a05cb3SStefano Zampini } 6753b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 675428143c3dSStefano Zampini subcommsize = commsize - subcommsize; 675528143c3dSStefano Zampini /* check if reuse has been requested */ 675657de7509SStefano Zampini if (reuse) { 675728143c3dSStefano Zampini if (*mat_n) { 675828143c3dSStefano Zampini PetscMPIInt subcommsize2; 675928143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 676028143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 676128143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 676228143c3dSStefano Zampini } else { 676328143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 676428143c3dSStefano Zampini } 676528143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 6766779c1cceSStefano Zampini PetscMPIInt rank; 6767779c1cceSStefano Zampini 6768779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 676928143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 677028143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 677128143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 6772306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 677328143c3dSStefano Zampini } 677428143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 677528143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 677628143c3dSStefano Zampini } else { 677728143c3dSStefano Zampini comm_n = comm; 677828143c3dSStefano Zampini } 677928143c3dSStefano Zampini 6780e7931f94SStefano Zampini /* prepare send/receive buffers */ 6781785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 6782e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 6783785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 6784e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 678528143c3dSStefano Zampini if (nis) { 6786854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 678728143c3dSStefano Zampini } 6788e7931f94SStefano Zampini 678928143c3dSStefano Zampini /* Get data from local matrices */ 67906c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 6791e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 6792e7931f94SStefano Zampini /* 6793e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 6794e7931f94SStefano Zampini send_buffer_idxs should contain: 6795e7931f94SStefano Zampini - MatType_PRIVATE type 6796e7931f94SStefano Zampini - PetscInt size_of_l2gmap 6797e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 6798e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 6799e7931f94SStefano Zampini */ 68006c4ed002SBarry Smith else { 6801e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 68023bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 6803854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 6804e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 6805e7931f94SStefano Zampini send_buffer_idxs[1] = i; 68063bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6807e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 68083bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6809e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 6810e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6811e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 6812e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 6813c8587f34SStefano Zampini } 6814c8587f34SStefano Zampini } 6815e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 681628143c3dSStefano Zampini /* additional is (if any) */ 681728143c3dSStefano Zampini if (nis) { 681828143c3dSStefano Zampini PetscMPIInt psum; 681928143c3dSStefano Zampini PetscInt j; 682028143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 682128143c3dSStefano Zampini PetscInt plen; 682228143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 682328143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 682428143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 682528143c3dSStefano Zampini } 6826854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 682728143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 682828143c3dSStefano Zampini PetscInt plen; 682928143c3dSStefano Zampini const PetscInt *is_array_idxs; 683028143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 683128143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 683228143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 683328143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 683428143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 683528143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 683628143c3dSStefano Zampini } 683728143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 683828143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 683928143c3dSStefano Zampini } 684028143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 684128143c3dSStefano Zampini } 684228143c3dSStefano Zampini 6843e7931f94SStefano Zampini buf_size_idxs = 0; 6844e7931f94SStefano Zampini buf_size_vals = 0; 684528143c3dSStefano Zampini buf_size_idxs_is = 0; 68461ae86dd6SStefano Zampini buf_size_vecs = 0; 6847e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6848e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 6849e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 685028143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 68511ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 6852e7931f94SStefano Zampini } 6853785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 6854785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 685595ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 68561ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 6857e7931f94SStefano Zampini 6858e7931f94SStefano Zampini /* get new tags for clean communications */ 6859e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 6860e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 686128143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 68621ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 6863e7931f94SStefano Zampini 6864e7931f94SStefano Zampini /* allocate for requests */ 6865785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 6866785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 686795ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 68681ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 6869785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 6870785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 687195ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 68721ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 6873e7931f94SStefano Zampini 6874e7931f94SStefano Zampini /* communications */ 6875e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6876e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 687728143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 68781ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 6879e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6880e7931f94SStefano Zampini source_dest = onodes[i]; 6881e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 6882e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 6883e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6884e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 688528143c3dSStefano Zampini if (nis) { 688657de7509SStefano Zampini source_dest = onodes_is[i]; 688728143c3dSStefano 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); 688828143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 688928143c3dSStefano Zampini } 68901ae86dd6SStefano Zampini if (nvecs) { 68911ae86dd6SStefano Zampini source_dest = onodes[i]; 68921ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 68931ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 68941ae86dd6SStefano Zampini } 6895e7931f94SStefano Zampini } 6896e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6897e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 6898e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 6899e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 690028143c3dSStefano Zampini if (nis) { 690128143c3dSStefano 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); 690228143c3dSStefano Zampini } 69031ae86dd6SStefano Zampini if (nvecs) { 69041ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 69051ae86dd6SStefano 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); 69061ae86dd6SStefano Zampini } 6907e7931f94SStefano Zampini } 6908e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6909e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 6910e7931f94SStefano Zampini 6911e7931f94SStefano Zampini /* assemble new l2g map */ 6912e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6913e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 69149d30be91SStefano Zampini new_local_rows = 0; 6915e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 69169d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6917e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6918e7931f94SStefano Zampini } 69199d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 6920e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 69219d30be91SStefano Zampini new_local_rows = 0; 6922e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 69239d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 69249d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6925e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6926e7931f94SStefano Zampini } 69279d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 69289d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 6929e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 6930e7931f94SStefano Zampini 6931e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 6932e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 6933e7931f94SStefano 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) */ 6934e7931f94SStefano Zampini if (n_recvs) { 693528143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 6936e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6937e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6938e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 6939e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 6940e7931f94SStefano Zampini break; 6941e7931f94SStefano Zampini } 6942e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6943e7931f94SStefano Zampini } 6944e7931f94SStefano Zampini switch (new_local_type_private) { 694528143c3dSStefano Zampini case MATDENSE_PRIVATE: 694628143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 6947e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6948e7931f94SStefano Zampini bs = 1; 694928143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 695028143c3dSStefano Zampini new_local_type = MATSEQDENSE; 695128143c3dSStefano Zampini bs = 1; 695228143c3dSStefano Zampini } 6953e7931f94SStefano Zampini break; 6954e7931f94SStefano Zampini case MATAIJ_PRIVATE: 6955e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6956e7931f94SStefano Zampini bs = 1; 6957e7931f94SStefano Zampini break; 6958e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 6959e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 6960e7931f94SStefano Zampini break; 6961e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 6962e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 6963e7931f94SStefano Zampini break; 6964e7931f94SStefano Zampini default: 69659d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 6966e7931f94SStefano Zampini break; 6967e7931f94SStefano Zampini } 696828143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 696928143c3dSStefano Zampini new_local_type = MATSEQDENSE; 697028143c3dSStefano Zampini bs = 1; 6971e7931f94SStefano Zampini } 6972e7931f94SStefano Zampini 697370cf5478SStefano Zampini /* create MATIS object if needed */ 697457de7509SStefano Zampini if (!reuse) { 6975e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 6976e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 697770cf5478SStefano Zampini } else { 697870cf5478SStefano Zampini /* it also destroys the local matrices */ 697957de7509SStefano Zampini if (*mat_n) { 698070cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 698157de7509SStefano Zampini } else { /* this is a fake object */ 698257de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 698357de7509SStefano Zampini } 698470cf5478SStefano Zampini } 698570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 6986e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 69879d30be91SStefano Zampini 69889d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 69899d30be91SStefano Zampini 69909d30be91SStefano Zampini /* Global to local map of received indices */ 69919d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 69929d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 69939d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 69949d30be91SStefano Zampini 69959d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 69969d30be91SStefano Zampini buf_size_idxs = 0; 69979d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 69989d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 69999d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 70009d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 70019d30be91SStefano Zampini } 70029d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 70039d30be91SStefano Zampini 70049d30be91SStefano Zampini /* set preallocation */ 70059d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 70069d30be91SStefano Zampini if (!newisdense) { 70079d30be91SStefano Zampini PetscInt *new_local_nnz=0; 70089d30be91SStefano Zampini 70099d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 70109d30be91SStefano Zampini if (n_recvs) { 70119d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 70129d30be91SStefano Zampini } 70139d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 70149d30be91SStefano Zampini PetscInt j; 70159d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 70169d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 70179d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 70189d30be91SStefano Zampini } 70199d30be91SStefano Zampini } else { 70209d30be91SStefano Zampini /* TODO */ 70219d30be91SStefano Zampini } 70229d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 70239d30be91SStefano Zampini } 70249d30be91SStefano Zampini if (new_local_nnz) { 70259d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 70269d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 70279d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 70289d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 70299d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 70309d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 70319d30be91SStefano Zampini } else { 70329d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 70339d30be91SStefano Zampini } 70349d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 70359d30be91SStefano Zampini } else { 70369d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 70379d30be91SStefano Zampini } 7038e7931f94SStefano Zampini 7039e7931f94SStefano Zampini /* set values */ 7040e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 70419d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 7042e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7043e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 7044e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 70459d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 7046e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7047e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7048e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 704928143c3dSStefano Zampini } else { 705028143c3dSStefano Zampini /* TODO */ 7051e7931f94SStefano Zampini } 7052e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7053e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 7054e7931f94SStefano Zampini } 7055e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7056e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 705770cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 705870cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 70599d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 7060e7931f94SStefano Zampini 7061dfd14d43SStefano Zampini #if 0 706228143c3dSStefano Zampini if (!restrict_comm) { /* check */ 7063e7931f94SStefano Zampini Vec lvec,rvec; 7064e7931f94SStefano Zampini PetscReal infty_error; 7065e7931f94SStefano Zampini 70662a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 7067e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 7068e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 7069e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 707070cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 7071e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 7072e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 7073e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 7074e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 7075e7931f94SStefano Zampini } 707628143c3dSStefano Zampini #endif 7077e7931f94SStefano Zampini 707828143c3dSStefano Zampini /* assemble new additional is (if any) */ 707928143c3dSStefano Zampini if (nis) { 708028143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 708128143c3dSStefano Zampini 708228143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7083854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 708428143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 708528143c3dSStefano Zampini psum = 0; 708628143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 708728143c3dSStefano Zampini for (j=0;j<nis;j++) { 708828143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 708928143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 709028143c3dSStefano Zampini psum += plen; 709128143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 709228143c3dSStefano Zampini } 709328143c3dSStefano Zampini } 7094854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 7095854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 709628143c3dSStefano Zampini for (i=1;i<nis;i++) { 709728143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 709828143c3dSStefano Zampini } 709928143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 710028143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 710128143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 710228143c3dSStefano Zampini for (j=0;j<nis;j++) { 710328143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 710428143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 710528143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 710628143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 710728143c3dSStefano Zampini } 710828143c3dSStefano Zampini } 710928143c3dSStefano Zampini for (i=0;i<nis;i++) { 711028143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 711128143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 711228143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 711328143c3dSStefano Zampini } 711428143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 711528143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 711628143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 711728143c3dSStefano Zampini } 7118e7931f94SStefano Zampini /* free workspace */ 711928143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 7120e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7121e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 7122e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7123e7931f94SStefano Zampini if (isdense) { 7124e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7125e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 7126e7931f94SStefano Zampini } else { 7127e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 7128e7931f94SStefano Zampini } 712928143c3dSStefano Zampini if (nis) { 713028143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 713128143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 713228143c3dSStefano Zampini } 71331ae86dd6SStefano Zampini 71341ae86dd6SStefano Zampini if (nvecs) { 71351ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 71361ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 71371ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 71381ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 71391ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 71401ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 71411ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 71421ae86dd6SStefano Zampini /* set values */ 71431ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 71441ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 71451ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 71461ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 71471ae86dd6SStefano Zampini PetscInt j; 71481ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 71491ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 71501ae86dd6SStefano Zampini } 71511ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 71521ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 71531ae86dd6SStefano Zampini } 71541ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 71551ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 71561ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 71571ae86dd6SStefano Zampini } 71581ae86dd6SStefano Zampini 71591ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 71601ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 7161e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 7162e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 71631ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 716428143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 7165e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 7166e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 71671ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 716828143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 7169e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 7170e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 7171e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 7172e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 7173e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 717428143c3dSStefano Zampini if (nis) { 717528143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 717628143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 717728143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 717828143c3dSStefano Zampini } 717928143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 718028143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 718128143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 718228143c3dSStefano Zampini for (i=0;i<nis;i++) { 718328143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 718428143c3dSStefano Zampini } 71851ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 71861ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 71871ae86dd6SStefano Zampini } 718853a05cb3SStefano Zampini *mat_n = NULL; 718928143c3dSStefano Zampini } 7190e7931f94SStefano Zampini PetscFunctionReturn(0); 7191e7931f94SStefano Zampini } 7192a57a6d2fSStefano Zampini 719312edc857SStefano Zampini /* temporary hack into ksp private data structure */ 7194af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 719512edc857SStefano Zampini 7196c8587f34SStefano Zampini #undef __FUNCT__ 7197c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 7198c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 7199c8587f34SStefano Zampini { 7200c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7201c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 720220a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 72031ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 72041e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 72059881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 720620a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 72076e683305SStefano Zampini IS coarse_is,*isarray; 72086e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 720930368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 7210f9eb5b7dSStefano Zampini PC pc_temp; 7211c8587f34SStefano Zampini PCType coarse_pc_type; 7212c8587f34SStefano Zampini KSPType coarse_ksp_type; 7213f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 72144f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 72151e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 721668457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 721722bc73bbSStefano Zampini PetscScalar *array; 721857de7509SStefano Zampini MatReuse coarse_mat_reuse; 721957de7509SStefano Zampini PetscBool restr, full_restr, have_void; 72209881197aSStefano Zampini PetscErrorCode ierr; 7221fdc09c96SStefano Zampini 7222c8587f34SStefano Zampini PetscFunctionBegin; 7223c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 722468457ee5SStefano 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 */ 7225fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 72265a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 7227fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 7228f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 7229f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 7230f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 7231fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 723251bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 723351bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 7234dc4bcba2SStefano Zampini PC pc; 7235dc4bcba2SStefano Zampini PetscBool isbddc; 7236dc4bcba2SStefano Zampini 7237dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 7238dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 7239dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 7240dc4bcba2SStefano Zampini if (isbddc) { 724163c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 724263c961adSStefano Zampini } else { 7243727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 724463c961adSStefano Zampini } 7245fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7246fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 7247fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7248f4ddd8eeSStefano Zampini } 7249fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 7250fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7251f4ddd8eeSStefano Zampini } 725270cf5478SStefano Zampini /* reset any subassembling information */ 725357de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 725470cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 725557de7509SStefano Zampini } 72566e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 7257fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7258f4ddd8eeSStefano Zampini } 725957de7509SStefano Zampini /* assemble coarse matrix */ 726057de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 726157de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 726257de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 726357de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 726418a45a71SStefano Zampini } else { 726557de7509SStefano Zampini coarse_mat = NULL; 726657de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 72676e683305SStefano Zampini } 7268e7931f94SStefano Zampini 7269abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 7270abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 7271abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 7272abbbba34SStefano Zampini 7273abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 727422bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 727522bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 727622bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 727722bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 7278e176bc59SStefano 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); 72796e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 72806e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 72816e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7282abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 7283abbbba34SStefano Zampini 728457de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 728557de7509SStefano Zampini im_active = !!(pcis->n); 728657de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 728757de7509SStefano Zampini 728814f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 728957de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 729057de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 729157de7509SStefano Zampini coarse_mat_is = NULL; 729257de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 729357de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 72941ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 729557de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 729657de7509SStefano Zampini if (multilevel_requested) { 729757de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 729857de7509SStefano Zampini restr = PETSC_FALSE; 729957de7509SStefano Zampini full_restr = PETSC_FALSE; 730057de7509SStefano Zampini } else { 730157de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 730257de7509SStefano Zampini restr = PETSC_TRUE; 730357de7509SStefano Zampini full_restr = PETSC_TRUE; 730457de7509SStefano Zampini } 73054b2aedd3SStefano Zampini if (!pcbddc->coarse_size) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 730657de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 730757de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 7308a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 7309bb360cb4SStefano Zampini if (multilevel_requested) { 7310bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7311bb360cb4SStefano Zampini } else { 7312bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7313bb360cb4SStefano Zampini } 7314a198735bSStefano Zampini } else { 7315a198735bSStefano Zampini PetscMPIInt size,rank; 7316a198735bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 7317a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 7318a198735bSStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 7319a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7320a198735bSStefano Zampini } 732157de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 732257de7509SStefano Zampini PetscInt psum; 732357de7509SStefano Zampini PetscMPIInt size; 732457de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 732557de7509SStefano Zampini else psum = 0; 732657de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 732757de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 732857de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 732957de7509SStefano Zampini } 733057de7509SStefano Zampini /* determine if we can go multilevel */ 733157de7509SStefano Zampini if (multilevel_requested) { 733257de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 733357de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 733457de7509SStefano Zampini } 733557de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 733657de7509SStefano Zampini 7337e4d548c7SStefano Zampini /* dump subassembling pattern */ 7338e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 7339e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 7340e4d548c7SStefano Zampini } 7341e4d548c7SStefano Zampini 73426e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 73431e0482f5SStefano Zampini nedcfield = -1; 73441e0482f5SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal)) { /* protects from unneded computations */ 73456e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 73466e683305SStefano Zampini const PetscInt *idxs; 73476e683305SStefano Zampini ISLocalToGlobalMapping tmap; 73486e683305SStefano Zampini 73496e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 73500be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 73516e683305SStefano Zampini /* allocate space for temporary storage */ 7352854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 7353854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 73546e683305SStefano Zampini /* allocate for IS array */ 73556e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 73561e0482f5SStefano Zampini if (pcbddc->nedclocal) { 73571e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 73581e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 73591e0482f5SStefano Zampini } else { 73601e0482f5SStefano Zampini nedcfield = 0; 73611e0482f5SStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%d)",nisdofs); 73621e0482f5SStefano Zampini nisdofs = 1; 73631e0482f5SStefano Zampini } 73641e0482f5SStefano Zampini } 73656e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 736627b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 736730368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 7368854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 73696e683305SStefano Zampini /* dofs splitting */ 73706e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 73716e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 73721e0482f5SStefano Zampini if (nedcfield != i) { 73736e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 73746e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 73756e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 73766e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 73771e0482f5SStefano Zampini } else { 73781e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 73791e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 73801e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 7381eee23b56SStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %d != %d\n",tsize,nout); 73821e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 73831e0482f5SStefano Zampini } 73846e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 738530368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 73866e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 73876e683305SStefano Zampini } 73886e683305SStefano Zampini /* neumann boundaries */ 73896e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 73906e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 73916e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 73926e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 73936e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 73946e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 73956e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 739630368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 73976e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 73986e683305SStefano Zampini } 73996e683305SStefano Zampini /* free memory */ 74006e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 74016e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 74026e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 74036e683305SStefano Zampini } else { 74046e683305SStefano Zampini nis = 0; 74056e683305SStefano Zampini nisdofs = 0; 74066e683305SStefano Zampini nisneu = 0; 740730368db7SStefano Zampini nisvert = 0; 74086e683305SStefano Zampini isarray = NULL; 74096e683305SStefano Zampini } 74106e683305SStefano Zampini /* destroy no longer needed map */ 74116e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 74126e683305SStefano Zampini 741357de7509SStefano Zampini /* subassemble */ 741457de7509SStefano Zampini if (multilevel_allowed) { 74151ae86dd6SStefano Zampini Vec vp[1]; 74161ae86dd6SStefano Zampini PetscInt nvecs = 0; 741757de7509SStefano Zampini PetscBool reuse,reuser; 74181ae86dd6SStefano Zampini 741957de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 742057de7509SStefano Zampini else reuse = PETSC_FALSE; 742157de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 74221ae86dd6SStefano Zampini vp[0] = NULL; 74231ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 74241ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 74251ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 74261ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 74271ae86dd6SStefano Zampini nvecs = 1; 74281ae86dd6SStefano Zampini 74291ae86dd6SStefano Zampini if (pcbddc->divudotp) { 7430a198735bSStefano Zampini Mat B,loc_divudotp; 74311ae86dd6SStefano Zampini Vec v,p; 74321ae86dd6SStefano Zampini IS dummy; 74331ae86dd6SStefano Zampini PetscInt np; 74341ae86dd6SStefano Zampini 7435a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 7436a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 74371ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 7438a198735bSStefano Zampini ierr = MatGetSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 74391ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 74401ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 74411ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 74421ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 74431ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 74441ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 74451ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 74461ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 74471ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 74481ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 74491ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 74501ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 745174e2c79eSStefano Zampini } 74521ae86dd6SStefano Zampini } 74531ae86dd6SStefano Zampini if (reuser) { 74541e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 745574e2c79eSStefano Zampini } else { 74561e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray,nvecs,vp);CHKERRQ(ierr); 74571ae86dd6SStefano Zampini } 74581ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 74591ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 74601ae86dd6SStefano Zampini PetscInt nl; 74611ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 74621ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 74631ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 74641ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 74651ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 74661ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 74671ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 74681ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 7469a198735bSStefano Zampini } else { 7470a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 74711ae86dd6SStefano Zampini } 74721ae86dd6SStefano Zampini } else { 74731e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,0,NULL,0,NULL);CHKERRQ(ierr); 74746e683305SStefano Zampini } 747557de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 747657de7509SStefano Zampini PetscMPIInt size; 7477f913dca9SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size);CHKERRQ(ierr); 747857de7509SStefano Zampini if (!multilevel_allowed) { 747957de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 74806e683305SStefano Zampini } else { 748157de7509SStefano Zampini Mat A; 7482779c1cceSStefano Zampini 748357de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 748457de7509SStefano Zampini if (coarse_mat_is) { 748557de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 748657de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 748757de7509SStefano Zampini coarse_mat = coarse_mat_is; 748857de7509SStefano Zampini } 748957de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 749057de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 749157de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 7492779c1cceSStefano Zampini } 7493779c1cceSStefano Zampini } 749457de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 749557de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 74966e683305SStefano Zampini 74976e683305SStefano Zampini /* create local to global scatters for coarse problem */ 749868457ee5SStefano Zampini if (compute_vecs) { 74996e683305SStefano Zampini PetscInt lrows; 75006e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 750157de7509SStefano Zampini if (coarse_mat) { 750257de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 75036e683305SStefano Zampini } else { 75046e683305SStefano Zampini lrows = 0; 75056e683305SStefano Zampini } 75066e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 75076e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 75086e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 75096e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 75106e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 75116e683305SStefano Zampini } 75126e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 7513c8587f34SStefano Zampini 7514f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 7515f9eb5b7dSStefano Zampini if (multilevel_allowed) { 7516f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 7517f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 7518f9eb5b7dSStefano Zampini } else { 7519f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 7520f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 7521c8587f34SStefano Zampini } 7522c8587f34SStefano Zampini 75236e683305SStefano Zampini /* print some info if requested */ 75246e683305SStefano Zampini if (pcbddc->dbg_flag) { 75256e683305SStefano Zampini if (!multilevel_allowed) { 75266e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 75276e683305SStefano Zampini if (multilevel_requested) { 75286e683305SStefano 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); 75296e683305SStefano Zampini } else if (pcbddc->max_levels) { 75306e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 75316e683305SStefano Zampini } 75326e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 75336e683305SStefano Zampini } 75346e683305SStefano Zampini } 75356e683305SStefano Zampini 75361e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 75371e0482f5SStefano Zampini coarseG = NULL; 75381e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 75391e0482f5SStefano Zampini MPI_Comm ccomm; 75401e0482f5SStefano Zampini if (coarse_mat) { 75411e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 75421e0482f5SStefano Zampini } else { 75431e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 75441e0482f5SStefano Zampini } 75451e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 75461e0482f5SStefano Zampini } 75471e0482f5SStefano Zampini 7548f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 754957de7509SStefano Zampini if (coarse_mat) { 75506a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 75516e683305SStefano Zampini if (pcbddc->dbg_flag) { 755257de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 75536e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 75546e683305SStefano Zampini } 7555f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 7556312be037SStefano Zampini char prefix[256],str_level[16]; 7557e604994aSStefano Zampini size_t len; 75581e0482f5SStefano Zampini 755957de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 7560422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 7561c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 7562f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 756357de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7564c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 75656e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 7566c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 75671e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 7568c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7569e604994aSStefano Zampini /* prefix */ 7570e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 7571e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 7572e604994aSStefano Zampini if (!pcbddc->current_level) { 7573e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 7574e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 7575c8587f34SStefano Zampini } else { 7576e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 7577312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 7578312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 757934d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 7580312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 7581e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 7582e604994aSStefano Zampini } 7583e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 75843e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 75853e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 75863e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 75873e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 7588f9eb5b7dSStefano Zampini /* allow user customization */ 7589f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 75903e3c6dadSStefano Zampini } 75913e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 759251bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 75933e3c6dadSStefano Zampini if (nisdofs) { 75943e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 75953e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 75963e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 75973e3c6dadSStefano Zampini } 75983e3c6dadSStefano Zampini } 75993e3c6dadSStefano Zampini if (nisneu) { 76003e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 76013e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 7602312be037SStefano Zampini } 760330368db7SStefano Zampini if (nisvert) { 760430368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 760530368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 760630368db7SStefano Zampini } 76071e0482f5SStefano Zampini if (coarseG) { 76081e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 76091e0482f5SStefano Zampini } 7610f9eb5b7dSStefano Zampini 7611f9eb5b7dSStefano Zampini /* get some info after set from options */ 7612f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 7613f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 76144f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 76156e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 7616f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7617f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 7618f9eb5b7dSStefano Zampini } 761939f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 76204f3a063dSStefano Zampini if (isredundant) { 76214f3a063dSStefano Zampini KSP inner_ksp; 76224f3a063dSStefano Zampini PC inner_pc; 76234f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 76244f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 76254f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 76264f3a063dSStefano Zampini } 7627f9eb5b7dSStefano Zampini 762857de7509SStefano Zampini /* parameters which miss an API */ 762957de7509SStefano Zampini if (isbddc) { 7630720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 7631720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 763257de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 763327b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 763427b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 7635a198735bSStefano Zampini Mat coarsedivudotp_is; 7636a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 7637a198735bSStefano Zampini IS row,col; 7638a198735bSStefano Zampini const PetscInt *gidxs; 7639a198735bSStefano Zampini PetscInt n,st,M,N; 7640a198735bSStefano Zampini 7641a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 7642a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 7643a198735bSStefano Zampini st = st-n; 7644a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 7645a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 7646a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 7647a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7648a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 7649a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7650a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 7651a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 7652a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 7653a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 7654a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 7655a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 7656a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 7657a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 7658a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 7659a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 7660a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7661a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7662a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 7663a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 76648ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 7665a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 7666720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 766759e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 7668720d30f9SStefano Zampini } 7669d4d8cf7bSStefano Zampini } 76709881197aSStefano Zampini 76713301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 76725a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 76733301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 76743301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 76753301b35fSStefano Zampini } 76763301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 76773301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 76783301b35fSStefano Zampini } 76793301b35fSStefano Zampini if (pc->pmat->spd_set) { 76803301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 76813301b35fSStefano Zampini } 768227b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 768327b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 768427b6a85dSStefano Zampini } 76856e683305SStefano Zampini /* set operators */ 76865f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 76876e683305SStefano Zampini if (pcbddc->dbg_flag) { 76886e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 76896e683305SStefano Zampini } 76906e683305SStefano Zampini } 76911e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 76926e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 7693b1ecc7b1SStefano Zampini #if 0 7694b9b85e73SStefano Zampini { 7695b9b85e73SStefano Zampini PetscViewer viewer; 7696b9b85e73SStefano Zampini char filename[256]; 7697b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 7698b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 76996a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 7700b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 7701f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 7702b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 7703b9b85e73SStefano Zampini } 7704b9b85e73SStefano Zampini #endif 7705f9eb5b7dSStefano Zampini 770698a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 770798a51de6SStefano Zampini Vec crhs,csol; 770804708bb6SStefano Zampini 7709f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 7710f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 7711f347579bSStefano Zampini if (!csol) { 77122a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 7713f9eb5b7dSStefano Zampini } 7714f347579bSStefano Zampini if (!crhs) { 77152a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 7716f347579bSStefano Zampini } 7717b0f5fe93SStefano Zampini } 77181ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 7719b0f5fe93SStefano Zampini 7720b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 7721b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 7722b0f5fe93SStefano Zampini 7723b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 77244f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 77254f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 77264f1b2e48SStefano Zampini } 7727b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 7728b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 7729b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7730b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7731b0f5fe93SStefano Zampini if (coarse_mat) { 7732b0f5fe93SStefano Zampini Vec nullv; 7733b0f5fe93SStefano Zampini PetscScalar *array,*array2; 7734b0f5fe93SStefano Zampini PetscInt nl; 7735b0f5fe93SStefano Zampini 7736b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 7737b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 7738b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7739b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 7740b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 7741b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 7742b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7743b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 7744b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 7745b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 7746b0f5fe93SStefano Zampini } 7747b0f5fe93SStefano Zampini } 7748b0f5fe93SStefano Zampini 7749b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 7750b0f5fe93SStefano Zampini PetscBool ispreonly; 7751b0f5fe93SStefano Zampini 7752b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7753b0f5fe93SStefano Zampini PetscBool isnull; 7754b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 7755bef83e63SStefano Zampini if (isnull) { 7756b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 7757b0f5fe93SStefano Zampini } 7758bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 7759b0f5fe93SStefano Zampini } 7760b0f5fe93SStefano Zampini /* setup coarse ksp */ 7761b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 7762cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 7763cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 77646e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 7765c8587f34SStefano Zampini KSP check_ksp; 77662b510759SStefano Zampini KSPType check_ksp_type; 7767c8587f34SStefano Zampini PC check_pc; 77686e683305SStefano Zampini Vec check_vec,coarse_vec; 77696a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 77702b510759SStefano Zampini PetscInt its; 77716e683305SStefano Zampini PetscBool compute_eigs; 77726e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 77736e683305SStefano Zampini PetscInt neigs; 77748e185a42SStefano Zampini const char *prefix; 7775c8587f34SStefano Zampini 77762b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 77776e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 7778422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 777923ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7780f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 7781e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 7782e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 7783e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 77842b510759SStefano Zampini if (ispreonly) { 77852b510759SStefano Zampini check_ksp_type = KSPPREONLY; 77866e683305SStefano Zampini compute_eigs = PETSC_FALSE; 77872b510759SStefano Zampini } else { 7788cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 77896e683305SStefano Zampini compute_eigs = PETSC_TRUE; 7790c8587f34SStefano Zampini } 7791c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 77926e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 77936e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 77946e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 7795a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 7796a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 7797a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 7798a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 7799c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 7800c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 7801c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 7802c8587f34SStefano Zampini /* create random vec */ 78032701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 7804c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 78056e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 7806c8587f34SStefano Zampini /* solve coarse problem */ 78076e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 7808cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 78096e683305SStefano Zampini if (compute_eigs) { 7810854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 7811854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 78126e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 78131ae86dd6SStefano Zampini if (neigs) { 78146e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 78156e683305SStefano Zampini lambda_min = eigs_r[0]; 78166e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 78172701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 78182701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 7819cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 7820cbcc2c2aSStefano Zampini } 7821c8587f34SStefano Zampini } 7822c8587f34SStefano Zampini } 78231ae86dd6SStefano Zampini } 7824cbcc2c2aSStefano Zampini 7825c8587f34SStefano Zampini /* check coarse problem residual error */ 78266e683305SStefano Zampini if (pcbddc->dbg_flag) { 78276e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 78286e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 78296e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 7830c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 78316e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 78326e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 7833779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 78346e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 78356e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 78366e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 78376e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 7838b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7839b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 7840b0f5fe93SStefano Zampini } 78416e683305SStefano Zampini if (compute_eigs) { 78426e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 7843b03ebc13SStefano Zampini KSPConvergedReason reason; 7844deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 7845c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 7846b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 78476e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 7848b03ebc13SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem eigenvalues (estimated with %d iterations of %s, conv reason %d): %1.6e %1.6e (%1.6e %1.6e)\n",its,check_ksp_type,reason,lambda_min,lambda_max,lambda_min_s,lambda_max_s);CHKERRQ(ierr); 78496e683305SStefano Zampini for (i=0;i<neigs;i++) { 78506e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 7851c8587f34SStefano Zampini } 78526e683305SStefano Zampini } 78536e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 78546e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 78556e683305SStefano Zampini } 7856e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 78572701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 7858c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 78596e683305SStefano Zampini if (compute_eigs) { 78606e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 78616e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 7862c8587f34SStefano Zampini } 78636e683305SStefano Zampini } 78646e683305SStefano Zampini } 7865bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 7866cbcc2c2aSStefano Zampini /* print additional info */ 7867cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 78686e683305SStefano Zampini /* waits until all processes reaches this point */ 78696e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 7870cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 7871cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7872cbcc2c2aSStefano Zampini } 7873cbcc2c2aSStefano Zampini 78742b510759SStefano Zampini /* free memory */ 7875fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 7876c8587f34SStefano Zampini PetscFunctionReturn(0); 7877c8587f34SStefano Zampini } 7878674ae819SStefano Zampini 7879f34684f1SStefano Zampini #undef __FUNCT__ 7880f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 7881f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 7882f34684f1SStefano Zampini { 7883f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7884f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 7885f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 7886dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 7887dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 788873be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 7889dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 7890f34684f1SStefano Zampini PetscErrorCode ierr; 7891f34684f1SStefano Zampini 7892f34684f1SStefano Zampini PetscFunctionBegin; 7893f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 78946c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 7895dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 78963bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 7897dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7898dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 78996583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 7900dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 7901dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 7902dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 79036c4ed002SBarry 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); 7904dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 7905dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7906dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 7907dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7908dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7909f34684f1SStefano Zampini 7910f34684f1SStefano Zampini /* check numbering */ 7911f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 7912019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 7913dc456d91SStefano Zampini PetscInt i; 7914b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 7915f34684f1SStefano Zampini 7916f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7917f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 7918f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 79191575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7920019a44ceSStefano Zampini /* counter */ 7921019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7922019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 7923019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7924019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7925019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7926019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7927f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 7928f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 7929727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 7930f34684f1SStefano Zampini } 7931f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7932f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7933f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7934e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7935e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7936e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7937e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7938f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7939019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7940f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7941019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 79422c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 794375c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 7944b9b85e73SStefano Zampini set_error = PETSC_TRUE; 79452c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 79462c66d082SStefano 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); 7947f34684f1SStefano Zampini } 7948f34684f1SStefano Zampini } 7949019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7950b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 7951f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7952f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7953f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 7954f34684f1SStefano Zampini } 7955f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7956f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7957e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7958e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7959f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 7960f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 7961b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 7962ca8b9ea9SStefano Zampini PetscInt *gidxs; 7963ca8b9ea9SStefano Zampini 7964ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 79653bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 7966f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 7967f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7968f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 7969f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 79704bc2dc4bSStefano 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); 7971f34684f1SStefano Zampini } 7972f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7973ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 7974f34684f1SStefano Zampini } 7975f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 79761575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7977302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 7978f34684f1SStefano Zampini } 79798bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 7980f34684f1SStefano Zampini /* get back data */ 7981f34684f1SStefano Zampini *coarse_size_n = coarse_size; 7982f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 7983674ae819SStefano Zampini PetscFunctionReturn(0); 7984674ae819SStefano Zampini } 7985674ae819SStefano Zampini 7986e456f2a8SStefano Zampini #undef __FUNCT__ 7987e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 7988a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 7989e456f2a8SStefano Zampini { 7990e456f2a8SStefano Zampini IS localis_t; 7991a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 7992e456f2a8SStefano Zampini PetscScalar *vals; 7993e456f2a8SStefano Zampini PetscErrorCode ierr; 7994e456f2a8SStefano Zampini 7995e456f2a8SStefano Zampini PetscFunctionBegin; 7996a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 7997e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 7998854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 7999e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 8000e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8001a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 8002a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 80031035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 8004a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 80051035eff8SStefano Zampini } 8006a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 8007e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8008e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 8009a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 8010a7dc3881SStefano Zampini /* now compute set in local ordering */ 8011a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8012a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8013a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8014a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 8015a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8016ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8017e456f2a8SStefano Zampini lsize++; 8018e456f2a8SStefano Zampini } 8019e456f2a8SStefano Zampini } 8020854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 8021a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8022ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8023e456f2a8SStefano Zampini idxs[lsize++] = i; 8024e456f2a8SStefano Zampini } 8025e456f2a8SStefano Zampini } 8026a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8027a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 8028e456f2a8SStefano Zampini *localis = localis_t; 8029e456f2a8SStefano Zampini PetscFunctionReturn(0); 8030e456f2a8SStefano Zampini } 8031906d46d4SStefano Zampini 8032b96c3477SStefano Zampini #undef __FUNCT__ 8033b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 803408122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 8035b96c3477SStefano Zampini { 8036a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8037b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8038b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 8039a64f4aa4SStefano Zampini Mat S_j; 8040b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 8041b96c3477SStefano Zampini PetscBool free_used_adj; 8042b96c3477SStefano Zampini PetscErrorCode ierr; 8043b96c3477SStefano Zampini 8044b96c3477SStefano Zampini PetscFunctionBegin; 8045b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 8046b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 804708122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 8048b96c3477SStefano Zampini used_xadj = NULL; 8049b96c3477SStefano Zampini used_adjncy = NULL; 8050b96c3477SStefano Zampini } else { 805108122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 805208122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 805308122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 805408122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 8055b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 8056b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 8057b96c3477SStefano Zampini } else { 80582fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 8059b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 8060b96c3477SStefano Zampini PetscInt nvtxs; 8061b96c3477SStefano Zampini 80622fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 80632fffb893SStefano Zampini if (flg_row) { 8064b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 8065b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 8066b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 8067b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 80682fffb893SStefano Zampini } else { 80692fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 80702fffb893SStefano Zampini used_xadj = NULL; 80712fffb893SStefano Zampini used_adjncy = NULL; 80722fffb893SStefano Zampini } 80732fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 8074b96c3477SStefano Zampini } 8075b96c3477SStefano Zampini } 8076d5574798SStefano Zampini 8077d5574798SStefano Zampini /* setup sub_schurs data */ 8078a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8079df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 8080df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 8081a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 808291af6908SStefano 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); 8083a64f4aa4SStefano Zampini } else { 80846816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 80854d7f8f00SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE; 8086a3df083aSStefano Zampini PetscInt benign_n; 808772b8c272SStefano Zampini Mat change = NULL; 80889d54b7f4SStefano Zampini Vec scaling = NULL; 808972b8c272SStefano Zampini IS change_primal = NULL; 8090a3df083aSStefano Zampini 80915feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 80925feab87aSStefano Zampini PetscInt n_vertices; 80935feab87aSStefano Zampini 80945feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 80952034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 80965feab87aSStefano Zampini } 809704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 809804708bb6SStefano Zampini if (!isseqaij) { 809904708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 810004708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 810104708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 810204708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 810304708bb6SStefano Zampini } else { 8104511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 810504708bb6SStefano Zampini } 810604708bb6SStefano Zampini } 8107a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 8108a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 8109ca92afb2SStefano Zampini } else { 8110a3df083aSStefano Zampini benign_n = 0; 8111ca92afb2SStefano Zampini } 8112b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 8113b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 8114b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 811572b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 811622db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 8117b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 811822db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 8119b7ab4a40SStefano Zampini } 8120b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 8121b7ab4a40SStefano 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 */ 8122b7ab4a40SStefano Zampini if (need_change) { 812388c03ad3SStefano Zampini PC_IS *pcisf; 812488c03ad3SStefano Zampini PC_BDDC *pcbddcf; 812588c03ad3SStefano Zampini PC pcf; 812688c03ad3SStefano Zampini 8127e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 812888c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 812988c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 813088c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 813188c03ad3SStefano Zampini /* hacks */ 813288c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 813372b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 813472b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 813572b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 813672b8c272SStefano Zampini pcisf->n = pcis->n; 813772b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 813888c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 813988c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 814088c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 814188c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 814288c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 814388c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 814472b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 814588c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 814688c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 814772b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 814872b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 814972b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 815072b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 815172b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 815288c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 815372b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 815488c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 815588c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 815688c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 815788c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 815888c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 815988c03ad3SStefano Zampini pcf->ops->destroy = NULL; 816088c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 816188c03ad3SStefano Zampini } 81629d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 816391af6908SStefano 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); 816472b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 816572b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 8166ca92afb2SStefano Zampini } 8167d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8168b96c3477SStefano Zampini 8169b96c3477SStefano Zampini /* free adjacency */ 8170b96c3477SStefano Zampini if (free_used_adj) { 8171b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 8172b96c3477SStefano Zampini } 8173b96c3477SStefano Zampini PetscFunctionReturn(0); 8174b96c3477SStefano Zampini } 8175b96c3477SStefano Zampini 8176b96c3477SStefano Zampini #undef __FUNCT__ 8177b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 817808122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 8179b96c3477SStefano Zampini { 8180b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8181b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8182b96c3477SStefano Zampini PCBDDCGraph graph; 8183b96c3477SStefano Zampini PetscErrorCode ierr; 8184b96c3477SStefano Zampini 8185b96c3477SStefano Zampini PetscFunctionBegin; 8186b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 818708122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 81883301b35fSStefano Zampini IS verticesIS,verticescomm; 81893301b35fSStefano Zampini PetscInt vsize,*idxs; 8190b96c3477SStefano Zampini 8191b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 81923301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 81933301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 81943301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 81953301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 8196c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 8197b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 8198be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 8199441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 82003301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 8201b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 8202b96c3477SStefano Zampini } else { 8203b96c3477SStefano Zampini graph = pcbddc->mat_graph; 8204b96c3477SStefano Zampini } 8205e4d548c7SStefano Zampini /* print some info */ 82065c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 8207e4d548c7SStefano Zampini IS vertices; 8208e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 8209c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 8210e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8211e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 8212e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8213e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 8214e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 8215e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 8216e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 8217e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8218e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8219c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8220e4d548c7SStefano Zampini } 8221b96c3477SStefano Zampini 8222b96c3477SStefano Zampini /* sub_schurs init */ 8223b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 8224b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 8225b334f244SStefano Zampini } 82268b6046baSStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 8227a64f4aa4SStefano Zampini 8228b96c3477SStefano Zampini /* free graph struct */ 822908122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 8230b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 8231b96c3477SStefano Zampini } 8232b96c3477SStefano Zampini PetscFunctionReturn(0); 8233b96c3477SStefano Zampini } 8234fa34dd3eSStefano Zampini 8235fa34dd3eSStefano Zampini #undef __FUNCT__ 8236fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 8237fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 8238fa34dd3eSStefano Zampini { 8239fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8240fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8241fa34dd3eSStefano Zampini PetscErrorCode ierr; 8242fa34dd3eSStefano Zampini 8243fa34dd3eSStefano Zampini PetscFunctionBegin; 8244fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 8245fa34dd3eSStefano Zampini IS zerodiag = NULL; 82464f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 8247fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 82484f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 824975c01103SStefano Zampini PetscReal norm; 8250fa34dd3eSStefano Zampini PetscInt i; 8251fa34dd3eSStefano Zampini 8252fa34dd3eSStefano Zampini /* B0 and B0_B */ 8253fa34dd3eSStefano Zampini if (zerodiag) { 8254fa34dd3eSStefano Zampini IS dummy; 8255fa34dd3eSStefano Zampini 82564f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 82574f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 8258fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 8259fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 8260fa34dd3eSStefano Zampini } 8261fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 8262fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 8263fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 8264fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8265fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8266fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8267fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8268fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 8269fa34dd3eSStefano Zampini /* S_j */ 8270fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8271fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 8272fa34dd3eSStefano Zampini 8273fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 8274fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 8275fa34dd3eSStefano Zampini /* continuous in primal space */ 8276fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 8277fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8278fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8279fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 82804f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 82814f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 8282fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8283fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8284fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8285fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8286fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8287fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8288fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 8289fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 8290fa34dd3eSStefano Zampini 8291fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 8292fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 8293fa34dd3eSStefano Zampini /* local with Schur */ 8294fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 8295fa34dd3eSStefano Zampini if (zerodiag) { 8296fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 82974f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 8298fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8299fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 8300fa34dd3eSStefano Zampini } 8301fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 8302fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8303fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8304fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8305fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8306fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 8307fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8308fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8309fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 8310fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8311fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8312fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8313fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8314fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8315fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 8316fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 8317fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8318fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8319fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8320fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8321fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8322fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8323fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 8324fa34dd3eSStefano Zampini if (zerodiag) { 8325fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 8326fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 83274f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 8328fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8329fa34dd3eSStefano Zampini } 8330fa34dd3eSStefano Zampini /* BDDC */ 8331fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 8332fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 8333fa34dd3eSStefano Zampini 8334fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 8335fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 8336fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 8337fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 83384f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 83394f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 8340fa34dd3eSStefano Zampini } 83414f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 8342fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 8343fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 8344fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 8345fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8346fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 8347fa34dd3eSStefano Zampini } 8348fa34dd3eSStefano Zampini PetscFunctionReturn(0); 8349fa34dd3eSStefano Zampini } 83501e0482f5SStefano Zampini 83511e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 83521e0482f5SStefano Zampini #undef __FUNCT__ 83531e0482f5SStefano Zampini #define __FUNCT__ "MatMPIAIJRestrict" 83541e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 83551e0482f5SStefano Zampini { 83561e0482f5SStefano Zampini Mat At; 83571e0482f5SStefano Zampini IS rows; 83581e0482f5SStefano Zampini PetscInt rst,ren; 83591e0482f5SStefano Zampini PetscErrorCode ierr; 83601e0482f5SStefano Zampini PetscLayout rmap; 83611e0482f5SStefano Zampini 83621e0482f5SStefano Zampini PetscFunctionBegin; 83631e0482f5SStefano Zampini rst = ren = 0; 83641e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 83651e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 83661e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 83671e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 83681e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 83691e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 83701e0482f5SStefano Zampini } 8371e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 83721e0482f5SStefano Zampini ierr = MatGetSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 83731e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 83741e0482f5SStefano Zampini 83751e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 83761e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 83771e0482f5SStefano Zampini IS from,to; 83781e0482f5SStefano Zampini Vec gvec; 83791e0482f5SStefano Zampini PetscInt lsize; 83801e0482f5SStefano Zampini 83811e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 83821e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 83831e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 83841e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 83851e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 83861e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 83871e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 83881e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 83891e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 83901e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 83911e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 83921e0482f5SStefano Zampini b->A = a->A; 83931e0482f5SStefano Zampini b->B = a->B; 83941e0482f5SStefano Zampini 83951e0482f5SStefano Zampini b->donotstash = a->donotstash; 83961e0482f5SStefano Zampini b->roworiented = a->roworiented; 83971e0482f5SStefano Zampini b->rowindices = 0; 83981e0482f5SStefano Zampini b->rowvalues = 0; 83991e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 84001e0482f5SStefano Zampini 84011e0482f5SStefano Zampini (*B)->rmap = rmap; 84021e0482f5SStefano Zampini (*B)->factortype = A->factortype; 84031e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 84041e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 84051e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 84061e0482f5SStefano Zampini 84071e0482f5SStefano Zampini if (a->colmap) { 84081e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 84091e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 84101e0482f5SStefano Zampini #else 84111e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 84121e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 84131e0482f5SStefano Zampini ierr = PetscMemcpy(b->colmap,a->colmap,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 84141e0482f5SStefano Zampini #endif 84151e0482f5SStefano Zampini } else b->colmap = 0; 84161e0482f5SStefano Zampini if (a->garray) { 84171e0482f5SStefano Zampini PetscInt len; 84181e0482f5SStefano Zampini len = a->B->cmap->n; 84191e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 84201e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 84211e0482f5SStefano Zampini if (len) { ierr = PetscMemcpy(b->garray,a->garray,len*sizeof(PetscInt));CHKERRQ(ierr); } 84221e0482f5SStefano Zampini } else b->garray = 0; 84231e0482f5SStefano Zampini 84241e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 84251e0482f5SStefano Zampini b->lvec = a->lvec; 84261e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 84271e0482f5SStefano Zampini 84281e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 84291e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 84301e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 84311e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 84321e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 84331e0482f5SStefano Zampini ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 84341e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 84351e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 84361e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 84371e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 84381e0482f5SStefano Zampini } 84391e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 84401e0482f5SStefano Zampini PetscFunctionReturn(0); 84411e0482f5SStefano Zampini } 8442