11cf9b237SStefano Zampini #include <../src/mat/impls/aij/seq/aij.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> 3ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 4837cedc9SStefano Zampini #include <../src/mat/impls/dense/seq/dense.h> 5c80a6c00SStefano Zampini #include <petscdmplex.h> 6674ae819SStefano Zampini #include <petscblaslapack.h> 7daf8a457SStefano Zampini #include <petsc/private/sfimpl.h> 8c80a6c00SStefano Zampini #include <petsc/private/dmpleximpl.h> 97620a527SStefano Zampini #include <petscdmda.h> 10674ae819SStefano Zampini 111e0482f5SStefano Zampini static PetscErrorCode MatMPIAIJRestrict(Mat,MPI_Comm,Mat*); 121e0482f5SStefano Zampini 13f498cd09SStefano Zampini /* if range is true, it returns B s.t. span{B} = range(A) 14f498cd09SStefano Zampini if range is false, it returns B s.t. range(B) _|_ range(A) */ 15f498cd09SStefano Zampini PetscErrorCode MatDenseOrthogonalRangeOrComplement(Mat A, PetscBool range, PetscInt lw, PetscScalar *work, PetscReal *rwork, Mat *B) 16a13144ffSStefano Zampini { 17a13144ffSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 18a13144ffSStefano Zampini PetscScalar *uwork,*data,*U, ds = 0.; 19a13144ffSStefano Zampini PetscReal *sing; 20a13144ffSStefano Zampini PetscBLASInt bM,bN,lwork,lierr,di = 1; 21a13144ffSStefano Zampini PetscInt ulw,i,nr,nc,n; 22a13144ffSStefano Zampini PetscErrorCode ierr; 23a13144ffSStefano Zampini 24a13144ffSStefano Zampini PetscFunctionBegin; 25a13144ffSStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 26a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"LAPACK _GESVD not available"); 27614dbb09SStefano Zampini #else 28a13144ffSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 29a13144ffSStefano Zampini if (!nr || !nc) PetscFunctionReturn(0); 30a13144ffSStefano Zampini 31a13144ffSStefano Zampini /* workspace */ 32a13144ffSStefano Zampini if (!work) { 33a13144ffSStefano Zampini ulw = PetscMax(PetscMax(1,5*PetscMin(nr,nc)),3*PetscMin(nr,nc)+PetscMax(nr,nc)); 34f913dca9SStefano Zampini ierr = PetscMalloc1(ulw,&uwork);CHKERRQ(ierr); 35a13144ffSStefano Zampini } else { 36a13144ffSStefano Zampini ulw = lw; 37a13144ffSStefano Zampini uwork = work; 38a13144ffSStefano Zampini } 39a13144ffSStefano Zampini n = PetscMin(nr,nc); 40a13144ffSStefano Zampini if (!rwork) { 41a13144ffSStefano Zampini ierr = PetscMalloc1(n,&sing);CHKERRQ(ierr); 42a13144ffSStefano Zampini } else { 43a13144ffSStefano Zampini sing = rwork; 44a13144ffSStefano Zampini } 45a13144ffSStefano Zampini 46a13144ffSStefano Zampini /* SVD */ 47a13144ffSStefano Zampini ierr = PetscMalloc1(nr*nr,&U);CHKERRQ(ierr); 48a13144ffSStefano Zampini ierr = PetscBLASIntCast(nr,&bM);CHKERRQ(ierr); 49a13144ffSStefano Zampini ierr = PetscBLASIntCast(nc,&bN);CHKERRQ(ierr); 50a13144ffSStefano Zampini ierr = PetscBLASIntCast(ulw,&lwork);CHKERRQ(ierr); 51a13144ffSStefano Zampini ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); 52a13144ffSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 53a13144ffSStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,&lierr)); 54a13144ffSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 55a13144ffSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 56a13144ffSStefano Zampini ierr = MatDenseRestoreArray(A,&data);CHKERRQ(ierr); 57a13144ffSStefano Zampini for (i=0;i<n;i++) if (sing[i] < PETSC_SMALL) break; 58a13144ffSStefano Zampini if (!rwork) { 59a13144ffSStefano Zampini ierr = PetscFree(sing);CHKERRQ(ierr); 60a13144ffSStefano Zampini } 61a13144ffSStefano Zampini if (!work) { 62a13144ffSStefano Zampini ierr = PetscFree(uwork);CHKERRQ(ierr); 63a13144ffSStefano Zampini } 64a13144ffSStefano Zampini /* create B */ 65f498cd09SStefano Zampini if (!range) { 66a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 67a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 68*580bdb30SBarry Smith ierr = PetscArraycpy(data,U+nr*i,(nr-i)*nr);CHKERRQ(ierr); 69f498cd09SStefano Zampini } else { 70f498cd09SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,i,NULL,B);CHKERRQ(ierr); 71f498cd09SStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 72*580bdb30SBarry Smith ierr = PetscArraycpy(data,U,i*nr);CHKERRQ(ierr); 73f498cd09SStefano Zampini } 74a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 75a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 76614dbb09SStefano Zampini #endif 77614dbb09SStefano Zampini #else /* PETSC_USE_COMPLEX */ 78a13144ffSStefano Zampini PetscFunctionBegin; 79a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for complexes"); 80a13144ffSStefano Zampini #endif 81a13144ffSStefano Zampini PetscFunctionReturn(0); 82a13144ffSStefano Zampini } 83a13144ffSStefano Zampini 841e0482f5SStefano Zampini /* TODO REMOVE */ 851e0482f5SStefano Zampini #if defined(PRINT_GDET) 861e0482f5SStefano Zampini static int inc = 0; 871e0482f5SStefano Zampini static int lev = 0; 881e0482f5SStefano Zampini #endif 891e0482f5SStefano Zampini 901e0482f5SStefano Zampini PetscErrorCode PCBDDCComputeNedelecChangeEdge(Mat lG, IS edge, IS extrow, IS extcol, IS corners, Mat* Gins, Mat* GKins, PetscScalar cvals[2], PetscScalar *work, PetscReal *rwork) 91a13144ffSStefano Zampini { 92a13144ffSStefano Zampini PetscErrorCode ierr; 93a13144ffSStefano Zampini Mat GE,GEd; 94a13144ffSStefano Zampini PetscInt rsize,csize,esize; 95a13144ffSStefano Zampini PetscScalar *ptr; 96a13144ffSStefano Zampini 97a13144ffSStefano Zampini PetscFunctionBegin; 98a13144ffSStefano Zampini ierr = ISGetSize(edge,&esize);CHKERRQ(ierr); 99c3c0e390SStefano Zampini if (!esize) PetscFunctionReturn(0); 100a13144ffSStefano Zampini ierr = ISGetSize(extrow,&rsize);CHKERRQ(ierr); 101a13144ffSStefano Zampini ierr = ISGetSize(extcol,&csize);CHKERRQ(ierr); 102a13144ffSStefano Zampini 103a13144ffSStefano Zampini /* gradients */ 104a13144ffSStefano Zampini ptr = work + 5*esize; 1057dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,extrow,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 106a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,rsize,csize,ptr,Gins);CHKERRQ(ierr); 107a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,Gins);CHKERRQ(ierr); 108a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 109a13144ffSStefano Zampini 110a13144ffSStefano Zampini /* constants */ 111a13144ffSStefano Zampini ptr += rsize*csize; 112a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,esize,csize,ptr,&GEd);CHKERRQ(ierr); 1137dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,edge,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 114a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,&GEd);CHKERRQ(ierr); 115a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 116f498cd09SStefano Zampini ierr = MatDenseOrthogonalRangeOrComplement(GEd,PETSC_FALSE,5*esize,work,rwork,GKins);CHKERRQ(ierr); 117a13144ffSStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1181e0482f5SStefano Zampini 1191e0482f5SStefano Zampini if (corners) { 1201e0482f5SStefano Zampini Mat GEc; 1211683a169SBarry Smith const PetscScalar *vals; 1221683a169SBarry Smith PetscScalar v; 1231e0482f5SStefano Zampini 1247dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,edge,corners,MAT_INITIAL_MATRIX,&GEc);CHKERRQ(ierr); 1251e0482f5SStefano Zampini ierr = MatTransposeMatMult(GEc,*GKins,MAT_INITIAL_MATRIX,1.0,&GEd);CHKERRQ(ierr); 1261683a169SBarry Smith ierr = MatDenseGetArrayRead(GEd,&vals);CHKERRQ(ierr); 127637e8532SStefano Zampini /* v = PetscAbsScalar(vals[0]) */; 128637e8532SStefano Zampini v = 1.; 1291e0482f5SStefano Zampini cvals[0] = vals[0]/v; 1301e0482f5SStefano Zampini cvals[1] = vals[1]/v; 1311683a169SBarry Smith ierr = MatDenseRestoreArrayRead(GEd,&vals);CHKERRQ(ierr); 1321e0482f5SStefano Zampini ierr = MatScale(*GKins,1./v);CHKERRQ(ierr); 1331e0482f5SStefano Zampini #if defined(PRINT_GDET) 1341e0482f5SStefano Zampini { 1351e0482f5SStefano Zampini PetscViewer viewer; 1361e0482f5SStefano Zampini char filename[256]; 1371e0482f5SStefano Zampini sprintf(filename,"Gdet_l%d_r%d_cc%d.m",lev,PetscGlobalRank,inc++); 1381e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1391e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1401e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEc,"GEc");CHKERRQ(ierr); 1411e0482f5SStefano Zampini ierr = MatView(GEc,viewer);CHKERRQ(ierr); 1421e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)(*GKins),"GK");CHKERRQ(ierr); 1431e0482f5SStefano Zampini ierr = MatView(*GKins,viewer);CHKERRQ(ierr); 1441e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEd,"Gproj");CHKERRQ(ierr); 1451e0482f5SStefano Zampini ierr = MatView(GEd,viewer);CHKERRQ(ierr); 1461e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1471e0482f5SStefano Zampini } 1481e0482f5SStefano Zampini #endif 1491e0482f5SStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1501e0482f5SStefano Zampini ierr = MatDestroy(&GEc);CHKERRQ(ierr); 1511e0482f5SStefano Zampini } 1521e0482f5SStefano Zampini 153a13144ffSStefano Zampini PetscFunctionReturn(0); 154a13144ffSStefano Zampini } 155a13144ffSStefano Zampini 156a13144ffSStefano Zampini PetscErrorCode PCBDDCNedelecSupport(PC pc) 157a13144ffSStefano Zampini { 158a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 159a13144ffSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1600569b399SStefano Zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe,lGinit; 161eee23b56SStefano Zampini Vec tvec; 162a13144ffSStefano Zampini PetscSF sfv; 1631e0482f5SStefano Zampini ISLocalToGlobalMapping el2g,vl2g,fl2g,al2g; 164a13144ffSStefano Zampini MPI_Comm comm; 165c2151214SStefano Zampini IS lned,primals,allprimals,nedfieldlocal; 166c2151214SStefano Zampini IS *eedges,*extrows,*extcols,*alleedges; 1677d871cd7SStefano Zampini PetscBT btv,bte,btvc,btb,btbd,btvcand,btvi,btee,bter; 168a13144ffSStefano Zampini PetscScalar *vals,*work; 169a13144ffSStefano Zampini PetscReal *rwork; 170a13144ffSStefano Zampini const PetscInt *idxs,*ii,*jj,*iit,*jjt; 1711e0482f5SStefano Zampini PetscInt ne,nv,Lv,order,n,field; 172a13144ffSStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 173eee23b56SStefano Zampini PetscInt i,j,extmem,cum,maxsize,nee; 174b03ebc13SStefano Zampini PetscInt *extrow,*extrowcum,*marks,*vmarks,*gidxs; 175a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 176b03ebc13SStefano Zampini PetscInt *corners,*cedges; 177637e8532SStefano Zampini PetscInt *ecount,**eneighs,*vcount,**vneighs; 178b03ebc13SStefano Zampini #if defined(PETSC_USE_DEBUG) 179b03ebc13SStefano Zampini PetscInt *emarks; 180b03ebc13SStefano Zampini #endif 181213b8bfaSStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,global,singular,setprimal; 182a13144ffSStefano Zampini PetscErrorCode ierr; 183a13144ffSStefano Zampini 184a13144ffSStefano Zampini PetscFunctionBegin; 185213b8bfaSStefano Zampini /* If the discrete gradient is defined for a subset of dofs and global is true, 186213b8bfaSStefano Zampini it assumes G is given in global ordering for all the dofs. 187213b8bfaSStefano Zampini Otherwise, the ordering is global for the Nedelec field */ 188213b8bfaSStefano Zampini order = pcbddc->nedorder; 189213b8bfaSStefano Zampini conforming = pcbddc->conforming; 190213b8bfaSStefano Zampini field = pcbddc->nedfield; 191213b8bfaSStefano Zampini global = pcbddc->nedglobal; 192213b8bfaSStefano Zampini setprimal = PETSC_FALSE; 193a13144ffSStefano Zampini print = PETSC_FALSE; 194213b8bfaSStefano Zampini singular = PETSC_FALSE; 195a13144ffSStefano Zampini 196213b8bfaSStefano Zampini /* Command line customization */ 197213b8bfaSStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC Nedelec options","PC");CHKERRQ(ierr); 198213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_field_primal","All edge dofs set as primals: Toselli's algorithm C",NULL,setprimal,&setprimal,NULL);CHKERRQ(ierr); 199213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_singular","Infer nullspace from discrete gradient",NULL,singular,&singular,NULL);CHKERRQ(ierr); 200213b8bfaSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_nedelec_order","Test variable order code (to be removed)",NULL,order,&order,NULL);CHKERRQ(ierr); 201213b8bfaSStefano Zampini /* print debug info TODO: to be removed */ 202213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_print","Print debug info",NULL,print,&print,NULL);CHKERRQ(ierr); 203213b8bfaSStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 204213b8bfaSStefano Zampini 205213b8bfaSStefano Zampini /* Return if there are no edges in the decomposition and the problem is not singular */ 2061e0482f5SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&al2g,NULL);CHKERRQ(ierr); 2071e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(al2g,&n);CHKERRQ(ierr); 208213b8bfaSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 209213b8bfaSStefano Zampini if (!singular) { 210a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 211a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 212c2151214SStefano Zampini for (i=0;i<n;i++) { 213a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 214a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 215a13144ffSStefano Zampini break; 216a13144ffSStefano Zampini } 217a13144ffSStefano Zampini } 218a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 219a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 220a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 221213b8bfaSStefano Zampini } 222a13144ffSStefano Zampini 223213b8bfaSStefano Zampini /* Get Nedelec field */ 2246080607fSStefano Zampini if (pcbddc->n_ISForDofsLocal && field >= pcbddc->n_ISForDofsLocal) SETERRQ2(comm,PETSC_ERR_USER,"Invalid field for Nedelec %D: number of fields is %D",field,pcbddc->n_ISForDofsLocal); 225213b8bfaSStefano Zampini if (pcbddc->n_ISForDofsLocal && field >= 0) { 226c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 227c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 228c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 229213b8bfaSStefano Zampini } else if (!pcbddc->n_ISForDofsLocal && field != PETSC_DECIDE) { 230213b8bfaSStefano Zampini ne = n; 231213b8bfaSStefano Zampini nedfieldlocal = NULL; 232213b8bfaSStefano Zampini global = PETSC_TRUE; 233213b8bfaSStefano Zampini } else if (field == PETSC_DECIDE) { 234213b8bfaSStefano Zampini PetscInt rst,ren,*idx; 235213b8bfaSStefano Zampini 236*580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,n);CHKERRQ(ierr); 237*580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,pc->pmat->rmap->n);CHKERRQ(ierr); 238213b8bfaSStefano Zampini ierr = MatGetOwnershipRange(pcbddc->discretegradient,&rst,&ren);CHKERRQ(ierr); 239213b8bfaSStefano Zampini for (i=rst;i<ren;i++) { 240213b8bfaSStefano Zampini PetscInt nc; 241213b8bfaSStefano Zampini 242213b8bfaSStefano Zampini ierr = MatGetRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 243213b8bfaSStefano Zampini if (nc > 1) matis->sf_rootdata[i-rst] = 1; 244213b8bfaSStefano Zampini ierr = MatRestoreRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 245213b8bfaSStefano Zampini } 246213b8bfaSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 247213b8bfaSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 248213b8bfaSStefano Zampini ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr); 249213b8bfaSStefano Zampini for (i=0,ne=0;i<n;i++) if (matis->sf_leafdata[i]) idx[ne++] = i; 250213b8bfaSStefano Zampini ierr = ISCreateGeneral(comm,ne,idx,PETSC_OWN_POINTER,&nedfieldlocal);CHKERRQ(ierr); 251213b8bfaSStefano Zampini } else { 252213b8bfaSStefano Zampini SETERRQ(comm,PETSC_ERR_USER,"When multiple fields are present, the Nedelec field has to be specified"); 253213b8bfaSStefano Zampini } 254213b8bfaSStefano Zampini 255213b8bfaSStefano Zampini /* Sanity checks */ 256213b8bfaSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 257213b8bfaSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 2586080607fSStefano Zampini if (order && ne%order) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"The number of local edge dofs %D it's not a multiple of the order %D",ne,order); 259213b8bfaSStefano Zampini 260213b8bfaSStefano Zampini /* Just set primal dofs and return */ 2611e0482f5SStefano Zampini if (setprimal) { 262eee23b56SStefano Zampini IS enedfieldlocal; 263eee23b56SStefano Zampini PetscInt *eidxs; 264eee23b56SStefano Zampini 265eee23b56SStefano Zampini ierr = PetscMalloc1(ne,&eidxs);CHKERRQ(ierr); 266eee23b56SStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 267213b8bfaSStefano Zampini if (nedfieldlocal) { 268213b8bfaSStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 269eee23b56SStefano Zampini for (i=0,cum=0;i<ne;i++) { 270eee23b56SStefano Zampini if (PetscRealPart(vals[idxs[i]]) > 2.) { 271eee23b56SStefano Zampini eidxs[cum++] = idxs[i]; 272eee23b56SStefano Zampini } 273eee23b56SStefano Zampini } 274eee23b56SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 275213b8bfaSStefano Zampini } else { 276213b8bfaSStefano Zampini for (i=0,cum=0;i<ne;i++) { 277213b8bfaSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 278213b8bfaSStefano Zampini eidxs[cum++] = i; 279213b8bfaSStefano Zampini } 280213b8bfaSStefano Zampini } 281213b8bfaSStefano Zampini } 282213b8bfaSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 283eee23b56SStefano Zampini ierr = ISCreateGeneral(comm,cum,eidxs,PETSC_COPY_VALUES,&enedfieldlocal);CHKERRQ(ierr); 284eee23b56SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,enedfieldlocal);CHKERRQ(ierr); 285eee23b56SStefano Zampini ierr = PetscFree(eidxs);CHKERRQ(ierr); 2861e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 287eee23b56SStefano Zampini ierr = ISDestroy(&enedfieldlocal);CHKERRQ(ierr); 2881e0482f5SStefano Zampini PetscFunctionReturn(0); 2891e0482f5SStefano Zampini } 290a13144ffSStefano Zampini 291213b8bfaSStefano Zampini /* Compute some l2g maps */ 292213b8bfaSStefano Zampini if (nedfieldlocal) { 293c2151214SStefano Zampini IS is; 294c2151214SStefano Zampini 295c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 296c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 2971e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering for the whole dofs*/ 2981e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(al2g,nedfieldlocal,&is);CHKERRQ(ierr); 2991e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&al2g);CHKERRQ(ierr); 3001e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering (for Nedelec only) */ 3011e0482f5SStefano Zampini if (global) { 3021e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3031e0482f5SStefano Zampini el2g = al2g; 3041e0482f5SStefano Zampini } else { 3051e0482f5SStefano Zampini IS gis; 3061e0482f5SStefano Zampini 3071e0482f5SStefano Zampini ierr = ISRenumber(is,NULL,NULL,&gis);CHKERRQ(ierr); 3081e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gis,&el2g);CHKERRQ(ierr); 3091e0482f5SStefano Zampini ierr = ISDestroy(&gis);CHKERRQ(ierr); 3101e0482f5SStefano Zampini } 311c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 312c2151214SStefano Zampini } else { 3131e0482f5SStefano Zampini /* restore default */ 3141e0482f5SStefano Zampini pcbddc->nedfield = -1; 3151e0482f5SStefano Zampini /* one ref for the destruction of al2g, one for el2g */ 3161e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3171e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3181e0482f5SStefano Zampini el2g = al2g; 319c2151214SStefano Zampini fl2g = NULL; 320c2151214SStefano Zampini } 321a13144ffSStefano Zampini 322213b8bfaSStefano Zampini /* Start communication to drop connections for interior edges (for cc analysis only) */ 323*580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,n);CHKERRQ(ierr); 324*580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,pc->pmat->rmap->n);CHKERRQ(ierr); 325c2151214SStefano Zampini if (nedfieldlocal) { 326c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 327c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 328c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 329c2151214SStefano Zampini } else { 330c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 331c2151214SStefano Zampini } 332c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 333c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 334213b8bfaSStefano Zampini 335213b8bfaSStefano Zampini if (!singular) { /* drop connections with interior edges to avoid unneeded communications and memory movements */ 336213b8bfaSStefano Zampini ierr = MatDuplicate(pcbddc->discretegradient,MAT_COPY_VALUES,&G);CHKERRQ(ierr); 337213b8bfaSStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 3381e0482f5SStefano Zampini if (global) { 3391e0482f5SStefano Zampini PetscInt rst; 3401e0482f5SStefano Zampini 341c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 342c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 343c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 344c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 345c2151214SStefano Zampini } 346c2151214SStefano Zampini } 347a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 348c2151214SStefano Zampini ierr = MatZeroRows(G,cum,matis->sf_rootdata,0.,NULL,NULL);CHKERRQ(ierr); 3491e0482f5SStefano Zampini } else { 3501e0482f5SStefano Zampini PetscInt *tbz; 3511e0482f5SStefano Zampini 3521e0482f5SStefano Zampini ierr = PetscMalloc1(ne,&tbz);CHKERRQ(ierr); 3531e0482f5SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3541e0482f5SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3551e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3561e0482f5SStefano Zampini for (i=0,cum=0;i<ne;i++) 3571e0482f5SStefano Zampini if (matis->sf_leafdata[idxs[i]] == 1) 3581e0482f5SStefano Zampini tbz[cum++] = i; 3591e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3601e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApply(el2g,cum,tbz,tbz);CHKERRQ(ierr); 3611e0482f5SStefano Zampini ierr = MatZeroRows(G,cum,tbz,0.,NULL,NULL);CHKERRQ(ierr); 3621e0482f5SStefano Zampini ierr = PetscFree(tbz);CHKERRQ(ierr); 3631e0482f5SStefano Zampini } 364213b8bfaSStefano Zampini } else { /* we need the entire G to infer the nullspace */ 365213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->discretegradient);CHKERRQ(ierr); 366213b8bfaSStefano Zampini G = pcbddc->discretegradient; 367213b8bfaSStefano Zampini } 368a13144ffSStefano Zampini 369a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 370a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 371a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 3727dae84e0SHong Zhang ierr = MatCreateSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 373a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 374a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 375a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 376a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 377a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 378a13144ffSStefano Zampini 379213b8bfaSStefano Zampini /* SF for nodal dofs communications */ 380c2151214SStefano Zampini ierr = MatGetLocalSize(G,NULL,&Lv);CHKERRQ(ierr); 381a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 382a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 383a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 384a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 385a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 386a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 387a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 388213b8bfaSStefano Zampini i = singular ? 2 : 1; 389213b8bfaSStefano Zampini ierr = PetscMalloc2(i*nv,&sfvleaves,i*Lv,&sfvroots);CHKERRQ(ierr); 390a13144ffSStefano Zampini 3911e0482f5SStefano Zampini /* Destroy temporary G created in MATIS format and modified G */ 392213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 393a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 394213b8bfaSStefano Zampini ierr = MatDestroy(&G);CHKERRQ(ierr); 395a13144ffSStefano Zampini 396213b8bfaSStefano Zampini if (print) { 397213b8bfaSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 398213b8bfaSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 399213b8bfaSStefano Zampini } 400213b8bfaSStefano Zampini 401213b8bfaSStefano Zampini /* Save lG for values insertion in change of basis */ 4020569b399SStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGinit);CHKERRQ(ierr); 4030569b399SStefano Zampini 404a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 4054e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 4064e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 407a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 408a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 409a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 4107d871cd7SStefano Zampini ierr = PetscBTCreate(ne,&btbd);CHKERRQ(ierr); 411c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 412a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 413a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 414a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 415c2151214SStefano Zampini IS is; 416c2151214SStefano Zampini 417c2151214SStefano Zampini if (fl2g) { 418c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 419c2151214SStefano Zampini } else { 420c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 421c2151214SStefano Zampini } 422c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 423c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 424a13144ffSStefano Zampini for (i=0;i<cum;i++) { 425a13144ffSStefano Zampini if (idxs[i] >= 0) { 426a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 4277d871cd7SStefano Zampini ierr = PetscBTSet(btbd,idxs[i]);CHKERRQ(ierr); 428a13144ffSStefano Zampini } 429a13144ffSStefano Zampini } 430c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 431c2151214SStefano Zampini if (fl2g) { 432c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 433c2151214SStefano Zampini } 434a13144ffSStefano Zampini } 435a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 436c2151214SStefano Zampini IS is; 437c2151214SStefano Zampini 438c2151214SStefano Zampini if (fl2g) { 439c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 440c2151214SStefano Zampini } else { 441c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 442c2151214SStefano Zampini } 443c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 444c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 445a13144ffSStefano Zampini for (i=0;i<cum;i++) { 446a13144ffSStefano Zampini if (idxs[i] >= 0) { 447a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 448a13144ffSStefano Zampini } 449a13144ffSStefano Zampini } 450c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 451c2151214SStefano Zampini if (fl2g) { 452c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 453a13144ffSStefano Zampini } 454c2151214SStefano Zampini } 455c2151214SStefano Zampini 456213b8bfaSStefano Zampini /* Count neighs per dof */ 457b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(el2g,NULL,&ecount,&eneighs);CHKERRQ(ierr); 458b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(vl2g,NULL,&vcount,&vneighs);CHKERRQ(ierr); 459637e8532SStefano Zampini 4607d871cd7SStefano Zampini /* need to remove coarse faces' dofs and coarse edges' dirichlet dofs 4617d871cd7SStefano Zampini for proper detection of coarse edges' endpoints */ 46262b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 46362b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 464b63b1311SStefano Zampini if ((ecount[i] > 2 && !PetscBTLookup(btbd,i)) || (ecount[i] == 2 && PetscBTLookup(btb,i))) { 46562b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 46662b0c6f7SStefano Zampini } 46762b0c6f7SStefano Zampini } 468637e8532SStefano Zampini ierr = PetscMalloc1(ne,&marks);CHKERRQ(ierr); 46962b0c6f7SStefano Zampini if (!conforming) { 47062b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 47162b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 47262b0c6f7SStefano Zampini } 4734e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 474dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 47562b0c6f7SStefano Zampini cum = 0; 476a13144ffSStefano Zampini for (i=0;i<ne;i++) { 477dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 47862b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 479a13144ffSStefano Zampini marks[cum++] = i; 480dec27d64SStefano Zampini continue; 481dec27d64SStefano Zampini } 482dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 48362b0c6f7SStefano Zampini if (!conforming) { 48462b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 485a13144ffSStefano Zampini marks[cum++] = i; 486a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 487a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 488a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 489a13144ffSStefano Zampini } 49062b0c6f7SStefano Zampini } else { 49162b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 49262b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 49362b0c6f7SStefano Zampini - at most 2 endpoints 49462b0c6f7SStefano Zampini - order-1 interior nodal dofs 49562b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 49662b0c6f7SStefano Zampini */ 49762b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 49862b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 49962b0c6f7SStefano Zampini PetscInt v = jj[j],k; 50062b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 50162b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 50262b0c6f7SStefano Zampini if (nconn > order) ends++; 50362b0c6f7SStefano Zampini else if (nconn == order) ints++; 50462b0c6f7SStefano Zampini else undef++; 50562b0c6f7SStefano Zampini } 50662b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 50762b0c6f7SStefano Zampini marks[cum++] = i; 50862b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 50962b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 51062b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 51162b0c6f7SStefano Zampini } 51262b0c6f7SStefano Zampini } 51362b0c6f7SStefano Zampini } 514a13144ffSStefano Zampini } 515dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 516dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 517dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 518dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 519a13144ffSStefano Zampini } 520dec27d64SStefano Zampini } 52162b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 522dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 5234e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 52462b0c6f7SStefano Zampini if (!conforming) { 52562b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 52662b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 52762b0c6f7SStefano Zampini } 5284e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 529637e8532SStefano Zampini 530b03ebc13SStefano Zampini /* identify splitpoints and corner candidates */ 5314e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 532a13144ffSStefano Zampini if (print) { 5334e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 5344e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 5354e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 536a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 537a13144ffSStefano Zampini } 538a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 539dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 540a13144ffSStefano Zampini for (i=0;i<nv;i++) { 541637e8532SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i], vc = vcount[i]; 5427d871cd7SStefano Zampini PetscBool sneighs = PETSC_TRUE, bdir = PETSC_FALSE; 543b03ebc13SStefano Zampini if (!order) { /* variable order */ 544dec27d64SStefano Zampini PetscReal vorder = 0.; 545dec27d64SStefano Zampini 546dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 547dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 5486080607fSStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%D)",vorder,test); 549dec27d64SStefano Zampini ord = 1; 550dec27d64SStefano Zampini } 551a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 5526080607fSStefano 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); 553a13144ffSStefano Zampini #endif 554637e8532SStefano Zampini for (j=ii[i];j<ii[i+1] && sneighs;j++) { 5557d871cd7SStefano Zampini if (PetscBTLookup(btbd,jj[j])) { 5567d871cd7SStefano Zampini bdir = PETSC_TRUE; 5577d871cd7SStefano Zampini break; 5587d871cd7SStefano Zampini } 559637e8532SStefano Zampini if (vc != ecount[jj[j]]) { 560637e8532SStefano Zampini sneighs = PETSC_FALSE; 561637e8532SStefano Zampini } else { 562637e8532SStefano Zampini PetscInt k,*vn = vneighs[i], *en = eneighs[jj[j]]; 563637e8532SStefano Zampini for (k=0;k<vc;k++) { 564637e8532SStefano Zampini if (vn[k] != en[k]) { 565637e8532SStefano Zampini sneighs = PETSC_FALSE; 566637e8532SStefano Zampini break; 567637e8532SStefano Zampini } 568637e8532SStefano Zampini } 569637e8532SStefano Zampini } 570637e8532SStefano Zampini } 5717d871cd7SStefano Zampini if (!sneighs || test >= 3*ord || bdir) { /* splitpoints */ 5726080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %D (%D %D %D)\n",i,!sneighs,test >= 3*ord,bdir); 573a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 574dec27d64SStefano Zampini } else if (test == ord) { 575b03ebc13SStefano Zampini if (order == 1 || (!order && ii[i+1]-ii[i] == 1)) { 5766080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %D\n",i); 577a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 578a13144ffSStefano Zampini } else { 5796080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %D\n",i); 580a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 581a13144ffSStefano Zampini } 582a13144ffSStefano Zampini } 583a13144ffSStefano Zampini } 584b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(el2g,NULL,&ecount,&eneighs);CHKERRQ(ierr); 585b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(vl2g,NULL,&vcount,&vneighs);CHKERRQ(ierr); 5867d871cd7SStefano Zampini ierr = PetscBTDestroy(&btbd);CHKERRQ(ierr); 587b03ebc13SStefano Zampini 588b03ebc13SStefano Zampini /* a candidate is valid if it is connected to another candidate via a non-primal edge dof */ 589b03ebc13SStefano Zampini if (order != 1) { 590b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSPECTING CANDIDATES\n"); 591b03ebc13SStefano Zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 592b03ebc13SStefano Zampini for (i=0;i<nv;i++) { 593b03ebc13SStefano Zampini if (PetscBTLookup(btvcand,i)) { 594b03ebc13SStefano Zampini PetscBool found = PETSC_FALSE; 595b03ebc13SStefano Zampini for (j=ii[i];j<ii[i+1] && !found;j++) { 596b03ebc13SStefano Zampini PetscInt k,e = jj[j]; 597b03ebc13SStefano Zampini if (PetscBTLookup(bte,e)) continue; 598b03ebc13SStefano Zampini for (k=iit[e];k<iit[e+1];k++) { 599b03ebc13SStefano Zampini PetscInt v = jjt[k]; 600b03ebc13SStefano Zampini if (v != i && PetscBTLookup(btvcand,v)) { 601b03ebc13SStefano Zampini found = PETSC_TRUE; 602b03ebc13SStefano Zampini break; 603b03ebc13SStefano Zampini } 604b03ebc13SStefano Zampini } 605b03ebc13SStefano Zampini } 606b03ebc13SStefano Zampini if (!found) { 6076080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %D CLEARED\n",i); 608b03ebc13SStefano Zampini ierr = PetscBTClear(btvcand,i);CHKERRQ(ierr); 609b03ebc13SStefano Zampini } else { 6106080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %D ACCEPTED\n",i); 611b03ebc13SStefano Zampini } 612b03ebc13SStefano Zampini } 613b03ebc13SStefano Zampini } 614b03ebc13SStefano Zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 615b03ebc13SStefano Zampini } 616dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 617a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 618b03ebc13SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 619a13144ffSStefano Zampini 620a13144ffSStefano Zampini /* Get the local G^T explicitly */ 6210569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 622a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 6234e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 624a13144ffSStefano Zampini 6254e64d54eSstefano_zampini /* Mark interior nodal dofs */ 626a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6274e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 628a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 629a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 6304e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 631a13144ffSStefano Zampini } 632a13144ffSStefano Zampini } 633a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 634a13144ffSStefano Zampini 635a13144ffSStefano Zampini /* communicate corners and splitpoints */ 636a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 637*580bdb30SBarry Smith ierr = PetscArrayzero(sfvleaves,nv);CHKERRQ(ierr); 638*580bdb30SBarry Smith ierr = PetscArrayzero(sfvroots,Lv);CHKERRQ(ierr); 639a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 640a13144ffSStefano Zampini 641a13144ffSStefano Zampini if (print) { 642a13144ffSStefano Zampini IS tbz; 643a13144ffSStefano Zampini 644a13144ffSStefano Zampini cum = 0; 645a13144ffSStefano Zampini for (i=0;i<nv;i++) 646a13144ffSStefano Zampini if (sfvleaves[i]) 647a13144ffSStefano Zampini vmarks[cum++] = i; 648a13144ffSStefano Zampini 649a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 650a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 651a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 652a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 653a13144ffSStefano Zampini } 654a13144ffSStefano Zampini 655a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 656a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 657a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 658a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 659a13144ffSStefano Zampini 6604e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 6614e64d54eSstefano_zampini and interior nodal dofs */ 662a13144ffSStefano Zampini cum = 0; 663a13144ffSStefano Zampini for (i=0;i<nv;i++) { 664a13144ffSStefano Zampini if (sfvleaves[i]) { 665a13144ffSStefano Zampini vmarks[cum++] = i; 666a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 667a13144ffSStefano Zampini } 6684e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 669a13144ffSStefano Zampini } 6704e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 671a13144ffSStefano Zampini if (print) { 672a13144ffSStefano Zampini IS tbz; 673a13144ffSStefano Zampini 674a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 6754e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 676a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 677a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 678a13144ffSStefano Zampini } 679a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 680a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 681a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 682a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 683a13144ffSStefano Zampini 684a13144ffSStefano Zampini /* Recompute G */ 685a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 686a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 687a13144ffSStefano Zampini if (print) { 688a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 689a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 690a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 691a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 692a13144ffSStefano Zampini } 693a13144ffSStefano Zampini 694a13144ffSStefano Zampini /* Get primal dofs (if any) */ 695a13144ffSStefano Zampini cum = 0; 696a13144ffSStefano Zampini for (i=0;i<ne;i++) { 697a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 698a13144ffSStefano Zampini } 699c2151214SStefano Zampini if (fl2g) { 700c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 701c2151214SStefano Zampini } 702a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 703a13144ffSStefano Zampini if (print) { 704a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 705a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 706a13144ffSStefano Zampini } 707a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 708c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 709a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 710a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 711a13144ffSStefano Zampini 712a13144ffSStefano Zampini /* Compute edge connectivity */ 713a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 714a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 715a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 716c2151214SStefano Zampini if (fl2g) { 717c2151214SStefano Zampini PetscBT btf; 718c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 719c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 720c2151214SStefano Zampini 721c2151214SStefano Zampini /* create CSR for all local dofs */ 722c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 723c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 7246080607fSStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid size of CSR graph %D. Should be %D",pcbddc->mat_graph->nvtxs_csr,n); 725c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 726c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 727c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 728c2151214SStefano Zampini rest = PETSC_TRUE; 729c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 730c2151214SStefano Zampini } else { 731c2151214SStefano Zampini free = PETSC_TRUE; 732c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 733c2151214SStefano Zampini iiu[0] = 0; 734c2151214SStefano Zampini for (i=0;i<n;i++) { 735c2151214SStefano Zampini iiu[i+1] = i+1; 736c2151214SStefano Zampini jju[i] = -1; 737d904f53bSStefano Zampini } 738c2151214SStefano Zampini } 739c2151214SStefano Zampini 740c2151214SStefano Zampini /* import sizes of CSR */ 741c2151214SStefano Zampini iia[0] = 0; 742c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 743c2151214SStefano Zampini 744c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 745c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 746c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 747c2151214SStefano Zampini for (i=0;i<ne;i++) { 748c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 749c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 750c2151214SStefano Zampini } 751c2151214SStefano Zampini 752c2151214SStefano Zampini /* iia in CSR */ 753c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 754c2151214SStefano Zampini 755c2151214SStefano Zampini /* jja in CSR */ 756c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 757c2151214SStefano Zampini for (i=0;i<n;i++) 758c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 759c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 760c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 761c2151214SStefano Zampini 762c2151214SStefano Zampini /* map edge dofs connectivity */ 7631e0482f5SStefano Zampini if (jj) { 764c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 765c2151214SStefano Zampini for (i=0;i<ne;i++) { 766c2151214SStefano Zampini PetscInt e = idxs[i]; 767c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 768c2151214SStefano Zampini } 7691e0482f5SStefano Zampini } 770c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 771c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 772c2151214SStefano Zampini if (rest) { 773c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 774c2151214SStefano Zampini } 775c2151214SStefano Zampini if (free) { 776c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 777c2151214SStefano Zampini } 778c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 779c2151214SStefano Zampini } else { 780c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 781c2151214SStefano Zampini } 782c2151214SStefano Zampini 783a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 784a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 785213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 786a13144ffSStefano Zampini 787a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 788c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 789a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 790a13144ffSStefano Zampini 791c2151214SStefano Zampini if (fl2g) { 792c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 793c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 794c2151214SStefano Zampini for (i=0;i<nee;i++) { 795c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 796c2151214SStefano Zampini } 797c2151214SStefano Zampini } else { 798c2151214SStefano Zampini eedges = alleedges; 799c2151214SStefano Zampini primals = allprimals; 800c2151214SStefano Zampini } 801c2151214SStefano Zampini 802a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 803*580bdb30SBarry Smith ierr = PetscArrayzero(marks,ne);CHKERRQ(ierr); 804c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 805c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 806c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 807c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 808c2151214SStefano Zampini if (print) { 809c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 810c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 811c2151214SStefano Zampini } 812c2151214SStefano Zampini 813c2151214SStefano Zampini maxsize = 0; 814a13144ffSStefano Zampini for (i=0;i<nee;i++) { 815a13144ffSStefano Zampini PetscInt size,mark = i+1; 816a13144ffSStefano Zampini 817a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 818a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 819a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 820a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 821a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 822a13144ffSStefano Zampini } 823a13144ffSStefano Zampini 824a13144ffSStefano Zampini /* Find coarse edge endpoints */ 825a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 826a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 827a13144ffSStefano Zampini for (i=0;i<nee;i++) { 828a13144ffSStefano Zampini PetscInt mark = i+1,size; 829a13144ffSStefano Zampini 830a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8311e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8326080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 833a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 834a13144ffSStefano Zampini if (print) { 8356080607fSStefano Zampini ierr = PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %D\n",i);CHKERRQ(ierr); 8366080607fSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 837a13144ffSStefano Zampini } 838a13144ffSStefano Zampini for (j=0;j<size;j++) { 839a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 8406080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %D\n",ee); 841a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 8426080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %D\n",jj[k]); 843a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 8446080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %D\n",jj[k]); 845a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 846a13144ffSStefano Zampini PetscInt k2; 847a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 848a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 8496080607fSStefano 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])); 850c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 851c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 852c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 853a13144ffSStefano Zampini corner = PETSC_TRUE; 854a13144ffSStefano Zampini break; 855a13144ffSStefano Zampini } 856a13144ffSStefano Zampini } 857a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 8586080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %D\n",jj[k]); 859a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 860a13144ffSStefano Zampini } else { 861a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 862a13144ffSStefano Zampini } 863a13144ffSStefano Zampini } 864a13144ffSStefano Zampini } 865a13144ffSStefano Zampini } 866a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 867a13144ffSStefano Zampini } 868a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 869a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 870c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 871a13144ffSStefano Zampini 872a13144ffSStefano Zampini /* Reset marked primal dofs */ 873a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 874a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 875a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 876a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 877a13144ffSStefano Zampini 8780569b399SStefano Zampini /* Now use the initial lG */ 8790569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 8800569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 8810569b399SStefano Zampini lG = lGinit; 8820569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 8830569b399SStefano Zampini 884a13144ffSStefano Zampini /* Compute extended cols indices */ 885b03ebc13SStefano Zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 886b03ebc13SStefano Zampini ierr = PetscBTCreate(nee,&bter);CHKERRQ(ierr); 887a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 888a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 889a13144ffSStefano Zampini i *= maxsize; 890b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 891a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 892a13144ffSStefano Zampini eerr = PETSC_FALSE; 893a13144ffSStefano Zampini for (i=0;i<nee;i++) { 894b03ebc13SStefano Zampini PetscInt size,found = 0; 895a13144ffSStefano Zampini 896a13144ffSStefano Zampini cum = 0; 897a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8981e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8996080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 900a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 901b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 902a13144ffSStefano Zampini for (j=0;j<size;j++) { 903a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 904b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 905b03ebc13SStefano Zampini PetscInt vv = jj[k]; 906b03ebc13SStefano Zampini if (!PetscBTLookup(btv,vv)) extrow[cum++] = vv; 907b03ebc13SStefano Zampini else if (!PetscBTLookupSet(btvc,vv)) found++; 908b03ebc13SStefano Zampini } 909a13144ffSStefano Zampini } 910a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 911a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 912a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 913a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 914a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 915a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 916a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 917b03ebc13SStefano Zampini if (cum != size -1 || found != 2) { 918b03ebc13SStefano Zampini ierr = PetscBTSet(bter,i);CHKERRQ(ierr); 919a13144ffSStefano Zampini if (print) { 920a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 921a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 922a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 923a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 924a13144ffSStefano Zampini } 925a13144ffSStefano Zampini eerr = PETSC_TRUE; 926a13144ffSStefano Zampini } 927a13144ffSStefano Zampini } 9284e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 929a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 930a13144ffSStefano Zampini if (done) { 931a13144ffSStefano Zampini PetscInt *newprimals; 932a13144ffSStefano Zampini 933a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 934a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 935a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 936*580bdb30SBarry Smith ierr = PetscArraycpy(newprimals,idxs,cum);CHKERRQ(ierr); 937a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 9380569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 9396080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"DOING SECOND PASS (eerr %D)\n",eerr); 940a13144ffSStefano Zampini for (i=0;i<nee;i++) { 941b03ebc13SStefano Zampini PetscBool has_candidates = PETSC_FALSE; 942b03ebc13SStefano Zampini if (PetscBTLookup(bter,i)) { 943a13144ffSStefano Zampini PetscInt size,mark = i+1; 944a13144ffSStefano Zampini 945a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 946a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 947c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 948a13144ffSStefano Zampini for (j=0;j<size;j++) { 949a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 9506080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"Inspecting edge dof %D [%D %D)\n",ee,ii[ee],ii[ee+1]); 951a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 952a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 953a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 954a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 955b03ebc13SStefano Zampini has_candidates = PETSC_TRUE; 9566080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Candidate set to vertex %D\n",vv); 957a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 958a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 959a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 960a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 961a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 9626080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected edge dof set to primal %D\n",ee2); 963a13144ffSStefano Zampini newprimals[cum++] = ee2; 964a13144ffSStefano Zampini /* finally set the new corners */ 965a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 9666080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected nodal dof set to vertex %D\n",jj[k3]); 967a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 968a13144ffSStefano Zampini } 969a13144ffSStefano Zampini } 970a13144ffSStefano Zampini } 971b03ebc13SStefano Zampini } else { 9726080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Not a candidate vertex %D\n",jj[k]); 973a13144ffSStefano Zampini } 974a13144ffSStefano Zampini } 975a13144ffSStefano Zampini } 976b03ebc13SStefano Zampini if (!has_candidates) { /* circular edge */ 977b03ebc13SStefano Zampini PetscInt k, ee = idxs[0],*tmarks; 978b03ebc13SStefano Zampini 979b03ebc13SStefano Zampini ierr = PetscCalloc1(ne,&tmarks);CHKERRQ(ierr); 9806080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Circular edge %D\n",i); 981b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 982b03ebc13SStefano Zampini PetscInt k2; 9836080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Set to corner %D\n",jj[k]); 984b03ebc13SStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 985b03ebc13SStefano Zampini for (k2=iit[jj[k]];k2<iit[jj[k]+1];k2++) tmarks[jjt[k2]]++; 986b03ebc13SStefano Zampini } 987b03ebc13SStefano Zampini for (j=0;j<size;j++) { 988b03ebc13SStefano Zampini if (tmarks[idxs[j]] > 1) { 9896080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Edge dof set to primal %D\n",idxs[j]); 990b03ebc13SStefano Zampini newprimals[cum++] = idxs[j]; 991b03ebc13SStefano Zampini } 992b03ebc13SStefano Zampini } 993b03ebc13SStefano Zampini ierr = PetscFree(tmarks);CHKERRQ(ierr); 994b03ebc13SStefano Zampini } 995a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 996a13144ffSStefano Zampini } 997a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 998a13144ffSStefano Zampini } 999b03ebc13SStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 10000569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 1001a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 1002c2151214SStefano Zampini if (fl2g) { 1003c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 1004c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1005c2151214SStefano Zampini for (i=0;i<nee;i++) { 1006c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1007c2151214SStefano Zampini } 1008c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1009c2151214SStefano Zampini } 1010c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1011a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 1012a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 1013a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 1014a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1015a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 1016213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 1017c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1018c2151214SStefano Zampini if (fl2g) { 1019c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 1020c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 1021c2151214SStefano Zampini for (i=0;i<nee;i++) { 1022c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 1023c2151214SStefano Zampini } 1024c2151214SStefano Zampini } else { 1025c2151214SStefano Zampini eedges = alleedges; 1026c2151214SStefano Zampini primals = allprimals; 1027c2151214SStefano Zampini } 1028b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 1029a13144ffSStefano Zampini 1030a13144ffSStefano Zampini /* Mark again */ 1031*580bdb30SBarry Smith ierr = PetscArrayzero(marks,ne);CHKERRQ(ierr); 1032a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1033a13144ffSStefano Zampini PetscInt size,mark = i+1; 1034a13144ffSStefano Zampini 1035a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1036a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1037a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 1038a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1039a13144ffSStefano Zampini } 1040a13144ffSStefano Zampini if (print) { 1041a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 1042a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 1043a13144ffSStefano Zampini } 1044a13144ffSStefano Zampini 1045a13144ffSStefano Zampini /* Recompute extended cols */ 1046a13144ffSStefano Zampini eerr = PETSC_FALSE; 1047a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1048a13144ffSStefano Zampini PetscInt size; 1049a13144ffSStefano Zampini 1050a13144ffSStefano Zampini cum = 0; 1051a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 10521e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 10536080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 1054a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1055a13144ffSStefano Zampini for (j=0;j<size;j++) { 1056a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 10571e0482f5SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 1058a13144ffSStefano Zampini } 1059a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1060a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 1061a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 1062a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 1063a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 1064a13144ffSStefano Zampini if (cum != size -1) { 1065a13144ffSStefano Zampini if (print) { 1066a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 1067a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 1068a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 1069a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 1070a13144ffSStefano Zampini } 1071a13144ffSStefano Zampini eerr = PETSC_TRUE; 1072a13144ffSStefano Zampini } 1073a13144ffSStefano Zampini } 1074a13144ffSStefano Zampini } 1075a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1076a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 1077b03ebc13SStefano Zampini ierr = PetscBTDestroy(&bter);CHKERRQ(ierr); 10787d871cd7SStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 1079a13144ffSStefano Zampini /* an error should not occur at this point */ 1080a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 1081a13144ffSStefano Zampini 10824e64d54eSstefano_zampini /* Check the number of endpoints */ 10830569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1084b03ebc13SStefano Zampini ierr = PetscMalloc1(2*nee,&corners);CHKERRQ(ierr); 1085b03ebc13SStefano Zampini ierr = PetscMalloc1(nee,&cedges);CHKERRQ(ierr); 10864e64d54eSstefano_zampini for (i=0;i<nee;i++) { 1087b03ebc13SStefano Zampini PetscInt size, found = 0, gc[2]; 10884e64d54eSstefano_zampini 1089b03ebc13SStefano Zampini /* init with defaults */ 1090b03ebc13SStefano Zampini cedges[i] = corners[i*2] = corners[i*2+1] = -1; 10914e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 10921e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 10936080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 10944e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1095b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 10964e64d54eSstefano_zampini for (j=0;j<size;j++) { 10974e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 10984e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 10994e64d54eSstefano_zampini PetscInt vv = jj[k]; 11004e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 11016080607fSStefano Zampini if (found == 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found more then two corners for edge %D",i); 1102b03ebc13SStefano Zampini corners[i*2+found++] = vv; 11034e64d54eSstefano_zampini } 11044e64d54eSstefano_zampini } 11054e64d54eSstefano_zampini } 1106b03ebc13SStefano Zampini if (found != 2) { 1107b03ebc13SStefano Zampini PetscInt e; 1108b03ebc13SStefano Zampini if (fl2g) { 1109b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,1,idxs,&e);CHKERRQ(ierr); 1110b03ebc13SStefano Zampini } else { 1111b03ebc13SStefano Zampini e = idxs[0]; 1112b03ebc13SStefano Zampini } 11136080607fSStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %D corners for edge %D (astart %D, estart %D)",found,i,e,idxs[0]); 1114b03ebc13SStefano Zampini } 1115eee23b56SStefano Zampini 1116eee23b56SStefano Zampini /* get primal dof index on this coarse edge */ 1117b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,2,corners+2*i,gc);CHKERRQ(ierr); 1118b03ebc13SStefano Zampini if (gc[0] > gc[1]) { 1119b03ebc13SStefano Zampini PetscInt swap = corners[2*i]; 1120b03ebc13SStefano Zampini corners[2*i] = corners[2*i+1]; 1121b03ebc13SStefano Zampini corners[2*i+1] = swap; 1122b03ebc13SStefano Zampini } 1123eee23b56SStefano Zampini cedges[i] = idxs[size-1]; 11244e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 11256080607fSStefano 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]); 11264e64d54eSstefano_zampini } 11270569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 11284e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 11294e64d54eSstefano_zampini 1130a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 1131a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 1132a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 1133a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 1134a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1135a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1136a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 1137a13144ffSStefano Zampini 1138a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1139*580bdb30SBarry Smith ierr = PetscArrayzero(emarks,nee+1);CHKERRQ(ierr); 1140a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 1141a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 1142a13144ffSStefano Zampini if (emax < emarks[j]) { 1143a13144ffSStefano Zampini emax = emarks[j]; 1144a13144ffSStefano Zampini eemax = j; 1145a13144ffSStefano Zampini } 1146a13144ffSStefano Zampini } 1147a13144ffSStefano Zampini /* not relevant for edges */ 1148a13144ffSStefano Zampini if (!eemax) continue; 1149a13144ffSStefano Zampini 1150a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 1151a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 11526080607fSStefano 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",marks[jj[j]]-1,eemax,i,jj[j]); 1153a13144ffSStefano Zampini } 1154a13144ffSStefano Zampini } 1155a13144ffSStefano Zampini } 1156a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 1157a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1158a13144ffSStefano Zampini #endif 1159a13144ffSStefano Zampini 1160a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 1161a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1162a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 1163a13144ffSStefano Zampini extmem *= maxsize; 1164a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 1165a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 1166a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 1167a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1168a13144ffSStefano Zampini PetscInt mark = 0,size,start; 1169213b8bfaSStefano Zampini 1170a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1171a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 1172a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 1173a13144ffSStefano Zampini mark = marks[jj[j]]; 1174a13144ffSStefano Zampini 1175a13144ffSStefano Zampini /* not relevant */ 1176a13144ffSStefano Zampini if (!mark) continue; 1177a13144ffSStefano Zampini 1178a13144ffSStefano Zampini /* import extended row */ 1179a13144ffSStefano Zampini mark--; 1180a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 1181a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 11826080607fSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %D > %D",extrowcum[mark] + size,extmem); 1183*580bdb30SBarry Smith ierr = PetscArraycpy(extrow+start,jj+ii[i],size);CHKERRQ(ierr); 1184a13144ffSStefano Zampini extrowcum[mark] += size; 1185a13144ffSStefano Zampini } 1186a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1187213b8bfaSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1188213b8bfaSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 1189213b8bfaSStefano Zampini 1190213b8bfaSStefano Zampini /* Compress extrows */ 1191a13144ffSStefano Zampini cum = 0; 1192a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1193a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 1194a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 1195a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 1196a13144ffSStefano Zampini cum = PetscMax(cum,size); 1197a13144ffSStefano Zampini } 1198a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 1199a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 1200a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 1201a13144ffSStefano Zampini 1202a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 1203a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 1204a13144ffSStefano Zampini 1205a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 1206a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1207c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 1208c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 1209a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 1210a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 1211a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 12121e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(T,al2g,al2g);CHKERRQ(ierr); 1213a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 1214a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1215213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&al2g);CHKERRQ(ierr); 1216a13144ffSStefano Zampini 1217a13144ffSStefano Zampini /* Defaults to identity */ 1218c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 1219a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 1220a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 1221a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 1222a13144ffSStefano Zampini 12231e0482f5SStefano Zampini /* Create discrete gradient for the coarser level if needed */ 12241e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 12251e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 12261e0482f5SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 12271e0482f5SStefano Zampini ISLocalToGlobalMapping cel2g,cvl2g; 12281e0482f5SStefano Zampini IS wis,gwis; 12291e0482f5SStefano Zampini PetscInt cnv,cne; 12301e0482f5SStefano Zampini 12311e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,nee,cedges,PETSC_COPY_VALUES,&wis);CHKERRQ(ierr); 12321e0482f5SStefano Zampini if (fl2g) { 12331e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(fl2g,wis,&pcbddc->nedclocal);CHKERRQ(ierr); 12341e0482f5SStefano Zampini } else { 12351e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)wis);CHKERRQ(ierr); 12361e0482f5SStefano Zampini pcbddc->nedclocal = wis; 12371e0482f5SStefano Zampini } 12381e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,wis,&gwis);CHKERRQ(ierr); 12391e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12401e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cne,&wis);CHKERRQ(ierr); 12411e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cel2g);CHKERRQ(ierr); 12421e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12431e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12441e0482f5SStefano Zampini 12451e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,2*nee,corners,PETSC_USE_POINTER,&wis);CHKERRQ(ierr); 12461e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(vl2g,wis,&gwis);CHKERRQ(ierr); 12471e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12481e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cnv,&wis);CHKERRQ(ierr); 12491e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cvl2g);CHKERRQ(ierr); 12501e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12511e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12521e0482f5SStefano Zampini 12531e0482f5SStefano Zampini ierr = MatCreate(comm,&pcbddc->nedcG);CHKERRQ(ierr); 12541e0482f5SStefano Zampini ierr = MatSetSizes(pcbddc->nedcG,PETSC_DECIDE,PETSC_DECIDE,cne,cnv);CHKERRQ(ierr); 12551e0482f5SStefano Zampini ierr = MatSetType(pcbddc->nedcG,MATAIJ);CHKERRQ(ierr); 12561e0482f5SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->nedcG,2,NULL);CHKERRQ(ierr); 12571e0482f5SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->nedcG,2,NULL,2,NULL);CHKERRQ(ierr); 12581e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->nedcG,cel2g,cvl2g);CHKERRQ(ierr); 12591e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cel2g);CHKERRQ(ierr); 12601e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cvl2g);CHKERRQ(ierr); 12611e0482f5SStefano Zampini } 1262213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 12631e0482f5SStefano Zampini 12641e0482f5SStefano Zampini #if defined(PRINT_GDET) 12651e0482f5SStefano Zampini inc = 0; 12661e0482f5SStefano Zampini lev = pcbddc->current_level; 12671e0482f5SStefano Zampini #endif 1268213b8bfaSStefano Zampini 1269213b8bfaSStefano Zampini /* Insert values in the change of basis matrix */ 1270a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1271a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 12721e0482f5SStefano Zampini IS cornersis = NULL; 12731e0482f5SStefano Zampini PetscScalar cvals[2]; 1274a13144ffSStefano Zampini 12751e0482f5SStefano Zampini if (pcbddc->nedcG) { 12761e0482f5SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners+2*i,PETSC_USE_POINTER,&cornersis);CHKERRQ(ierr); 12771e0482f5SStefano Zampini } 12781e0482f5SStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],cornersis,&Gins,&GKins,cvals,work,rwork);CHKERRQ(ierr); 1279a13144ffSStefano Zampini if (Gins && GKins) { 12801683a169SBarry Smith const PetscScalar *data; 1281a13144ffSStefano Zampini const PetscInt *rows,*cols; 1282a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 1283a13144ffSStefano Zampini 1284a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 1285a13144ffSStefano Zampini /* H1 */ 1286a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 1287a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 12881683a169SBarry Smith ierr = MatDenseGetArrayRead(Gins,&data);CHKERRQ(ierr); 1289a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 12901683a169SBarry Smith ierr = MatDenseRestoreArrayRead(Gins,&data);CHKERRQ(ierr); 1291a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 1292a13144ffSStefano Zampini /* complement */ 1293a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 12946080607fSStefano Zampini if (!ncc) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Constant function has not been generated for coarse edge %D",i); 12956080607fSStefano Zampini if (ncc + nch != nrc) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"The sum of the number of columns of GKins %D and Gins %D does not match %D for coarse edge %D",ncc,nch,nrc,i); 12966080607fSStefano Zampini if (ncc != 1 && pcbddc->nedcG) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot generate the coarse discrete gradient for coarse edge %D with ncc %D",i,ncc); 12971683a169SBarry Smith ierr = MatDenseGetArrayRead(GKins,&data);CHKERRQ(ierr); 1298a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 12991683a169SBarry Smith ierr = MatDenseRestoreArrayRead(GKins,&data);CHKERRQ(ierr); 13001e0482f5SStefano Zampini 13011e0482f5SStefano Zampini /* coarse discrete gradient */ 13021e0482f5SStefano Zampini if (pcbddc->nedcG) { 13031e0482f5SStefano Zampini PetscInt cols[2]; 13041e0482f5SStefano Zampini 13051e0482f5SStefano Zampini cols[0] = 2*i; 13061e0482f5SStefano Zampini cols[1] = 2*i+1; 13071e0482f5SStefano Zampini ierr = MatSetValuesLocal(pcbddc->nedcG,1,&i,2,cols,cvals,INSERT_VALUES);CHKERRQ(ierr); 13081e0482f5SStefano Zampini } 1309a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1310a13144ffSStefano Zampini } 1311a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1312a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 13131e0482f5SStefano Zampini ierr = ISDestroy(&cornersis);CHKERRQ(ierr); 1314a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1315a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1316a13144ffSStefano Zampini } 1317213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 1318a13144ffSStefano Zampini 1319a13144ffSStefano Zampini /* Start assembling */ 1320a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13211e0482f5SStefano Zampini if (pcbddc->nedcG) { 13221e0482f5SStefano Zampini ierr = MatAssemblyBegin(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13231e0482f5SStefano Zampini } 1324a13144ffSStefano Zampini 1325a13144ffSStefano Zampini /* Free */ 1326c2151214SStefano Zampini if (fl2g) { 1327c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1328c2151214SStefano Zampini for (i=0;i<nee;i++) { 1329c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1330c2151214SStefano Zampini } 1331c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1332c2151214SStefano Zampini } 1333eee23b56SStefano Zampini 1334eee23b56SStefano Zampini /* hack mat_graph with primal dofs on the coarse edges */ 1335eee23b56SStefano Zampini { 1336eee23b56SStefano Zampini PCBDDCGraph graph = pcbddc->mat_graph; 1337eee23b56SStefano Zampini PetscInt *oqueue = graph->queue; 1338eee23b56SStefano Zampini PetscInt *ocptr = graph->cptr; 1339eee23b56SStefano Zampini PetscInt ncc,*idxs; 1340eee23b56SStefano Zampini 1341eee23b56SStefano Zampini /* find first primal edge */ 1342eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1343eee23b56SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1344eee23b56SStefano Zampini } else { 1345eee23b56SStefano Zampini if (fl2g) { 1346eee23b56SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,nee,cedges,cedges);CHKERRQ(ierr); 1347eee23b56SStefano Zampini } 1348eee23b56SStefano Zampini idxs = cedges; 1349eee23b56SStefano Zampini } 1350eee23b56SStefano Zampini cum = 0; 1351eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1352eee23b56SStefano Zampini 1353eee23b56SStefano Zampini /* adapt connected components */ 1354eee23b56SStefano Zampini ierr = PetscMalloc2(graph->nvtxs+1,&graph->cptr,ocptr[graph->ncc],&graph->queue);CHKERRQ(ierr); 1355eee23b56SStefano Zampini graph->cptr[0] = 0; 1356eee23b56SStefano Zampini for (i=0,ncc=0;i<graph->ncc;i++) { 1357eee23b56SStefano Zampini PetscInt lc = ocptr[i+1]-ocptr[i]; 1358eee23b56SStefano Zampini if (cum != nee && oqueue[ocptr[i+1]-1] == cedges[cum]) { /* this cc has a primal dof */ 1359eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc]+1; 1360eee23b56SStefano Zampini graph->queue[graph->cptr[ncc]] = cedges[cum]; 1361eee23b56SStefano Zampini ncc++; 1362eee23b56SStefano Zampini lc--; 1363eee23b56SStefano Zampini cum++; 1364eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1365eee23b56SStefano Zampini } 1366eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc] + lc; 1367eee23b56SStefano Zampini for (j=0;j<lc;j++) graph->queue[graph->cptr[ncc]+j] = oqueue[ocptr[i]+j]; 1368eee23b56SStefano Zampini ncc++; 1369eee23b56SStefano Zampini } 1370eee23b56SStefano Zampini graph->ncc = ncc; 1371eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1372eee23b56SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1373eee23b56SStefano Zampini } 1374eee23b56SStefano Zampini ierr = PetscFree2(ocptr,oqueue);CHKERRQ(ierr); 1375eee23b56SStefano Zampini } 1376213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1377c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1378c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1379213b8bfaSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1380eee23b56SStefano Zampini 1381c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1382a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1383a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1384b03ebc13SStefano Zampini ierr = PetscFree(corners);CHKERRQ(ierr); 1385b03ebc13SStefano Zampini ierr = PetscFree(cedges);CHKERRQ(ierr); 1386a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1387a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1388a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1389a13144ffSStefano Zampini 1390a13144ffSStefano Zampini /* Complete assembling */ 1391a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13921e0482f5SStefano Zampini if (pcbddc->nedcG) { 13931e0482f5SStefano Zampini ierr = MatAssemblyEnd(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13941e0482f5SStefano Zampini #if 0 13951e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->nedcG,"coarse_G");CHKERRQ(ierr); 13961e0482f5SStefano Zampini ierr = MatView(pcbddc->nedcG,NULL);CHKERRQ(ierr); 13971e0482f5SStefano Zampini #endif 13981e0482f5SStefano Zampini } 1399a13144ffSStefano Zampini 1400a13144ffSStefano Zampini /* set change of basis */ 1401213b8bfaSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,singular);CHKERRQ(ierr); 1402a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1403a13144ffSStefano Zampini 1404a13144ffSStefano Zampini PetscFunctionReturn(0); 1405a13144ffSStefano Zampini } 1406a13144ffSStefano Zampini 1407d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1408d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1409d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1410d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1411d8203eabSStefano Zampini { 1412d8203eabSStefano Zampini PetscErrorCode ierr; 1413d8203eabSStefano Zampini PetscInt i; 1414d8203eabSStefano Zampini 1415d8203eabSStefano Zampini PetscFunctionBegin; 1416d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1417d8203eabSStefano Zampini PetscInt first,last; 1418d8203eabSStefano Zampini 1419d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 142086fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1421d8203eabSStefano Zampini if (i>=first && i < last) { 1422d8203eabSStefano Zampini PetscScalar *data; 1423d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1424d8203eabSStefano Zampini if (!has_const) { 1425d8203eabSStefano Zampini data[i-first] = 1.; 1426d8203eabSStefano Zampini } else { 142786fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 142886fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1429d8203eabSStefano Zampini } 1430d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1431d8203eabSStefano Zampini } 1432d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1433d8203eabSStefano Zampini } 1434d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1435d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1436d8203eabSStefano Zampini PetscInt first,last; 14378860a134SJunchao Zhang ierr = VecLockReadPop(quad_vecs[i]);CHKERRQ(ierr); 1438d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1439d8203eabSStefano Zampini if (i>=first && i < last) { 1440d8203eabSStefano Zampini PetscScalar *data; 1441d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1442d8203eabSStefano Zampini if (!has_const) { 1443d8203eabSStefano Zampini data[i-first] = 0.; 1444d8203eabSStefano Zampini } else { 144586fa73c5SStefano Zampini data[2*i-first] = 0.; 144686fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1447d8203eabSStefano Zampini } 1448d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1449d8203eabSStefano Zampini } 1450d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 14518860a134SJunchao Zhang ierr = VecLockReadPush(quad_vecs[i]);CHKERRQ(ierr); 1452d8203eabSStefano Zampini } 1453d8203eabSStefano Zampini PetscFunctionReturn(0); 1454d8203eabSStefano Zampini } 1455d8203eabSStefano Zampini 14568ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1457669cc0f4SStefano Zampini { 1458a198735bSStefano Zampini Mat loc_divudotp; 1459fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 14608ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1461669cc0f4SStefano Zampini PetscScalar *vals; 1462669cc0f4SStefano Zampini const PetscScalar *array; 14630f27d399SStefano Zampini PetscInt i,maxneighs,maxsize,*gidxs; 1464a040e873SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 14651ae86dd6SStefano Zampini PetscMPIInt rank; 1466a198735bSStefano Zampini PetscErrorCode ierr; 1467669cc0f4SStefano Zampini 1468669cc0f4SStefano Zampini PetscFunctionBegin; 1469a040e873SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1470a040e873SStefano Zampini ierr = MPIU_Allreduce(&n_neigh,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 14718037d520SStefano Zampini if (!maxneighs) { 14728037d520SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 14738037d520SStefano Zampini *nnsp = NULL; 14748037d520SStefano Zampini PetscFunctionReturn(0); 1475669cc0f4SStefano Zampini } 1476669cc0f4SStefano Zampini maxsize = 0; 1477a040e873SStefano Zampini for (i=0;i<n_neigh;i++) maxsize = PetscMax(n_shared[i],maxsize); 14780f27d399SStefano Zampini ierr = PetscMalloc2(maxsize,&gidxs,maxsize,&vals);CHKERRQ(ierr); 1479669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1480669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 14818ae0ca82SStefano Zampini if (!transpose) { 14828ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 14838ae0ca82SStefano Zampini } else { 14848ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 14858ae0ca82SStefano Zampini } 1486669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 14871ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1488d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1489669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 14908860a134SJunchao Zhang ierr = VecLockReadPop(quad_vecs[i]);CHKERRQ(ierr); 1491669cc0f4SStefano Zampini } 1492d8203eabSStefano Zampini 1493669cc0f4SStefano Zampini /* compute local quad vec */ 1494a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 14958ae0ca82SStefano Zampini if (!transpose) { 1496a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 14978ae0ca82SStefano Zampini } else { 14988ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 14998ae0ca82SStefano Zampini } 1500669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 15018ae0ca82SStefano Zampini if (!transpose) { 1502a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 15038ae0ca82SStefano Zampini } else { 15048ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 15058ae0ca82SStefano Zampini } 1506fa23a32eSStefano Zampini if (vl2l) { 1507187c917aSStefano Zampini Mat lA; 1508187c917aSStefano Zampini VecScatter sc; 1509187c917aSStefano Zampini 1510187c917aSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1511187c917aSStefano Zampini ierr = MatCreateVecs(lA,&vins,NULL);CHKERRQ(ierr); 15129448b7f1SJunchao Zhang ierr = VecScatterCreate(v,NULL,vins,vl2l,&sc);CHKERRQ(ierr); 1513187c917aSStefano Zampini ierr = VecScatterBegin(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1514187c917aSStefano Zampini ierr = VecScatterEnd(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1515187c917aSStefano Zampini ierr = VecScatterDestroy(&sc);CHKERRQ(ierr); 1516fa23a32eSStefano Zampini } else { 1517fa23a32eSStefano Zampini vins = v; 1518fa23a32eSStefano Zampini } 1519fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1520669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 15219a962809SStefano Zampini 15221ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 15231ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1524a040e873SStefano Zampini for (i=0;i<n_neigh;i++) { 1525669cc0f4SStefano Zampini const PetscInt *idxs; 1526669cc0f4SStefano Zampini PetscInt idx,nn,j; 1527669cc0f4SStefano Zampini 1528a040e873SStefano Zampini idxs = shared[i]; 1529a040e873SStefano Zampini nn = n_shared[i]; 1530669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 15311ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1532669cc0f4SStefano Zampini idx = -(idx+1); 15330f27d399SStefano Zampini ierr = ISLocalToGlobalMappingApply(map,nn,idxs,gidxs);CHKERRQ(ierr); 15340f27d399SStefano Zampini ierr = VecSetValues(quad_vecs[idx],nn,gidxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1535669cc0f4SStefano Zampini } 1536a040e873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1537fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1538fa23a32eSStefano Zampini if (vl2l) { 1539187c917aSStefano Zampini ierr = VecDestroy(&vins);CHKERRQ(ierr); 1540fa23a32eSStefano Zampini } 1541669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 15420f27d399SStefano Zampini ierr = PetscFree2(gidxs,vals);CHKERRQ(ierr); 1543669cc0f4SStefano Zampini 1544669cc0f4SStefano Zampini /* assemble near null space */ 1545669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1546669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1547669cc0f4SStefano Zampini } 1548669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1549669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 15503272d46bSStefano Zampini ierr = VecViewFromOptions(quad_vecs[i],NULL,"-pc_bddc_quad_vecs_view");CHKERRQ(ierr); 15518860a134SJunchao Zhang ierr = VecLockReadPush(quad_vecs[i]);CHKERRQ(ierr); 1552669cc0f4SStefano Zampini } 1553669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1554669cc0f4SStefano Zampini PetscFunctionReturn(0); 1555669cc0f4SStefano Zampini } 1556669cc0f4SStefano Zampini 15577620a527SStefano Zampini PetscErrorCode PCBDDCAddPrimalVerticesLocalIS(PC pc, IS primalv) 15587620a527SStefano Zampini { 15597620a527SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15607620a527SStefano Zampini PetscErrorCode ierr; 15617620a527SStefano Zampini 15627620a527SStefano Zampini PetscFunctionBegin; 15637620a527SStefano Zampini if (primalv) { 15647620a527SStefano Zampini if (pcbddc->user_primal_vertices_local) { 15657620a527SStefano Zampini IS list[2], newp; 15667620a527SStefano Zampini 15677620a527SStefano Zampini list[0] = primalv; 15687620a527SStefano Zampini list[1] = pcbddc->user_primal_vertices_local; 15697620a527SStefano Zampini ierr = ISConcatenate(PetscObjectComm((PetscObject)pc),2,list,&newp);CHKERRQ(ierr); 15707620a527SStefano Zampini ierr = ISSortRemoveDups(newp);CHKERRQ(ierr); 15717620a527SStefano Zampini ierr = ISDestroy(&list[1]);CHKERRQ(ierr); 15727620a527SStefano Zampini pcbddc->user_primal_vertices_local = newp; 15737620a527SStefano Zampini } else { 15747620a527SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 15757620a527SStefano Zampini } 15767620a527SStefano Zampini } 15777620a527SStefano Zampini PetscFunctionReturn(0); 15787620a527SStefano Zampini } 1579669cc0f4SStefano Zampini 15801c7a958bSStefano Zampini static PetscErrorCode func_coords_private(PetscInt dim, PetscReal t, const PetscReal X[], PetscInt Nf, PetscScalar *out, void *ctx) 15811c7a958bSStefano Zampini { 15821c7a958bSStefano Zampini PetscInt f, *comp = (PetscInt *)ctx; 15831c7a958bSStefano Zampini 15841c7a958bSStefano Zampini PetscFunctionBegin; 15851c7a958bSStefano Zampini for (f=0;f<Nf;f++) out[f] = X[*comp]; 15861c7a958bSStefano Zampini PetscFunctionReturn(0); 15871c7a958bSStefano Zampini } 1588674ae819SStefano Zampini 15891f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 15901f4df5f7SStefano Zampini { 15911f4df5f7SStefano Zampini PetscErrorCode ierr; 15921f4df5f7SStefano Zampini Vec local,global; 15931f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15941f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 15955c5e10d6SStefano Zampini PetscBool monolithic = PETSC_FALSE; 15961f4df5f7SStefano Zampini 15971f4df5f7SStefano Zampini PetscFunctionBegin; 15985c5e10d6SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC topology options","PC");CHKERRQ(ierr); 15995c5e10d6SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_monolithic","Discard any information on dofs splitting",NULL,monolithic,&monolithic,NULL);CHKERRQ(ierr); 16005c5e10d6SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 16011f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 160221ef3d20SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 16031f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 16046a8fc67bSStefano Zampini if (monolithic) { /* just get block size to properly compute vertices */ 16056a8fc67bSStefano Zampini if (pcbddc->vertex_size == 1) { 16066a8fc67bSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->vertex_size);CHKERRQ(ierr); 16076a8fc67bSStefano Zampini } 16086a8fc67bSStefano Zampini goto boundary; 16096a8fc67bSStefano Zampini } 16105c5e10d6SStefano Zampini 16111f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 16121f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 16131f4df5f7SStefano Zampini PetscInt i; 16140c85b387SStefano Zampini 16151f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16161f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 16170c85b387SStefano Zampini PetscInt bs; 16180c85b387SStefano Zampini 16191f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16200c85b387SStefano Zampini ierr = ISGetBlockSize(pcbddc->ISForDofs[i],&bs);CHKERRQ(ierr); 16210c85b387SStefano Zampini ierr = ISSetBlockSize(pcbddc->ISForDofsLocal[i],bs);CHKERRQ(ierr); 16221f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 16231f4df5f7SStefano Zampini } 16241f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 16251f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 16261f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 16271f4df5f7SStefano Zampini } 16281f4df5f7SStefano Zampini } else { 162921ef3d20SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present */ 163021ef3d20SStefano Zampini DM dm; 163121ef3d20SStefano Zampini 163221ef3d20SStefano Zampini ierr = MatGetDM(pc->pmat, &dm);CHKERRQ(ierr); 16334f819b78SStefano Zampini if (!dm) { 16344f819b78SStefano Zampini ierr = PCGetDM(pc, &dm);CHKERRQ(ierr); 163521ef3d20SStefano Zampini } 163621ef3d20SStefano Zampini if (dm) { 163721ef3d20SStefano Zampini IS *fields; 163821ef3d20SStefano Zampini PetscInt nf,i; 16390c85b387SStefano Zampini 164021ef3d20SStefano Zampini ierr = DMCreateFieldDecomposition(dm,&nf,NULL,&fields,NULL);CHKERRQ(ierr); 164121ef3d20SStefano Zampini ierr = PetscMalloc1(nf,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 164221ef3d20SStefano Zampini for (i=0;i<nf;i++) { 16430c85b387SStefano Zampini PetscInt bs; 16440c85b387SStefano Zampini 164521ef3d20SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,fields[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16460c85b387SStefano Zampini ierr = ISGetBlockSize(fields[i],&bs);CHKERRQ(ierr); 16470c85b387SStefano Zampini ierr = ISSetBlockSize(pcbddc->ISForDofsLocal[i],bs);CHKERRQ(ierr); 164821ef3d20SStefano Zampini ierr = ISDestroy(&fields[i]);CHKERRQ(ierr); 164921ef3d20SStefano Zampini } 165021ef3d20SStefano Zampini ierr = PetscFree(fields);CHKERRQ(ierr); 165121ef3d20SStefano Zampini pcbddc->n_ISForDofsLocal = nf; 165221ef3d20SStefano Zampini } else { /* See if MATIS has fields attached by the conversion from MatNest */ 165321ef3d20SStefano Zampini PetscContainer c; 165421ef3d20SStefano Zampini 165521ef3d20SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc->pmat,"_convert_nest_lfields",(PetscObject*)&c);CHKERRQ(ierr); 165621ef3d20SStefano Zampini if (c) { 165721ef3d20SStefano Zampini MatISLocalFields lf; 165821ef3d20SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&lf);CHKERRQ(ierr); 165921ef3d20SStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,lf->nr,lf->rf);CHKERRQ(ierr); 166021ef3d20SStefano Zampini } else { /* fallback, create the default fields if bs > 1 */ 16611f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1662986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 166321ef3d20SStefano Zampini if (i > 1) { 1664986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 16651f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16661f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16671f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16681f4df5f7SStefano Zampini } 16691f4df5f7SStefano Zampini } 167021ef3d20SStefano Zampini } 167121ef3d20SStefano Zampini } 16727a0e7b2cSstefano_zampini } else { 16737a0e7b2cSstefano_zampini PetscInt i; 16747a0e7b2cSstefano_zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16757a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16767a0e7b2cSstefano_zampini } 16771f4df5f7SStefano Zampini } 1678986cdee1SStefano Zampini } 16791f4df5f7SStefano Zampini 16805c5e10d6SStefano Zampini boundary: 16811f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 16821f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16837a0e7b2cSstefano_zampini } else if (pcbddc->DirichletBoundariesLocal) { 16847a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16851f4df5f7SStefano Zampini } 16861f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 16871f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16887a0e7b2cSstefano_zampini } else if (pcbddc->NeumannBoundariesLocal) { 16897a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16901f4df5f7SStefano Zampini } 16911f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 16921f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 16931f4df5f7SStefano Zampini } 16941f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 16951f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 16967620a527SStefano Zampini /* detect local disconnected subdomains if requested (use matis->A) */ 16977620a527SStefano Zampini if (pcbddc->detect_disconnected) { 16987620a527SStefano Zampini IS primalv = NULL; 16997620a527SStefano Zampini PetscInt i; 17008361f951SStefano Zampini PetscBool filter = pcbddc->detect_disconnected_filter; 17017a0e7b2cSstefano_zampini 17027620a527SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 17037620a527SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 17047620a527SStefano Zampini } 17057620a527SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 17068361f951SStefano Zampini ierr = PCBDDCDetectDisconnectedComponents(pc,filter,&pcbddc->n_local_subs,&pcbddc->local_subs,&primalv);CHKERRQ(ierr); 17077620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 17087620a527SStefano Zampini ierr = ISDestroy(&primalv);CHKERRQ(ierr); 17097620a527SStefano Zampini } 17107620a527SStefano Zampini /* early stage corner detection */ 17117620a527SStefano Zampini { 17127620a527SStefano Zampini DM dm; 17137620a527SStefano Zampini 17147620a527SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 17154f819b78SStefano Zampini if (!dm) { 17164f819b78SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 17174f819b78SStefano Zampini } 17187620a527SStefano Zampini if (dm) { 17197620a527SStefano Zampini PetscBool isda; 17207620a527SStefano Zampini 17217620a527SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&isda);CHKERRQ(ierr); 17227620a527SStefano Zampini if (isda) { 17237620a527SStefano Zampini ISLocalToGlobalMapping l2l; 17247620a527SStefano Zampini IS corners; 17257620a527SStefano Zampini Mat lA; 17264f819b78SStefano Zampini PetscBool gl,lo; 17277620a527SStefano Zampini 17284f819b78SStefano Zampini { 17294f819b78SStefano Zampini Vec cvec; 17304f819b78SStefano Zampini const PetscScalar *coords; 17314f819b78SStefano Zampini PetscInt dof,n,cdim; 17324f819b78SStefano Zampini PetscBool memc = PETSC_TRUE; 17334f819b78SStefano Zampini 17344f819b78SStefano Zampini ierr = DMDAGetInfo(dm,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dof,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 17354f819b78SStefano Zampini ierr = DMGetCoordinates(dm,&cvec);CHKERRQ(ierr); 17364f819b78SStefano Zampini ierr = VecGetLocalSize(cvec,&n);CHKERRQ(ierr); 17374f819b78SStefano Zampini ierr = VecGetBlockSize(cvec,&cdim);CHKERRQ(ierr); 17384f819b78SStefano Zampini n /= cdim; 17394f819b78SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->coords);CHKERRQ(ierr); 17404f819b78SStefano Zampini ierr = PetscMalloc1(dof*n*cdim,&pcbddc->mat_graph->coords);CHKERRQ(ierr); 17414f819b78SStefano Zampini ierr = VecGetArrayRead(cvec,&coords);CHKERRQ(ierr); 17424f819b78SStefano Zampini #if defined(PETSC_USE_COMPLEX) 17434f819b78SStefano Zampini memc = PETSC_FALSE; 17444f819b78SStefano Zampini #endif 17454f819b78SStefano Zampini if (dof != 1) memc = PETSC_FALSE; 17464f819b78SStefano Zampini if (memc) { 1747*580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->mat_graph->coords,coords,cdim*n*dof);CHKERRQ(ierr); 17484f819b78SStefano Zampini } else { /* BDDC graph does not use any blocked information, we need to replicate the data */ 17494f819b78SStefano Zampini PetscReal *bcoords = pcbddc->mat_graph->coords; 17504f819b78SStefano Zampini PetscInt i, b, d; 17514f819b78SStefano Zampini 17524f819b78SStefano Zampini for (i=0;i<n;i++) { 17534f819b78SStefano Zampini for (b=0;b<dof;b++) { 17544f819b78SStefano Zampini for (d=0;d<cdim;d++) { 17554f819b78SStefano Zampini bcoords[i*dof*cdim + b*cdim + d] = PetscRealPart(coords[i*cdim+d]); 17564f819b78SStefano Zampini } 17574f819b78SStefano Zampini } 17584f819b78SStefano Zampini } 17594f819b78SStefano Zampini } 17604f819b78SStefano Zampini ierr = VecRestoreArrayRead(cvec,&coords);CHKERRQ(ierr); 17614f819b78SStefano Zampini pcbddc->mat_graph->cdim = cdim; 17624f819b78SStefano Zampini pcbddc->mat_graph->cnloc = dof*n; 17634f819b78SStefano Zampini pcbddc->mat_graph->cloc = PETSC_FALSE; 17644f819b78SStefano Zampini } 1765d4a6ed37SStefano Zampini ierr = DMDAGetSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17667620a527SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17677620a527SStefano Zampini ierr = MatGetLocalToGlobalMapping(lA,&l2l,NULL);CHKERRQ(ierr); 17687620a527SStefano Zampini ierr = MatISRestoreLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17694f819b78SStefano Zampini lo = (PetscBool)(l2l && corners); 17704f819b78SStefano Zampini ierr = MPIU_Allreduce(&lo,&gl,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 17714f819b78SStefano Zampini if (gl) { /* From PETSc's DMDA */ 17727620a527SStefano Zampini const PetscInt *idx; 177372ed36d8SStefano Zampini PetscInt dof,bs,*idxout,n; 17747620a527SStefano Zampini 177572ed36d8SStefano Zampini ierr = DMDAGetInfo(dm,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dof,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 17767620a527SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(l2l,&bs);CHKERRQ(ierr); 17777620a527SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 17787620a527SStefano Zampini ierr = ISGetIndices(corners,&idx);CHKERRQ(ierr); 177972ed36d8SStefano Zampini if (bs == dof) { 17807620a527SStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 17817620a527SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(l2l,n,idx,idxout);CHKERRQ(ierr); 178272ed36d8SStefano Zampini } else { /* the original DMDA local-to-local map have been modified */ 178372ed36d8SStefano Zampini PetscInt i,d; 178472ed36d8SStefano Zampini 178572ed36d8SStefano Zampini ierr = PetscMalloc1(dof*n,&idxout);CHKERRQ(ierr); 178672ed36d8SStefano Zampini for (i=0;i<n;i++) for (d=0;d<dof;d++) idxout[dof*i+d] = dof*idx[i]+d; 178772ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingApply(l2l,dof*n,idxout,idxout);CHKERRQ(ierr); 178872ed36d8SStefano Zampini 178972ed36d8SStefano Zampini bs = 1; 179072ed36d8SStefano Zampini n *= dof; 179172ed36d8SStefano Zampini } 17927620a527SStefano Zampini ierr = ISRestoreIndices(corners,&idx);CHKERRQ(ierr); 1793d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17947620a527SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)pc),bs,n,idxout,PETSC_OWN_POINTER,&corners);CHKERRQ(ierr); 17957620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,corners);CHKERRQ(ierr); 17967620a527SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 17971c7a958bSStefano Zampini pcbddc->corner_selected = PETSC_TRUE; 17984f819b78SStefano Zampini pcbddc->corner_selection = PETSC_TRUE; 17994f819b78SStefano Zampini } 18004f819b78SStefano Zampini if (corners) { 1801d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 18027620a527SStefano Zampini } 18037620a527SStefano Zampini } 18047620a527SStefano Zampini } 18057620a527SStefano Zampini } 18061c7a958bSStefano Zampini if (pcbddc->corner_selection && !pcbddc->mat_graph->cdim) { 18071c7a958bSStefano Zampini DM dm; 18081c7a958bSStefano Zampini 18091c7a958bSStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 18104f819b78SStefano Zampini if (!dm) { 18114f819b78SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 18121c7a958bSStefano Zampini } 18134f819b78SStefano Zampini if (dm) { /* this can get very expensive, I need to find a faster alternative */ 18141c7a958bSStefano Zampini Vec vcoords; 18151c7a958bSStefano Zampini PetscSection section; 18161c7a958bSStefano Zampini PetscReal *coords; 18171c7a958bSStefano Zampini PetscInt d,cdim,nl,nf,**ctxs; 18181c7a958bSStefano Zampini PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal *, PetscInt, PetscScalar *, void *); 18191c7a958bSStefano Zampini 18201c7a958bSStefano Zampini ierr = DMGetCoordinateDim(dm,&cdim);CHKERRQ(ierr); 1821e87a4003SBarry Smith ierr = DMGetSection(dm,§ion);CHKERRQ(ierr); 18221c7a958bSStefano Zampini ierr = PetscSectionGetNumFields(section,&nf);CHKERRQ(ierr); 18231c7a958bSStefano Zampini ierr = DMCreateGlobalVector(dm,&vcoords);CHKERRQ(ierr); 18241c7a958bSStefano Zampini ierr = VecGetLocalSize(vcoords,&nl);CHKERRQ(ierr); 18251c7a958bSStefano Zampini ierr = PetscMalloc1(nl*cdim,&coords);CHKERRQ(ierr); 18261c7a958bSStefano Zampini ierr = PetscMalloc2(nf,&funcs,nf,&ctxs);CHKERRQ(ierr); 18271c7a958bSStefano Zampini ierr = PetscMalloc1(nf,&ctxs[0]);CHKERRQ(ierr); 18281c7a958bSStefano Zampini for (d=0;d<nf;d++) funcs[d] = func_coords_private; 18291c7a958bSStefano Zampini for (d=1;d<nf;d++) ctxs[d] = ctxs[d-1] + 1; 18301c7a958bSStefano Zampini for (d=0;d<cdim;d++) { 18311c7a958bSStefano Zampini PetscInt i; 18321c7a958bSStefano Zampini const PetscScalar *v; 18331c7a958bSStefano Zampini 18341c7a958bSStefano Zampini for (i=0;i<nf;i++) ctxs[i][0] = d; 18351c7a958bSStefano Zampini ierr = DMProjectFunction(dm,0.0,funcs,(void**)ctxs,INSERT_VALUES,vcoords);CHKERRQ(ierr); 18361c7a958bSStefano Zampini ierr = VecGetArrayRead(vcoords,&v);CHKERRQ(ierr); 18371c7a958bSStefano Zampini for (i=0;i<nl;i++) coords[i*cdim+d] = PetscRealPart(v[i]); 18381c7a958bSStefano Zampini ierr = VecRestoreArrayRead(vcoords,&v);CHKERRQ(ierr); 18391c7a958bSStefano Zampini } 18401c7a958bSStefano Zampini ierr = VecDestroy(&vcoords);CHKERRQ(ierr); 18411c7a958bSStefano Zampini ierr = PCSetCoordinates(pc,cdim,nl,coords);CHKERRQ(ierr); 18421c7a958bSStefano Zampini ierr = PetscFree(coords);CHKERRQ(ierr); 18431c7a958bSStefano Zampini ierr = PetscFree(ctxs[0]);CHKERRQ(ierr); 18441c7a958bSStefano Zampini ierr = PetscFree2(funcs,ctxs);CHKERRQ(ierr); 18451c7a958bSStefano Zampini } 18461c7a958bSStefano Zampini } 18477a0e7b2cSstefano_zampini PetscFunctionReturn(0); 18487a0e7b2cSstefano_zampini } 18497a0e7b2cSstefano_zampini 18507a0e7b2cSstefano_zampini PetscErrorCode PCBDDCConsistencyCheckIS(PC pc, MPI_Op mop, IS *is) 18517a0e7b2cSstefano_zampini { 18527a0e7b2cSstefano_zampini Mat_IS *matis = (Mat_IS*)(pc->pmat->data); 18537a0e7b2cSstefano_zampini PetscErrorCode ierr; 18547a0e7b2cSstefano_zampini IS nis; 18557a0e7b2cSstefano_zampini const PetscInt *idxs; 18567a0e7b2cSstefano_zampini PetscInt i,nd,n = matis->A->rmap->n,*nidxs,nnd; 18577a0e7b2cSstefano_zampini PetscBool *ld; 18587a0e7b2cSstefano_zampini 18597a0e7b2cSstefano_zampini PetscFunctionBegin; 18607a0e7b2cSstefano_zampini if (mop != MPI_LAND && mop != MPI_LOR) SETERRQ(PetscObjectComm((PetscObject)(pc)),PETSC_ERR_SUP,"Supported are MPI_LAND and MPI_LOR"); 18617a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18627a0e7b2cSstefano_zampini /* init rootdata with true */ 18637a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_rootdata; 18647a0e7b2cSstefano_zampini for (i=0;i<pc->pmat->rmap->n;i++) ld[i] = PETSC_TRUE; 18657a0e7b2cSstefano_zampini } else { 1866*580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,pc->pmat->rmap->n);CHKERRQ(ierr); 18677a0e7b2cSstefano_zampini } 1868*580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,n);CHKERRQ(ierr); 18697a0e7b2cSstefano_zampini ierr = ISGetLocalSize(*is,&nd);CHKERRQ(ierr); 18707a0e7b2cSstefano_zampini ierr = ISGetIndices(*is,&idxs);CHKERRQ(ierr); 18717a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_leafdata; 18727a0e7b2cSstefano_zampini for (i=0;i<nd;i++) 18737a0e7b2cSstefano_zampini if (-1 < idxs[i] && idxs[i] < n) 18747a0e7b2cSstefano_zampini ld[idxs[i]] = PETSC_TRUE; 18757a0e7b2cSstefano_zampini ierr = ISRestoreIndices(*is,&idxs);CHKERRQ(ierr); 18767a0e7b2cSstefano_zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18777a0e7b2cSstefano_zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18787a0e7b2cSstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18797a0e7b2cSstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18807a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18817a0e7b2cSstefano_zampini ierr = PetscMalloc1(nd,&nidxs);CHKERRQ(ierr); 18827a0e7b2cSstefano_zampini } else { 18837a0e7b2cSstefano_zampini ierr = PetscMalloc1(n,&nidxs);CHKERRQ(ierr); 18847a0e7b2cSstefano_zampini } 18857a0e7b2cSstefano_zampini for (i=0,nnd=0;i<n;i++) 18867a0e7b2cSstefano_zampini if (ld[i]) 18877a0e7b2cSstefano_zampini nidxs[nnd++] = i; 18887a0e7b2cSstefano_zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(*is)),nnd,nidxs,PETSC_OWN_POINTER,&nis);CHKERRQ(ierr); 18897a0e7b2cSstefano_zampini ierr = ISDestroy(is);CHKERRQ(ierr); 18907a0e7b2cSstefano_zampini *is = nis; 18911f4df5f7SStefano Zampini PetscFunctionReturn(0); 18921f4df5f7SStefano Zampini } 18931f4df5f7SStefano Zampini 18943e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 18953e589ea0SStefano Zampini { 18963e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18973e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 18983e589ea0SStefano Zampini PetscErrorCode ierr; 18993e589ea0SStefano Zampini 19003e589ea0SStefano Zampini PetscFunctionBegin; 19013e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 19023e589ea0SStefano Zampini PetscFunctionReturn(0); 19033e589ea0SStefano Zampini } 19043e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19053e589ea0SStefano Zampini Vec swap; 19063e589ea0SStefano Zampini 19073e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19083e589ea0SStefano Zampini swap = pcbddc->work_change; 19093e589ea0SStefano Zampini pcbddc->work_change = r; 19103e589ea0SStefano Zampini r = swap; 19113e589ea0SStefano Zampini } 19123e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19133e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19143e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1915c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 19163e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 19173e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19183e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19193e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1920f913dca9SStefano Zampini pcbddc->work_change = r; 19213e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 19223e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 19233e589ea0SStefano Zampini } 19243e589ea0SStefano Zampini PetscFunctionReturn(0); 19253e589ea0SStefano Zampini } 19263e589ea0SStefano Zampini 1927a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1928a3df083aSStefano Zampini { 1929a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1930a3df083aSStefano Zampini PetscErrorCode ierr; 1931a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1932a3df083aSStefano Zampini 1933a3df083aSStefano Zampini PetscFunctionBegin; 1934a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1935a3df083aSStefano Zampini if (transpose) { 1936a3df083aSStefano Zampini apply_right = ctx->apply_left; 1937a3df083aSStefano Zampini apply_left = ctx->apply_right; 1938a3df083aSStefano Zampini } else { 1939a3df083aSStefano Zampini apply_right = ctx->apply_right; 1940a3df083aSStefano Zampini apply_left = ctx->apply_left; 1941a3df083aSStefano Zampini } 1942a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1943a3df083aSStefano Zampini if (apply_right) { 1944a3df083aSStefano Zampini const PetscScalar *ax; 1945a3df083aSStefano Zampini PetscInt nl,i; 1946a3df083aSStefano Zampini 1947a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1948a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1949*580bdb30SBarry Smith ierr = PetscArraycpy(ctx->work,ax,nl);CHKERRQ(ierr); 1950a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1951a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1952a3df083aSStefano Zampini PetscScalar sum,val; 1953a3df083aSStefano Zampini const PetscInt *idxs; 1954a3df083aSStefano Zampini PetscInt nz,j; 1955a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1956a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1957a3df083aSStefano Zampini sum = 0.; 1958a3df083aSStefano Zampini if (ctx->apply_p0) { 1959a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1960a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1961a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1962a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1963a3df083aSStefano Zampini } 1964a3df083aSStefano Zampini } else { 1965a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1966a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1967a3df083aSStefano Zampini } 1968a3df083aSStefano Zampini } 1969a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1970a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1971a3df083aSStefano Zampini } 1972a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1973a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1974a3df083aSStefano Zampini } 1975a3df083aSStefano Zampini if (transpose) { 1976a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1977a3df083aSStefano Zampini } else { 1978a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1979a3df083aSStefano Zampini } 1980a3df083aSStefano Zampini if (reset_x) { 1981a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1982a3df083aSStefano Zampini } 1983a3df083aSStefano Zampini if (apply_left) { 1984a3df083aSStefano Zampini PetscScalar *ay; 1985a3df083aSStefano Zampini PetscInt i; 1986a3df083aSStefano Zampini 1987a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1988a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1989a3df083aSStefano Zampini PetscScalar sum,val; 1990a3df083aSStefano Zampini const PetscInt *idxs; 1991a3df083aSStefano Zampini PetscInt nz,j; 1992a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1993a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1994a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1995a3df083aSStefano Zampini if (ctx->apply_p0) { 1996a3df083aSStefano Zampini sum = 0.; 1997a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1998a3df083aSStefano Zampini sum += ay[idxs[j]]; 1999a3df083aSStefano Zampini ay[idxs[j]] += val; 2000a3df083aSStefano Zampini } 2001a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 2002a3df083aSStefano Zampini } else { 2003a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 2004a3df083aSStefano Zampini ay[idxs[j]] += val; 2005a3df083aSStefano Zampini } 2006a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 2007a3df083aSStefano Zampini } 2008a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 2009a3df083aSStefano Zampini } 2010a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 2011a3df083aSStefano Zampini } 2012a3df083aSStefano Zampini PetscFunctionReturn(0); 2013a3df083aSStefano Zampini } 2014a3df083aSStefano Zampini 2015a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 2016a3df083aSStefano Zampini { 2017a3df083aSStefano Zampini PetscErrorCode ierr; 2018a3df083aSStefano Zampini 2019a3df083aSStefano Zampini PetscFunctionBegin; 2020a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 2021a3df083aSStefano Zampini PetscFunctionReturn(0); 2022a3df083aSStefano Zampini } 2023a3df083aSStefano Zampini 2024a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 2025a3df083aSStefano Zampini { 2026a3df083aSStefano Zampini PetscErrorCode ierr; 2027a3df083aSStefano Zampini 2028a3df083aSStefano Zampini PetscFunctionBegin; 2029a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 2030a3df083aSStefano Zampini PetscFunctionReturn(0); 2031a3df083aSStefano Zampini } 2032a3df083aSStefano Zampini 2033a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 2034a3df083aSStefano Zampini { 2035a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2036a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2037a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 2038a3df083aSStefano Zampini PetscErrorCode ierr; 2039a3df083aSStefano Zampini 2040a3df083aSStefano Zampini PetscFunctionBegin; 2041a3df083aSStefano Zampini if (!restore) { 20421dd7afcfSStefano Zampini Mat A_IB,A_BI; 2043a3df083aSStefano Zampini PetscScalar *work; 2044b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 2045a3df083aSStefano Zampini 20469a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 20479a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 2048a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 2049a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 2050a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2051a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 2052a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 2053a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 2054a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 2055a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 2056a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 2057a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 2058a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 2059a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 2060059032f7SStefano Zampini if (reuse) { 2061a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 20621dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 2063059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 2064059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 2065059032f7SStefano Zampini PetscInt i; 2066059032f7SStefano Zampini 2067059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 2068059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2069059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2070059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2071059032f7SStefano Zampini } 2072059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 20731dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 2074059032f7SStefano Zampini } 2075a3df083aSStefano Zampini ctx->A = pcis->A_IB; 2076a3df083aSStefano Zampini ctx->work = work; 2077a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 2078a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2079a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2080a3df083aSStefano Zampini pcis->A_IB = A_IB; 2081a3df083aSStefano Zampini 2082a3df083aSStefano Zampini /* A_BI as A_IB^T */ 2083a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 2084a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 2085a3df083aSStefano Zampini pcis->A_BI = A_BI; 2086a3df083aSStefano Zampini } else { 20871dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 20881dd7afcfSStefano Zampini PetscFunctionReturn(0); 20891dd7afcfSStefano Zampini } 2090a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 2091a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 2092a3df083aSStefano Zampini pcis->A_IB = ctx->A; 20931dd7afcfSStefano Zampini ctx->A = NULL; 20941dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 20951dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 20961dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 20971dd7afcfSStefano Zampini if (ctx->free) { 2098059032f7SStefano Zampini PetscInt i; 20991dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 2100059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2101059032f7SStefano Zampini } 2102059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2103059032f7SStefano Zampini } 2104a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 2105a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 2106a3df083aSStefano Zampini } 2107a3df083aSStefano Zampini PetscFunctionReturn(0); 2108a3df083aSStefano Zampini } 2109a3df083aSStefano Zampini 2110a3df083aSStefano Zampini /* used just in bddc debug mode */ 2111a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 2112a3df083aSStefano Zampini { 2113a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2114a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2115a3df083aSStefano Zampini Mat An; 2116a3df083aSStefano Zampini PetscErrorCode ierr; 2117a3df083aSStefano Zampini 2118a3df083aSStefano Zampini PetscFunctionBegin; 2119a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 2120a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 2121a3df083aSStefano Zampini if (is1) { 21227dae84e0SHong Zhang ierr = MatCreateSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 2123a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 2124a3df083aSStefano Zampini } else { 2125a3df083aSStefano Zampini *B = An; 2126a3df083aSStefano Zampini } 2127a3df083aSStefano Zampini PetscFunctionReturn(0); 2128a3df083aSStefano Zampini } 2129a3df083aSStefano Zampini 21301cf9b237SStefano Zampini /* TODO: add reuse flag */ 21311cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 21321cf9b237SStefano Zampini { 21331cf9b237SStefano Zampini Mat Bt; 21341cf9b237SStefano Zampini PetscScalar *a,*bdata; 21351cf9b237SStefano Zampini const PetscInt *ii,*ij; 21361cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 21371cf9b237SStefano Zampini PetscBool flg_row; 21381cf9b237SStefano Zampini PetscErrorCode ierr; 21391cf9b237SStefano Zampini 21401cf9b237SStefano Zampini PetscFunctionBegin; 21411cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 21421cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 21431cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 21441cf9b237SStefano Zampini nnz = n; 21451cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 21461cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 21471cf9b237SStefano Zampini } 21481cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 21491cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 21501cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 21511cf9b237SStefano Zampini nnz = 0; 21521cf9b237SStefano Zampini bii[0] = 0; 21531cf9b237SStefano Zampini for (i=0;i<n;i++) { 21541cf9b237SStefano Zampini PetscInt j; 21551cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 21561cf9b237SStefano Zampini PetscScalar entry = a[j]; 21573272d46bSStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || (n == m && ij[j] == i)) { 21581cf9b237SStefano Zampini bij[nnz] = ij[j]; 21591cf9b237SStefano Zampini bdata[nnz] = entry; 21601cf9b237SStefano Zampini nnz++; 21611cf9b237SStefano Zampini } 21621cf9b237SStefano Zampini } 21631cf9b237SStefano Zampini bii[i+1] = nnz; 21641cf9b237SStefano Zampini } 21651cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 21661cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 21671cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 21681cf9b237SStefano Zampini { 21691cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 21701cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 21711cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 21721cf9b237SStefano Zampini } 21733272d46bSStefano Zampini if (*B == A) { 21743272d46bSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 21753272d46bSStefano Zampini } 21761cf9b237SStefano Zampini *B = Bt; 21771cf9b237SStefano Zampini PetscFunctionReturn(0); 21781cf9b237SStefano Zampini } 21791cf9b237SStefano Zampini 21808361f951SStefano Zampini PetscErrorCode PCBDDCDetectDisconnectedComponents(PC pc, PetscBool filter, PetscInt *ncc, IS* cc[], IS* primalv) 21814f1b2e48SStefano Zampini { 2182c80a6c00SStefano Zampini Mat B = NULL; 2183c80a6c00SStefano Zampini DM dm; 21844f1b2e48SStefano Zampini IS is_dummy,*cc_n; 21854f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 21864f1b2e48SStefano Zampini PCBDDCGraph graph; 2187c80a6c00SStefano Zampini PetscInt *xadj_filtered = NULL,*adjncy_filtered = NULL; 21884f1b2e48SStefano Zampini PetscInt i,n; 21894f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 2190c80a6c00SStefano Zampini PetscBool isplex = PETSC_FALSE; 21914f1b2e48SStefano Zampini PetscErrorCode ierr; 21924f1b2e48SStefano Zampini 21934f1b2e48SStefano Zampini PetscFunctionBegin; 2194a2eca866SStefano Zampini if (ncc) *ncc = 0; 2195a2eca866SStefano Zampini if (cc) *cc = NULL; 2196a2eca866SStefano Zampini if (primalv) *primalv = NULL; 2197c80a6c00SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 2198c80a6c00SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 21994f819b78SStefano Zampini if (!dm) { 22004f819b78SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 2201c80a6c00SStefano Zampini } 2202c80a6c00SStefano Zampini if (dm) { 2203c80a6c00SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&isplex);CHKERRQ(ierr); 2204c80a6c00SStefano Zampini } 22058361f951SStefano Zampini if (filter) isplex = PETSC_FALSE; 22068361f951SStefano Zampini 2207c80a6c00SStefano Zampini if (isplex) { /* this code has been modified from plexpartition.c */ 2208c80a6c00SStefano Zampini PetscInt p, pStart, pEnd, a, adjSize, idx, size, nroots; 2209c80a6c00SStefano Zampini PetscInt *adj = NULL; 2210c80a6c00SStefano Zampini IS cellNumbering; 2211c80a6c00SStefano Zampini const PetscInt *cellNum; 2212c80a6c00SStefano Zampini PetscBool useCone, useClosure; 2213c80a6c00SStefano Zampini PetscSection section; 2214c80a6c00SStefano Zampini PetscSegBuffer adjBuffer; 2215c80a6c00SStefano Zampini PetscSF sfPoint; 2216c80a6c00SStefano Zampini PetscErrorCode ierr; 2217c80a6c00SStefano Zampini 2218c80a6c00SStefano Zampini PetscFunctionBegin; 2219c80a6c00SStefano Zampini ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 2220c80a6c00SStefano Zampini ierr = DMGetPointSF(dm, &sfPoint);CHKERRQ(ierr); 2221c80a6c00SStefano Zampini ierr = PetscSFGetGraph(sfPoint, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 2222c80a6c00SStefano Zampini /* Build adjacency graph via a section/segbuffer */ 2223c80a6c00SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), §ion);CHKERRQ(ierr); 2224c80a6c00SStefano Zampini ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 2225c80a6c00SStefano Zampini ierr = PetscSegBufferCreate(sizeof(PetscInt),1000,&adjBuffer);CHKERRQ(ierr); 2226c80a6c00SStefano Zampini /* Always use FVM adjacency to create partitioner graph */ 2227b0441da4SMatthew G. Knepley ierr = DMGetBasicAdjacency(dm, &useCone, &useClosure);CHKERRQ(ierr); 2228b0441da4SMatthew G. Knepley ierr = DMSetBasicAdjacency(dm, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr); 2229956e2312SStefano Zampini ierr = DMPlexGetCellNumbering(dm, &cellNumbering);CHKERRQ(ierr); 2230c80a6c00SStefano Zampini ierr = ISGetIndices(cellNumbering, &cellNum);CHKERRQ(ierr); 2231c80a6c00SStefano Zampini for (n = 0, p = pStart; p < pEnd; p++) { 2232c80a6c00SStefano Zampini /* Skip non-owned cells in parallel (ParMetis expects no overlap) */ 2233c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2234c80a6c00SStefano Zampini adjSize = PETSC_DETERMINE; 2235c80a6c00SStefano Zampini ierr = DMPlexGetAdjacency(dm, p, &adjSize, &adj);CHKERRQ(ierr); 2236c80a6c00SStefano Zampini for (a = 0; a < adjSize; ++a) { 2237c80a6c00SStefano Zampini const PetscInt point = adj[a]; 22385cef3d0dSStefano Zampini if (pStart <= point && point < pEnd) { 2239c80a6c00SStefano Zampini PetscInt *PETSC_RESTRICT pBuf; 2240c80a6c00SStefano Zampini ierr = PetscSectionAddDof(section, p, 1);CHKERRQ(ierr); 2241c80a6c00SStefano Zampini ierr = PetscSegBufferGetInts(adjBuffer, 1, &pBuf);CHKERRQ(ierr); 2242c80a6c00SStefano Zampini *pBuf = point; 2243c80a6c00SStefano Zampini } 2244c80a6c00SStefano Zampini } 2245c80a6c00SStefano Zampini n++; 2246c80a6c00SStefano Zampini } 2247b0441da4SMatthew G. Knepley ierr = DMSetBasicAdjacency(dm, useCone, useClosure);CHKERRQ(ierr); 2248c80a6c00SStefano Zampini /* Derive CSR graph from section/segbuffer */ 2249c80a6c00SStefano Zampini ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 2250c80a6c00SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 2251c80a6c00SStefano Zampini ierr = PetscMalloc1(n+1, &xadj);CHKERRQ(ierr); 2252c80a6c00SStefano Zampini for (idx = 0, p = pStart; p < pEnd; p++) { 2253c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2254c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(section, p, &(xadj[idx++]));CHKERRQ(ierr); 2255c80a6c00SStefano Zampini } 2256c80a6c00SStefano Zampini xadj[n] = size; 2257c80a6c00SStefano Zampini ierr = PetscSegBufferExtractAlloc(adjBuffer, &adjncy);CHKERRQ(ierr); 2258c80a6c00SStefano Zampini /* Clean up */ 2259c80a6c00SStefano Zampini ierr = PetscSegBufferDestroy(&adjBuffer);CHKERRQ(ierr); 2260c80a6c00SStefano Zampini ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 2261c80a6c00SStefano Zampini ierr = PetscFree(adj);CHKERRQ(ierr); 2262c80a6c00SStefano Zampini graph->xadj = xadj; 2263c80a6c00SStefano Zampini graph->adjncy = adjncy; 2264c80a6c00SStefano Zampini } else { 2265c80a6c00SStefano Zampini Mat A; 22668361f951SStefano Zampini PetscBool isseqaij, flg_row; 2267c80a6c00SStefano Zampini 2268c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 226963c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 2270a2eca866SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 227163c961adSStefano Zampini PetscFunctionReturn(0); 227263c961adSStefano Zampini } 22734f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 22744f1b2e48SStefano Zampini if (!isseqaij && filter) { 22751cf9b237SStefano Zampini PetscBool isseqdense; 22761cf9b237SStefano Zampini 22771cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 22781cf9b237SStefano Zampini if (!isseqdense) { 22794f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 22801cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 22811cf9b237SStefano Zampini PetscScalar *array; 22821cf9b237SStefano Zampini PetscReal chop=1.e-6; 22831cf9b237SStefano Zampini 22841cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 22851cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 22861cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 22871cf9b237SStefano Zampini for (i=0;i<n;i++) { 22881cf9b237SStefano Zampini PetscInt j; 22891cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 22901cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 22911cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 22921cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 22931cf9b237SStefano Zampini } 22941cf9b237SStefano Zampini } 22951cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 22969d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 22971cf9b237SStefano Zampini } 22984f1b2e48SStefano Zampini } else { 2299c80a6c00SStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 23004f1b2e48SStefano Zampini B = A; 23014f1b2e48SStefano Zampini } 23024f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 23034f1b2e48SStefano Zampini 23044f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 23054f1b2e48SStefano Zampini if (filter) { 23064f1b2e48SStefano Zampini PetscScalar *data; 23074f1b2e48SStefano Zampini PetscInt j,cum; 23084f1b2e48SStefano Zampini 23094f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 23104f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 23114f1b2e48SStefano Zampini cum = 0; 23124f1b2e48SStefano Zampini for (i=0;i<n;i++) { 23134f1b2e48SStefano Zampini PetscInt t; 23144f1b2e48SStefano Zampini 23154f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 23164f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 23174f1b2e48SStefano Zampini continue; 23184f1b2e48SStefano Zampini } 23194f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 23204f1b2e48SStefano Zampini } 23214f1b2e48SStefano Zampini t = xadj_filtered[i]; 23224f1b2e48SStefano Zampini xadj_filtered[i] = cum; 23234f1b2e48SStefano Zampini cum += t; 23244f1b2e48SStefano Zampini } 23254f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 23264f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 23274f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 23284f1b2e48SStefano Zampini } else { 23294f1b2e48SStefano Zampini graph->xadj = xadj; 23304f1b2e48SStefano Zampini graph->adjncy = adjncy; 23314f1b2e48SStefano Zampini } 2332c80a6c00SStefano Zampini } 2333c80a6c00SStefano Zampini /* compute local connected components using PCBDDCGraph */ 2334c80a6c00SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 2335c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 2336c80a6c00SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2337c80a6c00SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 2338c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 23394f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 23404f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 2341c80a6c00SStefano Zampini 23424f1b2e48SStefano Zampini /* partial clean up */ 23434f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 2344c80a6c00SStefano Zampini if (B) { 2345c80a6c00SStefano Zampini PetscBool flg_row; 23464f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 23474f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 23484f1b2e48SStefano Zampini } 2349c80a6c00SStefano Zampini if (isplex) { 2350c80a6c00SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 2351c80a6c00SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 2352c80a6c00SStefano Zampini } 23534f1b2e48SStefano Zampini 23544f1b2e48SStefano Zampini /* get back data */ 2355c80a6c00SStefano Zampini if (isplex) { 2356c80a6c00SStefano Zampini if (ncc) *ncc = graph->ncc; 2357c80a6c00SStefano Zampini if (cc || primalv) { 2358c80a6c00SStefano Zampini Mat A; 2359c80a6c00SStefano Zampini PetscBT btv,btvt; 2360c80a6c00SStefano Zampini PetscSection subSection; 2361c80a6c00SStefano Zampini PetscInt *ids,cum,cump,*cids,*pids; 2362c80a6c00SStefano Zampini 2363c80a6c00SStefano Zampini ierr = DMPlexGetSubdomainSection(dm,&subSection);CHKERRQ(ierr); 2364c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 2365c80a6c00SStefano Zampini ierr = PetscMalloc3(A->rmap->n,&ids,graph->ncc+1,&cids,A->rmap->n,&pids);CHKERRQ(ierr); 2366c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btv);CHKERRQ(ierr); 2367c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btvt);CHKERRQ(ierr); 2368c80a6c00SStefano Zampini 2369c80a6c00SStefano Zampini cids[0] = 0; 2370c80a6c00SStefano Zampini for (i = 0, cump = 0, cum = 0; i < graph->ncc; i++) { 2371c80a6c00SStefano Zampini PetscInt j; 2372c80a6c00SStefano Zampini 2373c80a6c00SStefano Zampini ierr = PetscBTMemzero(A->rmap->n,btvt);CHKERRQ(ierr); 2374c80a6c00SStefano Zampini for (j = graph->cptr[i]; j < graph->cptr[i+1]; j++) { 2375c80a6c00SStefano Zampini PetscInt k, size, *closure = NULL, cell = graph->queue[j]; 2376c80a6c00SStefano Zampini 2377c80a6c00SStefano Zampini ierr = DMPlexGetTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2378c80a6c00SStefano Zampini for (k = 0; k < 2*size; k += 2) { 237920c3699dSStefano Zampini PetscInt s, pp, p = closure[k], off, dof, cdof; 2380c80a6c00SStefano Zampini 2381c80a6c00SStefano Zampini ierr = PetscSectionGetConstraintDof(subSection,p,&cdof);CHKERRQ(ierr); 2382c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(subSection,p,&off);CHKERRQ(ierr); 2383c80a6c00SStefano Zampini ierr = PetscSectionGetDof(subSection,p,&dof);CHKERRQ(ierr); 2384c80a6c00SStefano Zampini for (s = 0; s < dof-cdof; s++) { 2385c80a6c00SStefano Zampini if (PetscBTLookupSet(btvt,off+s)) continue; 2386c80a6c00SStefano Zampini if (!PetscBTLookup(btv,off+s)) { 2387c80a6c00SStefano Zampini ids[cum++] = off+s; 2388c80a6c00SStefano Zampini } else { /* cross-vertex */ 2389c80a6c00SStefano Zampini pids[cump++] = off+s; 2390c80a6c00SStefano Zampini } 2391c80a6c00SStefano Zampini } 239220c3699dSStefano Zampini ierr = DMPlexGetTreeParent(dm,p,&pp,NULL);CHKERRQ(ierr); 239320c3699dSStefano Zampini if (pp != p) { 239420c3699dSStefano Zampini ierr = PetscSectionGetConstraintDof(subSection,pp,&cdof);CHKERRQ(ierr); 239520c3699dSStefano Zampini ierr = PetscSectionGetOffset(subSection,pp,&off);CHKERRQ(ierr); 239620c3699dSStefano Zampini ierr = PetscSectionGetDof(subSection,pp,&dof);CHKERRQ(ierr); 239720c3699dSStefano Zampini for (s = 0; s < dof-cdof; s++) { 239820c3699dSStefano Zampini if (PetscBTLookupSet(btvt,off+s)) continue; 239920c3699dSStefano Zampini if (!PetscBTLookup(btv,off+s)) { 240020c3699dSStefano Zampini ids[cum++] = off+s; 240120c3699dSStefano Zampini } else { /* cross-vertex */ 240220c3699dSStefano Zampini pids[cump++] = off+s; 240320c3699dSStefano Zampini } 240420c3699dSStefano Zampini } 240520c3699dSStefano Zampini } 2406c80a6c00SStefano Zampini } 2407c80a6c00SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2408c80a6c00SStefano Zampini } 2409c80a6c00SStefano Zampini cids[i+1] = cum; 2410c80a6c00SStefano Zampini /* mark dofs as already assigned */ 2411c80a6c00SStefano Zampini for (j = cids[i]; j < cids[i+1]; j++) { 2412c80a6c00SStefano Zampini ierr = PetscBTSet(btv,ids[j]);CHKERRQ(ierr); 2413c80a6c00SStefano Zampini } 2414c80a6c00SStefano Zampini } 2415c80a6c00SStefano Zampini if (cc) { 2416c80a6c00SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 2417c80a6c00SStefano Zampini for (i = 0; i < graph->ncc; i++) { 2418c80a6c00SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cids[i+1]-cids[i],ids+cids[i],PETSC_COPY_VALUES,&cc_n[i]);CHKERRQ(ierr); 2419c80a6c00SStefano Zampini } 2420c80a6c00SStefano Zampini *cc = cc_n; 2421c80a6c00SStefano Zampini } 2422c80a6c00SStefano Zampini if (primalv) { 2423c80a6c00SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),cump,pids,PETSC_COPY_VALUES,primalv);CHKERRQ(ierr); 2424c80a6c00SStefano Zampini } 2425c80a6c00SStefano Zampini ierr = PetscFree3(ids,cids,pids);CHKERRQ(ierr); 2426c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 2427c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btvt);CHKERRQ(ierr); 2428c80a6c00SStefano Zampini } 2429c80a6c00SStefano Zampini } else { 24301cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 24311cf9b237SStefano Zampini if (cc) { 24324f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 24334f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 24344f1b2e48SStefano 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); 24354f1b2e48SStefano Zampini } 24364f1b2e48SStefano Zampini *cc = cc_n; 24371cf9b237SStefano Zampini } 2438c80a6c00SStefano Zampini } 24394f1b2e48SStefano Zampini /* clean up graph */ 24404f1b2e48SStefano Zampini graph->xadj = 0; 24414f1b2e48SStefano Zampini graph->adjncy = 0; 24424f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 24434f1b2e48SStefano Zampini PetscFunctionReturn(0); 24444f1b2e48SStefano Zampini } 24454f1b2e48SStefano Zampini 24465408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 24475408967cSStefano Zampini { 24485408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 24495408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2450dee84bffSStefano Zampini IS dirIS = NULL; 24514f1b2e48SStefano Zampini PetscInt i; 24525408967cSStefano Zampini PetscErrorCode ierr; 24535408967cSStefano Zampini 24545408967cSStefano Zampini PetscFunctionBegin; 2455dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 24565408967cSStefano Zampini if (zerodiag) { 24575408967cSStefano Zampini Mat A; 24585408967cSStefano Zampini Vec vec3_N; 24595408967cSStefano Zampini PetscScalar *vals; 24605408967cSStefano Zampini const PetscInt *idxs; 2461d12d3064SStefano Zampini PetscInt nz,*count; 24625408967cSStefano Zampini 24635408967cSStefano Zampini /* p0 */ 24645408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 24655408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 24665408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 24675408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 24684f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 24695408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24705408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 24715408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 24725408967cSStefano Zampini /* v_I */ 24735408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 24745408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 24755408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24765408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 24775408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24785408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 24795408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24805408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24815408967cSStefano Zampini if (dirIS) { 24825408967cSStefano Zampini PetscInt n; 24835408967cSStefano Zampini 24845408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 24855408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 24865408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 24875408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24885408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 24895408967cSStefano Zampini } 24905408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 24915408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 24925408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 24935408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2494669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 24955408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 24965408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 24979a962809SStefano 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])); 24985408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 24995408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2500d12d3064SStefano Zampini 2501d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2502d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2503d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2504d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2505d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2506d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 25076080607fSStefano 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]); 2508d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2509d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 25105408967cSStefano Zampini } 2511dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 25125408967cSStefano Zampini 25135408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 25145408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 25154f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 25165408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 25174f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 25185408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2519f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2520f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 25216080607fSStefano Zampini if (val != -PetscGlobalRank-i) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error testing PCBDDCBenignGetOrSetP0! Found %g at %D instead of %g",PetscRealPart(pcbddc->benign_p0[i]),i,-PetscGlobalRank-i); 2522f2a566d8SStefano Zampini } 25235408967cSStefano Zampini PetscFunctionReturn(0); 25245408967cSStefano Zampini } 25255408967cSStefano Zampini 25263b03f7bbSStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, PetscBool reuse, IS *zerodiaglocal) 2527339f8db1SStefano Zampini { 2528339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 25293b03f7bbSStefano Zampini IS pressures = NULL,zerodiag = NULL,*bzerodiag = NULL,zerodiag_save,*zerodiag_subs; 25303b03f7bbSStefano Zampini PetscInt nz,n,benign_n,bsp = 1; 25314edc6404Sstefano_zampini PetscInt *interior_dofs,n_interior_dofs,nneu; 25324edc6404Sstefano_zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag,checkb; 2533339f8db1SStefano Zampini PetscErrorCode ierr; 2534339f8db1SStefano Zampini 2535339f8db1SStefano Zampini PetscFunctionBegin; 25363b03f7bbSStefano Zampini if (reuse) goto project_b0; 25379f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 25389f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2539a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2540a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2541a3df083aSStefano Zampini } 2542a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 25433b03f7bbSStefano Zampini has_null_pressures = PETSC_TRUE; 25443b03f7bbSStefano Zampini have_null = PETSC_TRUE; 25453b03f7bbSStefano Zampini /* if a local information on dofs is present, gets pressure dofs from command line (uses the last field is not provided) 25463b03f7bbSStefano Zampini Without local information, it uses only the zerodiagonal dofs (ok if the pressure block is all zero and it is a scalar field) 25474f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 25484f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 25491ae86dd6SStefano Zampini since the local Schur complements are already SPD 25504f1b2e48SStefano Zampini */ 255140fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 25527fbe2174Sstefano_zampini IS iP = NULL; 25533b03f7bbSStefano Zampini PetscInt p,*pp; 25543b03f7bbSStefano Zampini PetscBool flg; 25554f1b2e48SStefano Zampini 25563b03f7bbSStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pp);CHKERRQ(ierr); 25573b03f7bbSStefano Zampini n = pcbddc->n_ISForDofsLocal; 255828b8efb1Sstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC benign options","PC");CHKERRQ(ierr); 25593b03f7bbSStefano Zampini ierr = PetscOptionsIntArray("-pc_bddc_pressure_field","Field id for pressures",NULL,pp,&n,&flg);CHKERRQ(ierr); 256028b8efb1Sstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 25613b03f7bbSStefano Zampini if (!flg) { 25623b03f7bbSStefano Zampini n = 1; 25633b03f7bbSStefano Zampini pp[0] = pcbddc->n_ISForDofsLocal-1; 25643b03f7bbSStefano Zampini } 25653b03f7bbSStefano Zampini 25663b03f7bbSStefano Zampini bsp = 0; 25673b03f7bbSStefano Zampini for (p=0;p<n;p++) { 25683b03f7bbSStefano Zampini PetscInt bs; 25693b03f7bbSStefano Zampini 25703b03f7bbSStefano Zampini if (pp[p] < 0 || pp[p] > pcbddc->n_ISForDofsLocal-1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Invalid field id for pressures %D",pp[p]); 25713b03f7bbSStefano Zampini ierr = ISGetBlockSize(pcbddc->ISForDofsLocal[pp[p]],&bs);CHKERRQ(ierr); 25723b03f7bbSStefano Zampini bsp += bs; 25733b03f7bbSStefano Zampini } 25743b03f7bbSStefano Zampini ierr = PetscMalloc1(bsp,&bzerodiag);CHKERRQ(ierr); 25753b03f7bbSStefano Zampini bsp = 0; 25763b03f7bbSStefano Zampini for (p=0;p<n;p++) { 25773b03f7bbSStefano Zampini const PetscInt *idxs; 25783b03f7bbSStefano Zampini PetscInt b,bs,npl,*bidxs; 25793b03f7bbSStefano Zampini 25803b03f7bbSStefano Zampini ierr = ISGetBlockSize(pcbddc->ISForDofsLocal[pp[p]],&bs);CHKERRQ(ierr); 25813b03f7bbSStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[pp[p]],&npl);CHKERRQ(ierr); 25823b03f7bbSStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[pp[p]],&idxs);CHKERRQ(ierr); 25833b03f7bbSStefano Zampini ierr = PetscMalloc1(npl/bs,&bidxs);CHKERRQ(ierr); 25843b03f7bbSStefano Zampini for (b=0;b<bs;b++) { 25853b03f7bbSStefano Zampini PetscInt i; 25863b03f7bbSStefano Zampini 25873b03f7bbSStefano Zampini for (i=0;i<npl/bs;i++) bidxs[i] = idxs[bs*i+b]; 25883b03f7bbSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl/bs,bidxs,PETSC_COPY_VALUES,&bzerodiag[bsp]);CHKERRQ(ierr); 25893b03f7bbSStefano Zampini bsp++; 25903b03f7bbSStefano Zampini } 25913b03f7bbSStefano Zampini ierr = PetscFree(bidxs);CHKERRQ(ierr); 25923b03f7bbSStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[pp[p]],&idxs);CHKERRQ(ierr); 25933b03f7bbSStefano Zampini } 25943b03f7bbSStefano Zampini ierr = ISConcatenate(PETSC_COMM_SELF,bsp,bzerodiag,&pressures);CHKERRQ(ierr); 25953b03f7bbSStefano Zampini 25967fbe2174Sstefano_zampini /* remove zeroed out pressures if we are setting up a BDDC solver for a saddle-point FETI-DP */ 25977fbe2174Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP",(PetscObject*)&iP);CHKERRQ(ierr); 25987fbe2174Sstefano_zampini if (iP) { 25997fbe2174Sstefano_zampini IS newpressures; 26007fbe2174Sstefano_zampini 26017fbe2174Sstefano_zampini ierr = ISDifference(pressures,iP,&newpressures);CHKERRQ(ierr); 26027fbe2174Sstefano_zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 26037fbe2174Sstefano_zampini pressures = newpressures; 26047fbe2174Sstefano_zampini } 260540fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 260640fa8d13SStefano Zampini if (!sorted) { 260740fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 260840fa8d13SStefano Zampini } 26093b03f7bbSStefano Zampini ierr = PetscFree(pp);CHKERRQ(ierr); 261040fa8d13SStefano Zampini } 26113b03f7bbSStefano Zampini 261297d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 261397d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 261427b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 261597d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2616339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2617339f8db1SStefano Zampini if (!sorted) { 2618339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2619339f8db1SStefano Zampini } 26204edc6404Sstefano_zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 26214edc6404Sstefano_zampini zerodiag_save = zerodiag; 2622339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 26234f1b2e48SStefano Zampini if (!nz) { 26244f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 26254f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 262640fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 262740fa8d13SStefano Zampini } 26284f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 26293b03f7bbSStefano Zampini 26304f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 26314f1b2e48SStefano Zampini zerodiag_subs = NULL; 26323b03f7bbSStefano Zampini benign_n = 0; 26331f4df5f7SStefano Zampini n_interior_dofs = 0; 26341f4df5f7SStefano Zampini interior_dofs = NULL; 26354edc6404Sstefano_zampini nneu = 0; 26364edc6404Sstefano_zampini if (pcbddc->NeumannBoundariesLocal) { 26374edc6404Sstefano_zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nneu);CHKERRQ(ierr); 26384edc6404Sstefano_zampini } 26393369cb78Sstefano_zampini checkb = (PetscBool)(!pcbddc->NeumannBoundariesLocal || pcbddc->current_level); 26404edc6404Sstefano_zampini if (checkb) { /* need to compute interior nodes */ 26411f4df5f7SStefano Zampini PetscInt n,i,j; 26421f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 26431f4df5f7SStefano Zampini PetscInt *iwork; 26441f4df5f7SStefano Zampini 26451f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 26461f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 26471f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 26481f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 264990648384SStefano Zampini for (i=1;i<n_neigh;i++) 26501f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 26511f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 26521f4df5f7SStefano Zampini for (i=0;i<n;i++) 26531f4df5f7SStefano Zampini if (!iwork[i]) 26541f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 26551f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 26561f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 26571f4df5f7SStefano Zampini } 26584f1b2e48SStefano Zampini if (has_null_pressures) { 26594f1b2e48SStefano Zampini IS *subs; 26604edc6404Sstefano_zampini PetscInt nsubs,i,j,nl; 26611f4df5f7SStefano Zampini const PetscInt *idxs; 26621f4df5f7SStefano Zampini PetscScalar *array; 26631f4df5f7SStefano Zampini Vec *work; 26641f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 26654f1b2e48SStefano Zampini 26664f1b2e48SStefano Zampini subs = pcbddc->local_subs; 26674f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 26681f4df5f7SStefano 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) */ 26694edc6404Sstefano_zampini if (checkb) { 26701f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 26711f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 26721f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 26731f4df5f7SStefano Zampini /* work[0] = 1_p */ 26741f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 26751f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 26761f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 26771f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 26781f4df5f7SStefano Zampini /* work[0] = 1_v */ 26791f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 26801f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 26811f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 26821f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 26831f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 26841f4df5f7SStefano Zampini } 26853b03f7bbSStefano Zampini 26863b03f7bbSStefano Zampini if (nsubs > 1 || bsp > 1) { 26873b03f7bbSStefano Zampini IS *is; 26883b03f7bbSStefano Zampini PetscInt b,totb; 26893b03f7bbSStefano Zampini 26903b03f7bbSStefano Zampini totb = bsp; 26913b03f7bbSStefano Zampini is = bsp > 1 ? bzerodiag : &zerodiag; 26923b03f7bbSStefano Zampini nsubs = PetscMax(nsubs,1); 26933b03f7bbSStefano Zampini ierr = PetscCalloc1(nsubs*totb,&zerodiag_subs);CHKERRQ(ierr); 26943b03f7bbSStefano Zampini for (b=0;b<totb;b++) { 26954f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 26964f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 26974f1b2e48SStefano Zampini IS t_zerodiag_subs; 26984f1b2e48SStefano Zampini PetscInt nl; 26994f1b2e48SStefano Zampini 27003b03f7bbSStefano Zampini if (subs) { 27014f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 27023b03f7bbSStefano Zampini } else { 27033b03f7bbSStefano Zampini IS tis; 27043b03f7bbSStefano Zampini 27053b03f7bbSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&nl,NULL);CHKERRQ(ierr); 27063b03f7bbSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nl,0,1,&tis);CHKERRQ(ierr); 27073b03f7bbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(tis,&l2g);CHKERRQ(ierr); 27083b03f7bbSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 27093b03f7bbSStefano Zampini } 27103b03f7bbSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,is[b],&t_zerodiag_subs);CHKERRQ(ierr); 27114f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 27124f1b2e48SStefano Zampini if (nl) { 27134f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 27144f1b2e48SStefano Zampini 27154edc6404Sstefano_zampini if (checkb) { 27161f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 27171f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 27181f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 27191f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 27201f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 27211f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 27221f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 27231f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 27241f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 27251f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 27261f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 27271f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 27281f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 27291f4df5f7SStefano Zampini valid = PETSC_FALSE; 27301f4df5f7SStefano Zampini break; 27311f4df5f7SStefano Zampini } 27321f4df5f7SStefano Zampini } 27331f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 27341f4df5f7SStefano Zampini } 27356632bad2Sstefano_zampini if (valid && nneu) { 27366632bad2Sstefano_zampini const PetscInt *idxs; 27371f4df5f7SStefano Zampini PetscInt nzb; 27381f4df5f7SStefano Zampini 27396632bad2Sstefano_zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 27406632bad2Sstefano_zampini ierr = ISGlobalToLocalMappingApply(l2g,IS_GTOLM_DROP,nneu,idxs,&nzb,NULL);CHKERRQ(ierr); 27416632bad2Sstefano_zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 27421f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 27431f4df5f7SStefano Zampini } 27441f4df5f7SStefano Zampini if (valid && pressures) { 27453b03f7bbSStefano Zampini IS t_pressure_subs,tmp; 27463b03f7bbSStefano Zampini PetscInt i1,i2; 27473b03f7bbSStefano Zampini 27484f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 27493b03f7bbSStefano Zampini ierr = ISEmbed(t_zerodiag_subs,t_pressure_subs,PETSC_TRUE,&tmp);CHKERRQ(ierr); 27503b03f7bbSStefano Zampini ierr = ISGetLocalSize(tmp,&i1);CHKERRQ(ierr); 27513b03f7bbSStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&i2);CHKERRQ(ierr); 27523b03f7bbSStefano Zampini if (i2 != i1) valid = PETSC_FALSE; 27534f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 27543b03f7bbSStefano Zampini ierr = ISDestroy(&tmp);CHKERRQ(ierr); 27554f1b2e48SStefano Zampini } 27564f1b2e48SStefano Zampini if (valid) { 27573b03f7bbSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[benign_n]);CHKERRQ(ierr); 27583b03f7bbSStefano Zampini benign_n++; 27593b03f7bbSStefano Zampini } else recompute_zerodiag = PETSC_TRUE; 27604f1b2e48SStefano Zampini } 27614f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 27624f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 27634f1b2e48SStefano Zampini } 27643b03f7bbSStefano Zampini } 27654f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 27664f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 27671f4df5f7SStefano Zampini 27686632bad2Sstefano_zampini if (nneu) valid = PETSC_FALSE; 27691f4df5f7SStefano Zampini if (valid && pressures) { 27704f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 27714f1b2e48SStefano Zampini } 27724edc6404Sstefano_zampini if (valid && checkb) { 27731f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 27741f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 27751f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 27761f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 27771f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 27781f4df5f7SStefano Zampini valid = PETSC_FALSE; 27791f4df5f7SStefano Zampini break; 27801f4df5f7SStefano Zampini } 27811f4df5f7SStefano Zampini } 27821f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 27831f4df5f7SStefano Zampini } 27844f1b2e48SStefano Zampini if (valid) { 27853b03f7bbSStefano Zampini benign_n = 1; 27863b03f7bbSStefano Zampini ierr = PetscMalloc1(benign_n,&zerodiag_subs);CHKERRQ(ierr); 27874f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 27884f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 27894f1b2e48SStefano Zampini } 27904f1b2e48SStefano Zampini } 27914edc6404Sstefano_zampini if (checkb) { 27921f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 27934f1b2e48SStefano Zampini } 27941f4df5f7SStefano Zampini } 27951f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 27964f1b2e48SStefano Zampini 27973b03f7bbSStefano Zampini if (!benign_n) { 2798b9b0e38cSStefano Zampini PetscInt n; 2799b9b0e38cSStefano Zampini 28004f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 28014f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2802b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 280376a58201SStefano Zampini if (n) have_null = PETSC_FALSE; 2804b9b0e38cSStefano Zampini } 28054f1b2e48SStefano Zampini 28064f1b2e48SStefano Zampini /* final check for null pressures */ 28074f1b2e48SStefano Zampini if (zerodiag && pressures) { 28083b03f7bbSStefano Zampini ierr = ISEqual(pressures,zerodiag,&have_null);CHKERRQ(ierr); 28094f1b2e48SStefano Zampini } 28104f1b2e48SStefano Zampini 28114f1b2e48SStefano Zampini if (recompute_zerodiag) { 28124f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 28133b03f7bbSStefano Zampini if (benign_n == 1) { 28144f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 28154f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 28164f1b2e48SStefano Zampini } else { 28174f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 28184f1b2e48SStefano Zampini 28194f1b2e48SStefano Zampini nzn = 0; 28203b03f7bbSStefano Zampini for (i=0;i<benign_n;i++) { 28214f1b2e48SStefano Zampini PetscInt ns; 28224f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 28234f1b2e48SStefano Zampini nzn += ns; 28244f1b2e48SStefano Zampini } 28254f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 28264f1b2e48SStefano Zampini nzn = 0; 28273b03f7bbSStefano Zampini for (i=0;i<benign_n;i++) { 28284f1b2e48SStefano Zampini PetscInt ns,*idxs; 28294f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 28304f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2831*580bdb30SBarry Smith ierr = PetscArraycpy(new_idxs+nzn,idxs,ns);CHKERRQ(ierr); 28324f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 28334f1b2e48SStefano Zampini nzn += ns; 28344f1b2e48SStefano Zampini } 28354f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 28364f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 28374f1b2e48SStefano Zampini } 28384f1b2e48SStefano Zampini have_null = PETSC_FALSE; 28394f1b2e48SStefano Zampini } 28404f1b2e48SStefano Zampini 28413b03f7bbSStefano Zampini /* determines if the coarse solver will be singular or not */ 28423b03f7bbSStefano Zampini ierr = MPIU_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 28433b03f7bbSStefano Zampini 2844669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2845a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2846a198735bSStefano Zampini Mat A,loc_divudotp; 2847a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2848a198735bSStefano Zampini IS row,col,isused = NULL; 2849a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2850a198735bSStefano Zampini 28511f4df5f7SStefano Zampini if (pressures) { 28521f4df5f7SStefano Zampini isused = pressures; 28531f4df5f7SStefano Zampini } else { 28544edc6404Sstefano_zampini isused = zerodiag_save; 28551f4df5f7SStefano Zampini } 2856a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2857669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 28581ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 28591ae86dd6SStefano 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"); 2860a198735bSStefano Zampini n_isused = 0; 2861a198735bSStefano Zampini if (isused) { 2862a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2863a198735bSStefano Zampini } 2864a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2865a198735bSStefano Zampini st = st-n_isused; 28661ae86dd6SStefano Zampini if (n) { 2867a198735bSStefano Zampini const PetscInt *gidxs; 2868a198735bSStefano Zampini 28697dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2870a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2871a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2872a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2873a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2874a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 28751ae86dd6SStefano Zampini } else { 2876a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2877a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2878a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2879a198735bSStefano Zampini } 2880a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2881a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2882a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2883a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2884a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2885a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2886a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2887a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2888a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2889a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2890a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2891a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2892a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2893a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 28941ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28951ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28961ae86dd6SStefano Zampini } 28974edc6404Sstefano_zampini ierr = ISDestroy(&zerodiag_save);CHKERRQ(ierr); 28983b03f7bbSStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 28993b03f7bbSStefano Zampini if (bzerodiag) { 29003b03f7bbSStefano Zampini PetscInt i; 2901b3afcdbeSStefano Zampini 29023b03f7bbSStefano Zampini for (i=0;i<bsp;i++) { 29033b03f7bbSStefano Zampini ierr = ISDestroy(&bzerodiag[i]);CHKERRQ(ierr); 29043b03f7bbSStefano Zampini } 29053b03f7bbSStefano Zampini ierr = PetscFree(bzerodiag);CHKERRQ(ierr); 29063b03f7bbSStefano Zampini } 29073b03f7bbSStefano Zampini pcbddc->benign_n = benign_n; 29083b03f7bbSStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 29093b03f7bbSStefano Zampini 29103b03f7bbSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 29113b03f7bbSStefano Zampini have_null = (PetscBool)(!!pcbddc->benign_n); 29123b03f7bbSStefano Zampini ierr = MPIU_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 29133b03f7bbSStefano Zampini 29143b03f7bbSStefano Zampini project_b0: 2915aa0d93e9SStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2916b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 29173b03f7bbSStefano Zampini if (pcbddc->benign_n) { 29184f1b2e48SStefano Zampini PetscInt i,s,*nnz; 29194f1b2e48SStefano Zampini 2920339f8db1SStefano Zampini /* local change of basis for pressures */ 2921339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 292297d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2923339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2924339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2925339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 2926aa0d93e9SStefano Zampini for (i=0;i<n;i++) nnz[i] = 1; /* defaults to identity */ 29274f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2928aa0d93e9SStefano Zampini const PetscInt *idxs; 29294f1b2e48SStefano Zampini PetscInt nzs,j; 29304f1b2e48SStefano Zampini 29313b03f7bbSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nzs);CHKERRQ(ierr); 29323b03f7bbSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 29334f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 29344f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 29353b03f7bbSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 29364f1b2e48SStefano Zampini } 2937339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2938e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->benign_change,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 2939339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2940aa0d93e9SStefano Zampini /* set identity by default */ 2941aa0d93e9SStefano Zampini for (i=0;i<n;i++) { 2942aa0d93e9SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,i,i,1.,INSERT_VALUES);CHKERRQ(ierr); 2943339f8db1SStefano Zampini } 29449f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 29454f1b2e48SStefano 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); 2946339f8db1SStefano Zampini /* set change on pressures */ 29474f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 29484f1b2e48SStefano Zampini PetscScalar *array; 2949aa0d93e9SStefano Zampini const PetscInt *idxs; 29504f1b2e48SStefano Zampini PetscInt nzs; 29514f1b2e48SStefano Zampini 29523b03f7bbSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[s],&nzs);CHKERRQ(ierr); 29533b03f7bbSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[s],&idxs);CHKERRQ(ierr); 29544f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2955339f8db1SStefano Zampini PetscScalar vals[2]; 2956339f8db1SStefano Zampini PetscInt cols[2]; 2957339f8db1SStefano Zampini 2958339f8db1SStefano Zampini cols[0] = idxs[i]; 29594f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2960339f8db1SStefano Zampini vals[0] = 1.; 2961b0f5fe93SStefano Zampini vals[1] = 1.; 29624f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2963339f8db1SStefano Zampini } 29644f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 29654f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 29664f1b2e48SStefano Zampini array[nzs-1] = 1.; 29674f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 29684f1b2e48SStefano Zampini /* store local idxs for p0 */ 29694f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 29703b03f7bbSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2971339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 29724f1b2e48SStefano Zampini } 2973339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2974339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 29753b03f7bbSStefano Zampini 2976a3df083aSStefano Zampini /* project if needed */ 2977a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 29781dd7afcfSStefano Zampini Mat M; 29791dd7afcfSStefano Zampini 29801dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2981339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 29821dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 29831dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2984a3df083aSStefano Zampini } 29854f1b2e48SStefano Zampini /* store global idxs for p0 */ 29864f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2987339f8db1SStefano Zampini } 2988339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2989339f8db1SStefano Zampini PetscFunctionReturn(0); 2990339f8db1SStefano Zampini } 2991339f8db1SStefano Zampini 2992015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2993efc2fbd9SStefano Zampini { 2994efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2995de9d7bd0SStefano Zampini PetscScalar *array; 2996efc2fbd9SStefano Zampini PetscErrorCode ierr; 2997efc2fbd9SStefano Zampini 2998efc2fbd9SStefano Zampini PetscFunctionBegin; 2999efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 3000efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 30014f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 3002efc2fbd9SStefano Zampini } 3003de9d7bd0SStefano Zampini if (get) { 3004efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 30054f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 30064f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 3007efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 3008de9d7bd0SStefano Zampini } else { 3009de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 3010de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 3011de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 3012de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 3013efc2fbd9SStefano Zampini } 3014efc2fbd9SStefano Zampini PetscFunctionReturn(0); 3015efc2fbd9SStefano Zampini } 3016efc2fbd9SStefano Zampini 3017c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 3018c263805aSStefano Zampini { 3019c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3020c263805aSStefano Zampini PetscErrorCode ierr; 3021c263805aSStefano Zampini 3022c263805aSStefano Zampini PetscFunctionBegin; 3023c263805aSStefano Zampini /* TODO: add error checking 3024c263805aSStefano Zampini - avoid nested pop (or push) calls. 3025c263805aSStefano Zampini - cannot push before pop. 30261c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 3027c263805aSStefano Zampini */ 30284f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 3029efc2fbd9SStefano Zampini PetscFunctionReturn(0); 3030efc2fbd9SStefano Zampini } 3031c263805aSStefano Zampini if (pop) { 3032a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 30334f1b2e48SStefano Zampini IS is_p0; 30344f1b2e48SStefano Zampini MatReuse reuse; 3035c263805aSStefano Zampini 3036c263805aSStefano Zampini /* extract B_0 */ 30374f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 30384f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 30394f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 30404f1b2e48SStefano Zampini } 30414f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 30427dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 3043c263805aSStefano Zampini /* remove rows and cols from local problem */ 3044c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 304597d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 30464f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 30474f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 3048a3df083aSStefano Zampini } else { 3049a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 3050a3df083aSStefano Zampini PetscScalar *vals; 3051a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 3052a3df083aSStefano Zampini 3053a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 3054a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 3055a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 30560b5adadeSStefano Zampini PetscInt *nnz; 3057a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 3058a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 3059a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 3060331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 3061331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3062331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 3063331e053bSStefano Zampini nnz[i] = n - nnz[i]; 3064331e053bSStefano Zampini } 3065331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 3066e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->benign_B0,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3067331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3068331e053bSStefano Zampini } 3069a3df083aSStefano Zampini 3070a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3071a3df083aSStefano Zampini PetscScalar *array; 3072a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 3073a3df083aSStefano Zampini 3074a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 3075a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3076a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 3077a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 3078a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 3079a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 3080a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 3081a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 3082a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 3083a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 3084a3df083aSStefano Zampini cum = 0; 3085a3df083aSStefano Zampini for (j=0;j<n;j++) { 308622db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 3087a3df083aSStefano Zampini vals[cum] = array[j]; 3088a3df083aSStefano Zampini idxs_ins[cum] = j; 3089a3df083aSStefano Zampini cum++; 3090a3df083aSStefano Zampini } 3091a3df083aSStefano Zampini } 3092a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 3093a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 3094a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 3095a3df083aSStefano Zampini } 3096a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3097a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3098a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 3099a3df083aSStefano Zampini } 3100c263805aSStefano Zampini } else { /* push */ 3101a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 31024f1b2e48SStefano Zampini PetscInt i; 31034f1b2e48SStefano Zampini 31044f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 31054f1b2e48SStefano Zampini PetscScalar *B0_vals; 31064f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 31074f1b2e48SStefano Zampini 31084f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 31094f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 31107b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 31114f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 31124f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 31134f1b2e48SStefano Zampini } 3114c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3115c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 31166080607fSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!"); 3117c263805aSStefano Zampini } 3118c263805aSStefano Zampini PetscFunctionReturn(0); 3119c263805aSStefano Zampini } 3120c263805aSStefano Zampini 312108122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 3122b1b3d7a2SStefano Zampini { 3123b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 312408122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 312508122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 312608122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 312708122e43SStefano Zampini PetscScalar *work,lwork; 312808122e43SStefano Zampini PetscScalar *St,*S,*eigv; 312908122e43SStefano Zampini PetscScalar *Sarray,*Starray; 3130bd2a564bSStefano Zampini PetscReal *eigs,thresh,lthresh,uthresh; 31311b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 3132f6f667cfSStefano Zampini PetscBool allocated_S_St; 313308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 313408122e43SStefano Zampini PetscReal *rwork; 313508122e43SStefano Zampini #endif 3136b1b3d7a2SStefano Zampini PetscErrorCode ierr; 3137b1b3d7a2SStefano Zampini 3138b1b3d7a2SStefano Zampini PetscFunctionBegin; 3139b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 3140af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 3141bd2a564bSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_symmetric)) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adaptive selection not yet implemented for this matrix pencil (herm %d, symm %d, posdef %d)",sub_schurs->is_hermitian,sub_schurs->is_symmetric,sub_schurs->is_posdef); 314243371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_AdaptiveSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 314306a4e24aSStefano Zampini 3144fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3145fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3146fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3147fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 31481575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3149fd14bc51SStefano Zampini } 3150fd14bc51SStefano Zampini 3151e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 31526080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d cc %D (%d,%d).\n",PetscGlobalRank,sub_schurs->n_subs,sub_schurs->is_hermitian,sub_schurs->is_posdef);CHKERRQ(ierr); 3153e496cd5dSStefano Zampini } 3154e496cd5dSStefano Zampini 315508122e43SStefano Zampini /* max size of subsets */ 315608122e43SStefano Zampini mss = 0; 315708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 315808122e43SStefano Zampini PetscInt subset_size; 3159862806e4SStefano Zampini 316008122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 316108122e43SStefano Zampini mss = PetscMax(mss,subset_size); 316208122e43SStefano Zampini } 316308122e43SStefano Zampini 316408122e43SStefano Zampini /* min/max and threshold */ 316508122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 3166f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 316708122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 3168f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 3169bd2a564bSStefano Zampini if (nmin || !sub_schurs->is_posdef) { /* XXX */ 3170f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 3171f6f667cfSStefano Zampini } 317208122e43SStefano Zampini 317308122e43SStefano Zampini /* allocate lapack workspace */ 317408122e43SStefano Zampini cum = cum2 = 0; 317508122e43SStefano Zampini maxneigs = 0; 317608122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 317708122e43SStefano Zampini PetscInt n,subset_size; 3178f6f667cfSStefano Zampini 317908122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 318008122e43SStefano Zampini n = PetscMin(subset_size,nmax); 31819162d606SStefano Zampini cum += subset_size; 31829162d606SStefano Zampini cum2 += subset_size*n; 318308122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 318408122e43SStefano Zampini } 318508122e43SStefano Zampini if (mss) { 3186bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 318708122e43SStefano Zampini PetscBLASInt B_itype = 1; 318808122e43SStefano Zampini PetscBLASInt B_N = mss; 31894c6709b3SStefano Zampini PetscReal zero = 0.0; 31904c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 319108122e43SStefano Zampini 319208122e43SStefano Zampini B_lwork = -1; 319308122e43SStefano Zampini S = NULL; 319408122e43SStefano Zampini St = NULL; 3195a58a30b4SStefano Zampini eigs = NULL; 3196a58a30b4SStefano Zampini eigv = NULL; 3197a58a30b4SStefano Zampini B_iwork = NULL; 3198a58a30b4SStefano Zampini B_ifail = NULL; 3199d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3200d1710679SStefano Zampini rwork = NULL; 3201d1710679SStefano Zampini #endif 32028bec7fa6SStefano Zampini thresh = 1.0; 320308122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 320408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 320508122e43SStefano 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)); 320608122e43SStefano Zampini #else 320708122e43SStefano 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)); 320808122e43SStefano Zampini #endif 320908122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 321008122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3211bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 321208122e43SStefano Zampini } else { 321308122e43SStefano Zampini lwork = 0; 321408122e43SStefano Zampini } 321508122e43SStefano Zampini 321608122e43SStefano Zampini nv = 0; 3217d62866d3SStefano 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) */ 3218d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 321908122e43SStefano Zampini } 32204c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 3221f6f667cfSStefano Zampini if (allocated_S_St) { 3222f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 3223f6f667cfSStefano Zampini } 3224f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 322508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 322608122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 322708122e43SStefano Zampini #endif 32289162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 32299162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 32309162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 323108122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 32329162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 3233*580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->adaptive_constraints_n,nv+sub_schurs->n_subs);CHKERRQ(ierr); 323408122e43SStefano Zampini 323508122e43SStefano Zampini maxneigs = 0; 323672b8c272SStefano Zampini cum = cumarray = 0; 32379162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 32389162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 3239d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 324008122e43SStefano Zampini const PetscInt *idxs; 324108122e43SStefano Zampini 3242d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 324308122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 324408122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 324508122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 324608122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 32479162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 32489162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 324908122e43SStefano Zampini } 3250d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 325108122e43SStefano Zampini } 325208122e43SStefano Zampini 325308122e43SStefano Zampini if (mss) { /* multilevel */ 325408122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 325508122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 325608122e43SStefano Zampini } 325708122e43SStefano Zampini 3258bd2a564bSStefano Zampini lthresh = pcbddc->adaptive_threshold[0]; 3259bd2a564bSStefano Zampini uthresh = pcbddc->adaptive_threshold[1]; 326008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 326108122e43SStefano Zampini const PetscInt *idxs; 32629d54b7f4SStefano Zampini PetscReal upper,lower; 3263862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 326408122e43SStefano Zampini PetscBLASInt B_N; 3265aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 3266bd2a564bSStefano Zampini PetscBool scal = PETSC_FALSE; 326708122e43SStefano Zampini 32689d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 32699d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 3270bd2a564bSStefano Zampini lower = uthresh; 32719d54b7f4SStefano Zampini } else { 3272bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented without deluxe scaling"); 3273bd2a564bSStefano Zampini upper = 1./uthresh; 32749d54b7f4SStefano Zampini lower = 0.; 32759d54b7f4SStefano Zampini } 3276862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 3277ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 3278f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 3279bd2a564bSStefano Zampini /* this is experimental: we assume the dofs have been properly grouped to have 3280bd2a564bSStefano Zampini the diagonal blocks Schur complements either positive or negative definite (true for Stokes) */ 3281bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) { 3282bd2a564bSStefano Zampini Mat T; 3283bd2a564bSStefano Zampini 3284bd2a564bSStefano Zampini for (j=0;j<subset_size;j++) { 3285bd2a564bSStefano Zampini if (PetscRealPart(*(Sarray+cumarray+j*(subset_size+1))) < 0.0) { 3286bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Sarray+cumarray,&T);CHKERRQ(ierr); 3287bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3288bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3289bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Starray+cumarray,&T);CHKERRQ(ierr); 3290bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3291bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3292bd2a564bSStefano Zampini if (sub_schurs->change_primal_sub) { 3293bd2a564bSStefano Zampini PetscInt nz,k; 3294bd2a564bSStefano Zampini const PetscInt *idxs; 3295bd2a564bSStefano Zampini 3296bd2a564bSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nz);CHKERRQ(ierr); 3297bd2a564bSStefano Zampini ierr = ISGetIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3298bd2a564bSStefano Zampini for (k=0;k<nz;k++) { 3299bd2a564bSStefano Zampini *( Sarray + cumarray + idxs[k]*(subset_size+1)) *= -1.0; 3300bd2a564bSStefano Zampini *(Starray + cumarray + idxs[k]*(subset_size+1)) = 0.0; 3301bd2a564bSStefano Zampini } 3302bd2a564bSStefano Zampini ierr = ISRestoreIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3303bd2a564bSStefano Zampini } 3304bd2a564bSStefano Zampini scal = PETSC_TRUE; 3305bd2a564bSStefano Zampini break; 3306bd2a564bSStefano Zampini } 3307bd2a564bSStefano Zampini } 3308bd2a564bSStefano Zampini } 3309bd2a564bSStefano Zampini 3310f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 3311bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 3312aff50787SStefano Zampini PetscInt j,k; 3313*580bdb30SBarry Smith if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscArraycmp() later */ 3314*580bdb30SBarry Smith ierr = PetscArrayzero(S,subset_size*subset_size);CHKERRQ(ierr); 3315*580bdb30SBarry Smith ierr = PetscArrayzero(St,subset_size*subset_size);CHKERRQ(ierr); 331608122e43SStefano Zampini } 331708122e43SStefano Zampini for (j=0;j<subset_size;j++) { 3318aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 3319aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 3320aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 3321aff50787SStefano Zampini } 332208122e43SStefano Zampini } 332308122e43SStefano Zampini } else { 3324*580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3325*580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 332608122e43SStefano Zampini } 33278bec7fa6SStefano Zampini } else { 3328f6f667cfSStefano Zampini S = Sarray + cumarray; 3329f6f667cfSStefano Zampini St = Starray + cumarray; 33308bec7fa6SStefano Zampini } 3331aff50787SStefano Zampini /* see if we can save some work */ 3332b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 3333*580bdb30SBarry Smith ierr = PetscArraycmp(S,St,subset_size*subset_size,&same_data);CHKERRQ(ierr); 3334aff50787SStefano Zampini } 3335aff50787SStefano Zampini 3336b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 3337aff50787SStefano Zampini B_neigs = 0; 3338aff50787SStefano Zampini } else { 3339bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 334008122e43SStefano Zampini PetscBLASInt B_itype = 1; 3341f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 33424c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 33439552c7c7SStefano Zampini PetscInt nmin_s; 3344bd2a564bSStefano Zampini PetscBool compute_range; 3345bd2a564bSStefano Zampini 33469036ceccSStefano Zampini B_neigs = 0; 3347bd2a564bSStefano Zampini compute_range = (PetscBool)!same_data; 3348bd2a564bSStefano Zampini if (nmin >= subset_size) compute_range = PETSC_FALSE; 334908122e43SStefano Zampini 3350fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 33519036ceccSStefano Zampini PetscInt nc = 0; 3352d16cbb6bSStefano Zampini 33539036ceccSStefano Zampini if (sub_schurs->change_primal_sub) { 33549036ceccSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nc);CHKERRQ(ierr); 33559036ceccSStefano Zampini } 33566080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %D/%D size %D count %D fid %D (range %d) (change %D).\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]+1,pcbddc->mat_graph->which_dof[idxs[0]],compute_range,nc);CHKERRQ(ierr); 3357b7ab4a40SStefano Zampini } 3358b7ab4a40SStefano Zampini 335908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3360b7ab4a40SStefano Zampini if (compute_range) { 3361d16cbb6bSStefano Zampini 3362d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 3363bd2a564bSStefano Zampini if (sub_schurs->is_posdef) { 336408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 33659d54b7f4SStefano 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)); 336608122e43SStefano Zampini #else 33679d54b7f4SStefano 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)); 336808122e43SStefano Zampini #endif 336943371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3370bd2a564bSStefano Zampini } else { /* no theory so far, but it works nicely */ 33719036ceccSStefano Zampini PetscInt recipe = 0,recipe_m = 1; 3372bd2a564bSStefano Zampini PetscReal bb[2]; 3373bd2a564bSStefano Zampini 3374bd2a564bSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe",&recipe,NULL);CHKERRQ(ierr); 3375bd2a564bSStefano Zampini switch (recipe) { 3376bd2a564bSStefano Zampini case 0: 3377bd2a564bSStefano Zampini if (scal) { bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; } 3378bd2a564bSStefano Zampini else { bb[0] = uthresh; bb[1] = PETSC_MAX_REAL; } 3379bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3380bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 3381bd2a564bSStefano Zampini #else 3382bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 3383bd2a564bSStefano Zampini #endif 338443371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3385bd2a564bSStefano Zampini break; 3386bd2a564bSStefano Zampini case 1: 3387bd2a564bSStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh*lthresh; 3388bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3389bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 3390bd2a564bSStefano Zampini #else 3391bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 3392bd2a564bSStefano Zampini #endif 339343371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3394bd2a564bSStefano Zampini if (!scal) { 33959036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 3396bd2a564bSStefano Zampini 3397aed7e7d0SStefano Zampini bb[0] = PetscMax(lthresh*lthresh,uthresh); bb[1] = PETSC_MAX_REAL; 3398*580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3399*580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3400bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3401bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 3402bd2a564bSStefano Zampini #else 3403bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 3404bd2a564bSStefano Zampini #endif 340543371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3406bd2a564bSStefano Zampini B_neigs += B_neigs2; 3407bd2a564bSStefano Zampini } 3408bd2a564bSStefano Zampini break; 34099036ceccSStefano Zampini case 2: 34109036ceccSStefano Zampini if (scal) { 34119036ceccSStefano Zampini bb[0] = PETSC_MIN_REAL; 34129036ceccSStefano Zampini bb[1] = 0; 34139036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34149036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 34159036ceccSStefano Zampini #else 34169036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 34179036ceccSStefano Zampini #endif 341843371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34199036ceccSStefano Zampini } else { 34209036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 34219036ceccSStefano Zampini PetscBool import = PETSC_FALSE; 34229036ceccSStefano Zampini 34239036ceccSStefano Zampini lthresh = PetscMax(lthresh,0.0); 34249036ceccSStefano Zampini if (lthresh > 0.0) { 34259036ceccSStefano Zampini bb[0] = PETSC_MIN_REAL; 34269036ceccSStefano Zampini bb[1] = lthresh*lthresh; 34279036ceccSStefano Zampini 34289036ceccSStefano Zampini import = PETSC_TRUE; 34299036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34309036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 34319036ceccSStefano Zampini #else 34329036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 34339036ceccSStefano Zampini #endif 343443371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34359036ceccSStefano Zampini } 34369036ceccSStefano Zampini bb[0] = PetscMax(lthresh*lthresh,uthresh); 34379036ceccSStefano Zampini bb[1] = PETSC_MAX_REAL; 34389036ceccSStefano Zampini if (import) { 3439*580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3440*580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 34419036ceccSStefano Zampini } 34429036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34439036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 34449036ceccSStefano Zampini #else 34459036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 34469036ceccSStefano Zampini #endif 344743371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34489036ceccSStefano Zampini B_neigs += B_neigs2; 34499036ceccSStefano Zampini } 34509036ceccSStefano Zampini break; 34519036ceccSStefano Zampini case 3: 34529036ceccSStefano Zampini if (scal) { 34539036ceccSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe3_min_scal",&recipe_m,NULL);CHKERRQ(ierr); 34549036ceccSStefano Zampini } else { 34559036ceccSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe3_min",&recipe_m,NULL);CHKERRQ(ierr); 34569036ceccSStefano Zampini } 34579036ceccSStefano Zampini if (!scal) { 34589036ceccSStefano Zampini bb[0] = uthresh; 34599036ceccSStefano Zampini bb[1] = PETSC_MAX_REAL; 34609036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34619036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 34629036ceccSStefano Zampini #else 34639036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 34649036ceccSStefano Zampini #endif 346543371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34669036ceccSStefano Zampini } 34679036ceccSStefano Zampini if (recipe_m > 0 && B_N - B_neigs > 0) { 34689036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 34699036ceccSStefano Zampini 34709036ceccSStefano Zampini B_IL = 1; 34719036ceccSStefano Zampini ierr = PetscBLASIntCast(PetscMin(recipe_m,B_N - B_neigs),&B_IU);CHKERRQ(ierr); 3472*580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3473*580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 34749036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34759036ceccSStefano 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*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 34769036ceccSStefano Zampini #else 34779036ceccSStefano 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*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 34789036ceccSStefano Zampini #endif 347943371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34809036ceccSStefano Zampini B_neigs += B_neigs2; 34819036ceccSStefano Zampini } 34829036ceccSStefano Zampini break; 348348cebe81SStefano Zampini case 4: 348448cebe81SStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; 348548cebe81SStefano Zampini #if defined(PETSC_USE_COMPLEX) 348648cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 348748cebe81SStefano Zampini #else 348848cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 348948cebe81SStefano Zampini #endif 349043371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 349148cebe81SStefano Zampini { 349248cebe81SStefano Zampini PetscBLASInt B_neigs2 = 0; 349348cebe81SStefano Zampini 349448cebe81SStefano Zampini bb[0] = PetscMax(lthresh+PETSC_SMALL,uthresh); bb[1] = PETSC_MAX_REAL; 3495*580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3496*580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 349748cebe81SStefano Zampini #if defined(PETSC_USE_COMPLEX) 349848cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 349948cebe81SStefano Zampini #else 350048cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 350148cebe81SStefano Zampini #endif 350243371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 350348cebe81SStefano Zampini B_neigs += B_neigs2; 350448cebe81SStefano Zampini } 350548cebe81SStefano Zampini break; 350680db8efeSStefano Zampini case 5: /* same as before: first compute all eigenvalues, then filter */ 350780db8efeSStefano Zampini #if defined(PETSC_USE_COMPLEX) 350880db8efeSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","A","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 350980db8efeSStefano Zampini #else 351080db8efeSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","A","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 351180db8efeSStefano Zampini #endif 351243371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 351380db8efeSStefano Zampini { 351480db8efeSStefano Zampini PetscInt e,k,ne; 351580db8efeSStefano Zampini for (e=0,ne=0;e<B_neigs;e++) { 351680db8efeSStefano Zampini if (eigs[e] < lthresh || eigs[e] > uthresh) { 351780db8efeSStefano Zampini for (k=0;k<B_N;k++) S[ne*B_N+k] = eigv[e*B_N+k]; 351880db8efeSStefano Zampini eigs[ne] = eigs[e]; 351980db8efeSStefano Zampini ne++; 352080db8efeSStefano Zampini } 352180db8efeSStefano Zampini } 3522*580bdb30SBarry Smith ierr = PetscArraycpy(eigv,S,B_N*ne);CHKERRQ(ierr); 352380db8efeSStefano Zampini B_neigs = ne; 352480db8efeSStefano Zampini } 352580db8efeSStefano Zampini break; 3526bd2a564bSStefano Zampini default: 3527bd2a564bSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Unknown recipe %D",recipe); 3528bd2a564bSStefano Zampini break; 3529bd2a564bSStefano Zampini } 3530bd2a564bSStefano Zampini } 3531bd2a564bSStefano Zampini } else if (!same_data) { /* this is just to see all the eigenvalues */ 3532d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 3533d16cbb6bSStefano Zampini B_IL = 1; 3534d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 35359d54b7f4SStefano 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)); 3536d16cbb6bSStefano Zampini #else 35379d54b7f4SStefano 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)); 3538d16cbb6bSStefano Zampini #endif 353943371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3540b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 3541b7ab4a40SStefano Zampini PetscInt k; 3542b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 3543b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 3544b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 3545b7ab4a40SStefano Zampini nmin = nmax; 3546*580bdb30SBarry Smith ierr = PetscArrayzero(eigv,subset_size*nmax);CHKERRQ(ierr); 3547b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 3548b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 3549b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 3550b7ab4a40SStefano Zampini } 3551d16cbb6bSStefano Zampini } 355208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 355308122e43SStefano Zampini if (B_ierr) { 35546c4ed002SBarry 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); 35556c4ed002SBarry 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); 35566c4ed002SBarry 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); 355708122e43SStefano Zampini } 355808122e43SStefano Zampini 355908122e43SStefano Zampini if (B_neigs > nmax) { 3560fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 35616080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %D.\n",B_neigs,nmax);CHKERRQ(ierr); 3562fd14bc51SStefano Zampini } 3563bd2a564bSStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = scal ? 0 : B_neigs-nmax; 356408122e43SStefano Zampini B_neigs = nmax; 356508122e43SStefano Zampini } 356608122e43SStefano Zampini 35679552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 35689552c7c7SStefano Zampini if (B_neigs < nmin_s) { 35699036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 357008122e43SStefano Zampini 35719d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3572bd2a564bSStefano Zampini if (scal) { 3573bd2a564bSStefano Zampini B_IU = nmin_s; 3574bd2a564bSStefano Zampini B_IL = B_neigs + 1; 3575bd2a564bSStefano Zampini } else { 3576f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 35779d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 3578bd2a564bSStefano Zampini } 35799d54b7f4SStefano Zampini } else { 35809d54b7f4SStefano Zampini B_IL = B_neigs + 1; 35819d54b7f4SStefano Zampini B_IU = nmin_s; 35829d54b7f4SStefano Zampini } 3583fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 35846080607fSStefano Zampini ierr = 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);CHKERRQ(ierr); 3585fd14bc51SStefano Zampini } 3586bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 35871ae86dd6SStefano Zampini PetscInt j,k; 358808122e43SStefano Zampini for (j=0;j<subset_size;j++) { 35891ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 35901ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 35911ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 359208122e43SStefano Zampini } 359308122e43SStefano Zampini } 359408122e43SStefano Zampini } else { 3595*580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3596*580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 359708122e43SStefano Zampini } 359808122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 359908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 36009d54b7f4SStefano 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)); 360108122e43SStefano Zampini #else 36029d54b7f4SStefano 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)); 360308122e43SStefano Zampini #endif 360443371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 360508122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 360608122e43SStefano Zampini B_neigs += B_neigs2; 360708122e43SStefano Zampini } 360808122e43SStefano Zampini if (B_ierr) { 36096c4ed002SBarry 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); 36106c4ed002SBarry 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); 36116c4ed002SBarry 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); 361208122e43SStefano Zampini } 3613fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3614ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 361508122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 361608122e43SStefano Zampini if (eigs[j] == 0.0) { 3617ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 361808122e43SStefano Zampini } else { 36199d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3620ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 36219d54b7f4SStefano Zampini } else { 36229d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 36239d54b7f4SStefano Zampini } 3624fd14bc51SStefano Zampini } 362508122e43SStefano Zampini } 362608122e43SStefano Zampini } 3627bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 3628aff50787SStefano Zampini } 36296c3e6151SStefano Zampini /* change the basis back to the original one */ 36306c3e6151SStefano Zampini if (sub_schurs->change) { 363172b8c272SStefano Zampini Mat change,phi,phit; 36326c3e6151SStefano Zampini 363303dfb2d7SStefano Zampini if (pcbddc->dbg_flag > 2) { 36346c3e6151SStefano Zampini PetscInt ii; 36356c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 36366c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 36376c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 3638684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3639684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 3640684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 3641684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3642684229deSStefano Zampini #else 36436c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 3644684229deSStefano Zampini #endif 36456c3e6151SStefano Zampini } 36466c3e6151SStefano Zampini } 36476c3e6151SStefano Zampini } 364872b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 36496c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 365072b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 36516c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 36526c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 36536c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 36546c3e6151SStefano Zampini } 36558bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 36568bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 36579162d606SStefano Zampini if (B_neigs) { 3658*580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum],eigv+eigs_start*subset_size,B_neigs*subset_size);CHKERRQ(ierr); 3659fd14bc51SStefano Zampini 3660fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 36619552c7c7SStefano Zampini PetscInt ii; 36629552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 3663ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 36649552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 3665ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3666ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3667ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3668ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3669ac47001eSStefano Zampini #else 3670ac47001eSStefano 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); 3671ac47001eSStefano Zampini #endif 36729552c7c7SStefano Zampini } 36739552c7c7SStefano Zampini } 3674fd14bc51SStefano Zampini } 3675*580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size);CHKERRQ(ierr); 36769162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 36779162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 36789162d606SStefano Zampini cum++; 367908122e43SStefano Zampini } 368008122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 368108122e43SStefano Zampini /* shift for next computation */ 368208122e43SStefano Zampini cumarray += subset_size*subset_size; 368308122e43SStefano Zampini } 3684fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3685fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3686fd14bc51SStefano Zampini } 368708122e43SStefano Zampini 368808122e43SStefano Zampini if (mss) { 368908122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 369008122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3691f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3692f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3693f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 369408122e43SStefano Zampini } 3695f6f667cfSStefano Zampini if (allocated_S_St) { 3696f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3697f6f667cfSStefano Zampini } 3698f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 369908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 370008122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 370108122e43SStefano Zampini #endif 370208122e43SStefano Zampini if (pcbddc->dbg_flag) { 37031b968477SStefano Zampini PetscInt maxneigs_r; 3704b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 37056080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %D\n",maxneigs_r);CHKERRQ(ierr); 370608122e43SStefano Zampini } 370743371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_AdaptiveSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 370808122e43SStefano Zampini PetscFunctionReturn(0); 370908122e43SStefano Zampini } 3710b1b3d7a2SStefano Zampini 3711c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3712c8587f34SStefano Zampini { 37138629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3714c8587f34SStefano Zampini PetscErrorCode ierr; 3715c8587f34SStefano Zampini 3716c8587f34SStefano Zampini PetscFunctionBegin; 3717f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 37185e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3719c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3720c8587f34SStefano Zampini 3721684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 37220fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3723684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3724c8587f34SStefano Zampini 37258629588bSStefano Zampini /* 37268629588bSStefano Zampini Setup local correction and local part of coarse basis. 37278629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 37288629588bSStefano Zampini */ 372947f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 37308629588bSStefano Zampini 37318629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 37328629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 37338629588bSStefano Zampini 37348629588bSStefano Zampini /* free */ 37358629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3736c8587f34SStefano Zampini PetscFunctionReturn(0); 3737c8587f34SStefano Zampini } 3738c8587f34SStefano Zampini 3739674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3740674ae819SStefano Zampini { 3741674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3742674ae819SStefano Zampini PetscErrorCode ierr; 3743674ae819SStefano Zampini 3744674ae819SStefano Zampini PetscFunctionBegin; 3745674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 374630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3747674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3748785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3749674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3750f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3751f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3752785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 375363602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 375463602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3755674ae819SStefano Zampini PetscFunctionReturn(0); 3756674ae819SStefano Zampini } 3757674ae819SStefano Zampini 3758674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3759674ae819SStefano Zampini { 3760674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 37614f1b2e48SStefano Zampini PetscInt i; 3762674ae819SStefano Zampini PetscErrorCode ierr; 3763674ae819SStefano Zampini 3764674ae819SStefano Zampini PetscFunctionBegin; 37651e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 37661e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3767a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3768b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3769674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 377016909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 37711dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3772674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3773669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3774fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 37759326c5c6Sstefano_zampini ierr = PCBDDCGraphDestroy(&pcbddc->mat_graph);CHKERRQ(ierr); 37764f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 37774f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 37784f1b2e48SStefano Zampini } 3779e68a0315Sstefano_zampini pcbddc->n_local_subs = 0; 37804f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3781e68a0315Sstefano_zampini ierr = PCBDDCSubSchursDestroy(&pcbddc->sub_schurs);CHKERRQ(ierr); 3782c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 37838af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 37841c7a958bSStefano Zampini pcbddc->corner_selected = PETSC_FALSE; 3785674ae819SStefano Zampini PetscFunctionReturn(0); 3786674ae819SStefano Zampini } 3787674ae819SStefano Zampini 3788674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3789674ae819SStefano Zampini { 3790674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3791674ae819SStefano Zampini PetscErrorCode ierr; 3792674ae819SStefano Zampini 3793674ae819SStefano Zampini PetscFunctionBegin; 3794674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 379558da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3796ca92afb2SStefano Zampini PetscScalar *array; 379706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 379806656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 379958da7f69SStefano Zampini } 3800674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3801674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 380215aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 380315aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3804674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3805674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3806674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 380706656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3808674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3809674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 38108ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3811674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3812674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3813674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 38149326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_D);CHKERRQ(ierr); 38159326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 38169326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3817f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3818727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 38190e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3820f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 382170cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 382281d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 38230369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 38241dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 38254f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 38268b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3827ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3828ca92afb2SStefano Zampini PetscInt i; 3829ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3830ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3831ca92afb2SStefano Zampini } 3832ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3833ca92afb2SStefano Zampini } 38344f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3835674ae819SStefano Zampini PetscFunctionReturn(0); 3836674ae819SStefano Zampini } 3837674ae819SStefano Zampini 3838f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 38396bfb1811SStefano Zampini { 38406bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 38416bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 38426bfb1811SStefano Zampini VecType impVecType; 38434f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 38446bfb1811SStefano Zampini PetscErrorCode ierr; 38456bfb1811SStefano Zampini 38466bfb1811SStefano Zampini PetscFunctionBegin; 38474f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3848b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 38496bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3850e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3851e7b262bdSStefano Zampini /* R nodes */ 3852e7b262bdSStefano Zampini old_size = -1; 3853e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3854e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3855e7b262bdSStefano Zampini } 3856e7b262bdSStefano Zampini if (n_R != old_size) { 3857e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3858e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 38596bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 38606bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 38616bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 38626bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3863e7b262bdSStefano Zampini } 3864e7b262bdSStefano Zampini /* local primal dofs */ 3865e7b262bdSStefano Zampini old_size = -1; 3866e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3867e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3868e7b262bdSStefano Zampini } 3869e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3870e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 387183b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3872e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 38736bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3874e7b262bdSStefano Zampini } 3875e7b262bdSStefano Zampini /* local explicit constraints */ 3876e7b262bdSStefano Zampini old_size = -1; 3877e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3878e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3879e7b262bdSStefano Zampini } 3880e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3881e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 388283b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 388383b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 388483b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 388583b7ccabSStefano Zampini } 38866bfb1811SStefano Zampini PetscFunctionReturn(0); 38876bfb1811SStefano Zampini } 38886bfb1811SStefano Zampini 388947f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 389088ebb749SStefano Zampini { 389125084f0cSStefano Zampini PetscErrorCode ierr; 389225084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 389388ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 389488ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3895d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 389625084f0cSStefano Zampini /* submatrices of local problem */ 389780677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 389806656605SStefano Zampini /* submatrices of local coarse problem */ 389906656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 390025084f0cSStefano Zampini /* working matrices */ 390106656605SStefano Zampini Mat C_CR; 390225084f0cSStefano Zampini /* additional working stuff */ 390306656605SStefano Zampini PC pc_R; 3904c58f9fdbSStefano Zampini Mat F,Brhs = NULL; 39055cbda25cSStefano Zampini Vec dummy_vec; 3906c58f9fdbSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction,sparserhs; 390725084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 390806656605SStefano Zampini PetscScalar *work; 390906656605SStefano Zampini PetscInt *idx_V_B; 3910ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 391106656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 3912ffd830a3SStefano Zampini 391325084f0cSStefano Zampini /* some shortcuts to scalars */ 391406656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 391588ebb749SStefano Zampini 391688ebb749SStefano Zampini PetscFunctionBegin; 39179a962809SStefano 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"); 391843371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CorrectionSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 3919ffd830a3SStefano Zampini 3920ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3921b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 39224f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3923b371cd4fSStefano Zampini n_B = pcis->n_B; 3924b371cd4fSStefano Zampini n_D = pcis->n - n_B; 392588ebb749SStefano Zampini n_R = pcis->n - n_vertices; 392688ebb749SStefano Zampini 392788ebb749SStefano Zampini /* vertices in boundary numbering */ 3928785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 39290e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 39306080607fSStefano Zampini if (i != n_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D",n_vertices,i); 393188ebb749SStefano Zampini 393206656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3933019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 393406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 393506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 393606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 393706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 393806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 393906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 394006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 394106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 394206656605SStefano Zampini 394306656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 394406656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 39452958b453SStefano Zampini ierr = PCSetUp(pc_R);CHKERRQ(ierr); 394606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 394706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 394806656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3949ffd830a3SStefano Zampini lda_rhs = n_R; 3950a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 395106656605SStefano Zampini if (isLU || isILU || isCHOL) { 395206656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3953b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3954df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3955d62866d3SStefano Zampini MatFactorType type; 3956d62866d3SStefano Zampini 3957df4d28bfSStefano Zampini F = reuse_solver->F; 39586816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3959d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 3960ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 396122db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 396206656605SStefano Zampini } else { 396306656605SStefano Zampini F = NULL; 396406656605SStefano Zampini } 396506656605SStefano Zampini 3966c58f9fdbSStefano Zampini /* determine if we can use a sparse right-hand side */ 3967c58f9fdbSStefano Zampini sparserhs = PETSC_FALSE; 3968c58f9fdbSStefano Zampini if (F) { 3969ea799195SBarry Smith MatSolverType solver; 3970c58f9fdbSStefano Zampini 39713ca39a21SBarry Smith ierr = MatFactorGetSolverType(F,&solver);CHKERRQ(ierr); 3972c58f9fdbSStefano Zampini ierr = PetscStrcmp(solver,MATSOLVERMUMPS,&sparserhs);CHKERRQ(ierr); 3973c58f9fdbSStefano Zampini } 3974c58f9fdbSStefano Zampini 3975ffd830a3SStefano Zampini /* allocate workspace */ 3976ffd830a3SStefano Zampini n = 0; 3977ffd830a3SStefano Zampini if (n_constraints) { 3978ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3979ffd830a3SStefano Zampini } 3980ffd830a3SStefano Zampini if (n_vertices) { 3981ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3982ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3983ffd830a3SStefano Zampini } 39842a3a6641Sstefano_zampini if (!pcbddc->symmetric_primal) { 39852a3a6641Sstefano_zampini n = PetscMax(2*lda_rhs*pcbddc->local_primal_size,n); 39862a3a6641Sstefano_zampini } 3987ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3988ffd830a3SStefano Zampini 39895cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 39905cbda25cSStefano Zampini dummy_vec = NULL; 39915cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 3992c72cccf8SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&dummy_vec);CHKERRQ(ierr); 3993c72cccf8SStefano Zampini ierr = VecSetSizes(dummy_vec,lda_rhs,PETSC_DECIDE);CHKERRQ(ierr); 3994c72cccf8SStefano Zampini ierr = VecSetType(dummy_vec,((PetscObject)pcis->vec1_N)->type_name);CHKERRQ(ierr); 39955cbda25cSStefano Zampini } 39965cbda25cSStefano Zampini 399788ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 399888ebb749SStefano Zampini if (n_constraints) { 3999837cedc9SStefano Zampini Mat M3,C_B; 400006656605SStefano Zampini IS is_aux; 400180677318SStefano Zampini PetscScalar *array,*array2; 400206656605SStefano Zampini 4003f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 400480677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 400588ebb749SStefano Zampini 400625084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 400725084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 40087dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 40097dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 401088ebb749SStefano Zampini 401180677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 401280677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 4013c58f9fdbSStefano Zampini if (!sparserhs) { 4014*580bdb30SBarry Smith ierr = PetscArrayzero(work,lda_rhs*n_constraints);CHKERRQ(ierr); 401588ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 401606656605SStefano Zampini const PetscScalar *row_cmat_values; 401706656605SStefano Zampini const PetscInt *row_cmat_indices; 401806656605SStefano Zampini PetscInt size_of_constraint,j; 401988ebb749SStefano Zampini 402006656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 402106656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 4022ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 402306656605SStefano Zampini } 402406656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 402506656605SStefano Zampini } 4026c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&Brhs);CHKERRQ(ierr); 4027c58f9fdbSStefano Zampini } else { 4028c58f9fdbSStefano Zampini Mat tC_CR; 4029c58f9fdbSStefano Zampini 4030c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 4031c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 4032c58f9fdbSStefano Zampini PetscScalar *aa; 4033c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 4034c58f9fdbSStefano Zampini PetscBool done; 4035c58f9fdbSStefano Zampini 4036c58f9fdbSStefano Zampini ierr = MatGetRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 403713903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 4038c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(C_CR,&aa);CHKERRQ(ierr); 4039c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_constraints,lda_rhs,ii,jj,aa,&tC_CR);CHKERRQ(ierr); 4040c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 404113903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 4042c58f9fdbSStefano Zampini } else { 4043c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)C_CR);CHKERRQ(ierr); 4044c58f9fdbSStefano Zampini tC_CR = C_CR; 4045c58f9fdbSStefano Zampini } 4046c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tC_CR,&Brhs);CHKERRQ(ierr); 4047c58f9fdbSStefano Zampini ierr = MatDestroy(&tC_CR);CHKERRQ(ierr); 4048c58f9fdbSStefano Zampini } 4049ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 405006656605SStefano Zampini if (F) { 4051a3df083aSStefano Zampini if (need_benign_correction) { 4052df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4053a3df083aSStefano Zampini 405472b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 4055*580bdb30SBarry Smith ierr = PetscArrayzero(reuse_solver->benign_save_vals,pcbddc->benign_n);CHKERRQ(ierr); 4056a3df083aSStefano Zampini } 4057c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,local_auxmat2_R);CHKERRQ(ierr); 4058a3df083aSStefano Zampini if (need_benign_correction) { 4059a3df083aSStefano Zampini PetscScalar *marr; 4060df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4061a3df083aSStefano Zampini 4062a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 40635cbda25cSStefano Zampini if (lda_rhs != n_R) { 40645cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 40655cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 40665cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 40675cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 40685cbda25cSStefano Zampini } 40695cbda25cSStefano Zampini } else { 4070a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 4071a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 40725cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4073a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4074a3df083aSStefano Zampini } 40755cbda25cSStefano Zampini } 4076a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 4077a3df083aSStefano Zampini } 407806656605SStefano Zampini } else { 407980677318SStefano Zampini PetscScalar *marr; 408080677318SStefano Zampini 408180677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 408206656605SStefano Zampini for (i=0;i<n_constraints;i++) { 4083ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4084ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 408506656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4086c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 408706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 408806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 408906656605SStefano Zampini } 409080677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 409106656605SStefano Zampini } 4092c58f9fdbSStefano Zampini if (sparserhs) { 4093c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 4094c58f9fdbSStefano Zampini } 4095c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 409680677318SStefano Zampini if (!pcbddc->switch_static) { 409780677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 409880677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 409980677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 410080677318SStefano Zampini for (i=0;i<n_constraints;i++) { 4101ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 410280677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 410380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 410480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 410580677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 410680677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 410780677318SStefano Zampini } 410880677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 410980677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 411072b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 411180677318SStefano Zampini } else { 4112ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4113ffd830a3SStefano Zampini IS dummy; 4114ffd830a3SStefano Zampini 4115ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 41167dae84e0SHong Zhang ierr = MatCreateSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 4117ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 4118ffd830a3SStefano Zampini } else { 411980677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 412080677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 4121ffd830a3SStefano Zampini } 412225084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 412380677318SStefano Zampini } 412480677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 412580677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 412680677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 412780677318SStefano Zampini if (isCHOL) { 412880677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 412980677318SStefano Zampini } else { 413025084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 413180677318SStefano Zampini } 4132837cedc9SStefano Zampini ierr = MatSeqDenseInvertFactors_Private(M3);CHKERRQ(ierr); 413380677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 4134837cedc9SStefano Zampini ierr = MatMatMult(M3,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 413572b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 4136837cedc9SStefano Zampini ierr = MatCopy(M3,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 4137837cedc9SStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 4138f4ddd8eeSStefano Zampini } 4139fc227af8SStefano Zampini 4140fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 414188ebb749SStefano Zampini if (n_vertices) { 414206656605SStefano Zampini IS is_aux; 4143c58f9fdbSStefano Zampini PetscBool isseqaij; 41443a50541eSStefano Zampini 4145b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 41466816873aSStefano Zampini IS tis; 41476816873aSStefano Zampini 41486816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 41496816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 41506816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 41516816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 41526816873aSStefano Zampini } else { 41533a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 41546816873aSStefano Zampini } 41557dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 41567dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 4157c58f9fdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 4158c58f9fdbSStefano Zampini if (!isseqaij) { /* MatMatMult(A_VR,A_RRmA_RV) below will raise an error */ 4159c58f9fdbSStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4160c58f9fdbSStefano Zampini } 41617dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 416225084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 416388ebb749SStefano Zampini } 416488ebb749SStefano Zampini 416588ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 4166f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 416706656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 416806656605SStefano Zampini if (pcbddc->coarse_phi_D) { 416906656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 417006656605SStefano Zampini } 4171f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 417206656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 417306656605SStefano Zampini PetscScalar *marray; 417406656605SStefano Zampini 417506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 417606656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 4177f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 4178f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 4179f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 4180f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 4181f4ddd8eeSStefano Zampini } 4182f4ddd8eeSStefano Zampini } 418306656605SStefano Zampini 4184f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 4185a6e023c1Sstefano_zampini PetscScalar *marr; 418688ebb749SStefano Zampini 4187a6e023c1Sstefano_zampini /* memory size */ 418806656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 4189a6e023c1Sstefano_zampini if (pcbddc->switch_static || pcbddc->dbg_flag) n += n_D*pcbddc->local_primal_size; 4190a6e023c1Sstefano_zampini if (!pcbddc->symmetric_primal) n *= 2; 4191a6e023c1Sstefano_zampini ierr = PetscCalloc1(n,&marr);CHKERRQ(ierr); 4192a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 4193a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 41948eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4195a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 4196a6e023c1Sstefano_zampini marr += n_D*pcbddc->local_primal_size; 419788ebb749SStefano Zampini } 41983301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4199a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 4200a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 42018eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4202a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 420388ebb749SStefano Zampini } 420488ebb749SStefano Zampini } else { 4205c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 4206c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 42071b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4208c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 4209c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 4210c0553b1fSStefano Zampini } 421188ebb749SStefano Zampini } 421206656605SStefano Zampini } 4213019a44ceSStefano Zampini 421406656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 42154f1b2e48SStefano Zampini p0_lidx_I = NULL; 42164f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 4217d12edf2fSStefano Zampini const PetscInt *idxs; 4218d12edf2fSStefano Zampini 4219d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 42204f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 42214f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 42224f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 42234f1b2e48SStefano Zampini } 4224d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 4225d12edf2fSStefano Zampini } 4226d16cbb6bSStefano Zampini 422706656605SStefano Zampini /* vertices */ 422806656605SStefano Zampini if (n_vertices) { 4229c58f9fdbSStefano Zampini PetscBool restoreavr = PETSC_FALSE; 423016f15bc4SStefano Zampini 4231af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 423204708bb6SStefano Zampini 423316f15bc4SStefano Zampini if (n_R) { 423414393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 423506656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 42361683a169SBarry Smith const PetscScalar *x; 42371683a169SBarry Smith PetscScalar *y; 423806656605SStefano Zampini 423921eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 424014393ed6SStefano Zampini if (need_benign_correction) { 424114393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 424214393ed6SStefano Zampini IS is_p0; 424314393ed6SStefano Zampini PetscInt *idxs_p0,n; 424414393ed6SStefano Zampini 424514393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 424614393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 424714393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 42486080607fSStefano Zampini if (n != pcbddc->benign_n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in R numbering for benign p0! %D != %D",n,pcbddc->benign_n); 424914393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 425014393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 42517dae84e0SHong Zhang ierr = MatCreateSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 425214393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 425314393ed6SStefano Zampini } 425414393ed6SStefano Zampini 4255c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4256c58f9fdbSStefano Zampini if (!sparserhs || need_benign_correction) { 4257ffd830a3SStefano Zampini if (lda_rhs == n_R) { 4258af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 4259ffd830a3SStefano Zampini } else { 4260ca92afb2SStefano Zampini PetscScalar *av,*array; 4261ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 4262ca92afb2SStefano Zampini PetscInt n; 4263ca92afb2SStefano Zampini PetscBool flg_row; 4264ffd830a3SStefano Zampini 4265ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 4266*580bdb30SBarry Smith ierr = PetscArrayzero(array,lda_rhs*n_vertices);CHKERRQ(ierr); 42679d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 4268ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4269ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 4270ca92afb2SStefano Zampini for (i=0;i<n;i++) { 4271ca92afb2SStefano Zampini PetscInt j; 4272ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 4273ffd830a3SStefano Zampini } 4274ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4275ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4276ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 4277ffd830a3SStefano Zampini } 4278a3df083aSStefano Zampini if (need_benign_correction) { 4279df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4280a3df083aSStefano Zampini PetscScalar *marr; 4281a3df083aSStefano Zampini 4282a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 428314393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 428414393ed6SStefano Zampini 428514393ed6SStefano Zampini | 0 0 0 | (V) 428614393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 428714393ed6SStefano Zampini | 0 0 -1 | (p0) 428814393ed6SStefano Zampini 428914393ed6SStefano Zampini */ 4290df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 429114393ed6SStefano Zampini const PetscScalar *vals; 429214393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 429314393ed6SStefano Zampini PetscInt n,j,nz; 429414393ed6SStefano Zampini 4295df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4296df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 429714393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 429814393ed6SStefano Zampini for (j=0;j<n;j++) { 429914393ed6SStefano Zampini PetscScalar val = vals[j]; 430014393ed6SStefano Zampini PetscInt k,col = idxs[j]; 430114393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 430214393ed6SStefano Zampini } 430314393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4304df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 430514393ed6SStefano Zampini } 430672b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 430772b8c272SStefano Zampini } 4308c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RV);CHKERRQ(ierr); 4309c58f9fdbSStefano Zampini Brhs = A_RV; 4310c58f9fdbSStefano Zampini } else { 4311c58f9fdbSStefano Zampini Mat tA_RVT,A_RVT; 4312c58f9fdbSStefano Zampini 4313c58f9fdbSStefano Zampini if (!pcbddc->symmetric_primal) { 4314fb6280fbSStefano Zampini /* A_RV already scaled by -1 */ 4315c58f9fdbSStefano Zampini ierr = MatTranspose(A_RV,MAT_INITIAL_MATRIX,&A_RVT);CHKERRQ(ierr); 4316c58f9fdbSStefano Zampini } else { 4317c58f9fdbSStefano Zampini restoreavr = PETSC_TRUE; 4318c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4319c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_VR);CHKERRQ(ierr); 4320c58f9fdbSStefano Zampini A_RVT = A_VR; 4321c58f9fdbSStefano Zampini } 4322c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 4323c58f9fdbSStefano Zampini PetscScalar *aa; 4324c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 4325c58f9fdbSStefano Zampini PetscBool done; 4326c58f9fdbSStefano Zampini 4327c58f9fdbSStefano Zampini ierr = MatGetRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 432813903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 4329c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(A_RVT,&aa);CHKERRQ(ierr); 4330c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_vertices,lda_rhs,ii,jj,aa,&tA_RVT);CHKERRQ(ierr); 4331c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 433213903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 4333c58f9fdbSStefano Zampini } else { 4334c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RVT);CHKERRQ(ierr); 4335c58f9fdbSStefano Zampini tA_RVT = A_RVT; 4336c58f9fdbSStefano Zampini } 4337c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tA_RVT,&Brhs);CHKERRQ(ierr); 4338c58f9fdbSStefano Zampini ierr = MatDestroy(&tA_RVT);CHKERRQ(ierr); 4339c58f9fdbSStefano Zampini ierr = MatDestroy(&A_RVT);CHKERRQ(ierr); 4340c58f9fdbSStefano Zampini } 434172b8c272SStefano Zampini if (F) { 434214393ed6SStefano Zampini /* need to correct the rhs */ 434372b8c272SStefano Zampini if (need_benign_correction) { 434472b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 434572b8c272SStefano Zampini PetscScalar *marr; 434672b8c272SStefano Zampini 4347c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&marr);CHKERRQ(ierr); 43485cbda25cSStefano Zampini if (lda_rhs != n_R) { 43495cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 43505cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 43515cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 43525cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 43535cbda25cSStefano Zampini } 43545cbda25cSStefano Zampini } else { 4355a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4356a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 43575cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 4358a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4359a3df083aSStefano Zampini } 43605cbda25cSStefano Zampini } 4361c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&marr);CHKERRQ(ierr); 4362a3df083aSStefano Zampini } 4363c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,A_RRmA_RV);CHKERRQ(ierr); 4364c58f9fdbSStefano Zampini if (restoreavr) { 4365c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4366c58f9fdbSStefano Zampini } 436714393ed6SStefano Zampini /* need to correct the solution */ 4368a3df083aSStefano Zampini if (need_benign_correction) { 4369df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4370a3df083aSStefano Zampini PetscScalar *marr; 4371a3df083aSStefano Zampini 4372a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 43735cbda25cSStefano Zampini if (lda_rhs != n_R) { 43745cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 43755cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 43765cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 43775cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 43785cbda25cSStefano Zampini } 43795cbda25cSStefano Zampini } else { 4380a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4381a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 43825cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4383a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4384a3df083aSStefano Zampini } 43855cbda25cSStefano Zampini } 4386a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 4387a3df083aSStefano Zampini } 438806656605SStefano Zampini } else { 4389c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&y);CHKERRQ(ierr); 439006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 4391ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 4392ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 439306656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4394c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 439506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 439606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 439706656605SStefano Zampini } 4398c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&y);CHKERRQ(ierr); 439906656605SStefano Zampini } 440080677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4401c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 4402ffd830a3SStefano Zampini /* S_VV and S_CV */ 440306656605SStefano Zampini if (n_constraints) { 440406656605SStefano Zampini Mat B; 440580677318SStefano Zampini 4406*580bdb30SBarry Smith ierr = PetscArrayzero(work+lda_rhs*n_vertices,n_B*n_vertices);CHKERRQ(ierr); 440780677318SStefano Zampini for (i=0;i<n_vertices;i++) { 4408ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4409ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 441080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 441180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 441280677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 441380677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 441480677318SStefano Zampini } 4415ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 441680677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 441780677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 4418ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 441980677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 442006656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 4421ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 4422ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 442306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 442406656605SStefano Zampini } 4425ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4426ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 4427ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4428ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 4429ffd830a3SStefano Zampini } 443006656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 443114393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 443214393ed6SStefano Zampini if (need_benign_correction) { 4433df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 443414393ed6SStefano Zampini PetscScalar *marr,*sums; 443514393ed6SStefano Zampini 443614393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 4437f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 4438df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 443914393ed6SStefano Zampini const PetscScalar *vals; 444014393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 444114393ed6SStefano Zampini PetscInt n,j,nz; 444214393ed6SStefano Zampini 4443df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4444df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 444514393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 444614393ed6SStefano Zampini PetscInt k; 444714393ed6SStefano Zampini sums[j] = 0.; 444814393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 444914393ed6SStefano Zampini } 445014393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 445114393ed6SStefano Zampini for (j=0;j<n;j++) { 445214393ed6SStefano Zampini PetscScalar val = vals[j]; 445314393ed6SStefano Zampini PetscInt k; 445414393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 445514393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 445614393ed6SStefano Zampini } 445714393ed6SStefano Zampini } 445814393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4459df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 446014393ed6SStefano Zampini } 446114393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 4462f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 446314393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 446414393ed6SStefano Zampini } 446580677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 446606656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 44671683a169SBarry Smith ierr = MatDenseGetArrayRead(A_VV,&x);CHKERRQ(ierr); 446806656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 446906656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 44701683a169SBarry Smith ierr = MatDenseRestoreArrayRead(A_VV,&x);CHKERRQ(ierr); 447106656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 447206656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4473d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 4474019a44ceSStefano Zampini } else { 4475d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4476d16cbb6bSStefano Zampini } 447721eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 4478d16cbb6bSStefano Zampini 447906656605SStefano Zampini /* coarse basis functions */ 448006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 448116f15bc4SStefano Zampini PetscScalar *y; 448216f15bc4SStefano Zampini 4483ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 448406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 448506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 448606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 448706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 448806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 448906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 449006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 449106656605SStefano Zampini 449206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 44934f1b2e48SStefano Zampini PetscInt j; 44944f1b2e48SStefano Zampini 449506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 449606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 449706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 449806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 449906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 45004f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 450106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 450206656605SStefano Zampini } 450306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 450406656605SStefano Zampini } 450504708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 450604708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 450706656605SStefano Zampini } 45085cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 450906656605SStefano Zampini 451006656605SStefano Zampini if (n_constraints) { 451106656605SStefano Zampini Mat B; 451206656605SStefano Zampini 4513ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 451406656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 451580677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 451606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 451706656605SStefano Zampini if (n_vertices) { 451803dfb2d7SStefano Zampini if (isCHOL || need_benign_correction) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 451980677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 452080677318SStefano Zampini } else { 452180677318SStefano Zampini Mat S_VCt; 452280677318SStefano Zampini 4523ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4524ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 452572b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 4526ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 4527ffd830a3SStefano Zampini } 452880677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 452980677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 453080677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 453180677318SStefano Zampini } 453206656605SStefano Zampini } 453306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 453406656605SStefano Zampini /* coarse basis functions */ 453506656605SStefano Zampini for (i=0;i<n_constraints;i++) { 453606656605SStefano Zampini PetscScalar *y; 453706656605SStefano Zampini 4538ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 453906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 454006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 454106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 454206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 454306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 454406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 454506656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 45464f1b2e48SStefano Zampini PetscInt j; 45474f1b2e48SStefano Zampini 454806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 454906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 455006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 455106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 455206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 45534f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 455406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 455506656605SStefano Zampini } 455606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 455706656605SStefano Zampini } 455806656605SStefano Zampini } 455980677318SStefano Zampini if (n_constraints) { 456080677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 456180677318SStefano Zampini } 45624f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 456372b8c272SStefano Zampini 456472b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 456572b8c272SStefano Zampini if (pcbddc->benign_n) { 456672b8c272SStefano Zampini Mat B0_B,B0_BPHI; 456772b8c272SStefano Zampini IS is_dummy; 45681683a169SBarry Smith const PetscScalar *data; 456972b8c272SStefano Zampini PetscInt j; 457072b8c272SStefano Zampini 457172b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 45727dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 457372b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 457472b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 457586c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 45761683a169SBarry Smith ierr = MatDenseGetArrayRead(B0_BPHI,&data);CHKERRQ(ierr); 457772b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 457872b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 457972b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 458072b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 458172b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 458272b8c272SStefano Zampini } 458372b8c272SStefano Zampini } 45841683a169SBarry Smith ierr = MatDenseRestoreArrayRead(B0_BPHI,&data);CHKERRQ(ierr); 458572b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 458672b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 458772b8c272SStefano Zampini } 4588019a44ceSStefano Zampini 458906656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 45903301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4591ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 4592ffd830a3SStefano Zampini PetscScalar *marray; 459306656605SStefano Zampini 459406656605SStefano Zampini if (n_constraints) { 4595ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 459606656605SStefano Zampini 4597abc8f43dSstefano_zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 459806656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 4599ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 460016f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 460106656605SStefano Zampini if (n_vertices) { 4602ffd830a3SStefano Zampini Mat S_VCT; 460306656605SStefano Zampini 460406656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 4605ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 460616f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 460706656605SStefano Zampini } 4608ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 46095b782168SStefano Zampini } else { 46105b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 461106656605SStefano Zampini } 461216f15bc4SStefano Zampini if (n_vertices && n_R) { 4613ffd830a3SStefano Zampini PetscScalar *av,*marray; 4614ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 4615ffd830a3SStefano Zampini PetscInt n; 4616ffd830a3SStefano Zampini PetscBool flg_row; 461706656605SStefano Zampini 4618ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 4619af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4620ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4621ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 4622ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4623ffd830a3SStefano Zampini for (i=0;i<n;i++) { 4624ffd830a3SStefano Zampini PetscInt j; 4625ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 4626ffd830a3SStefano Zampini } 4627ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4628ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4629ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 463006656605SStefano Zampini } 463106656605SStefano Zampini 4632ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 4633abc8f43dSstefano_zampini if (n_vertices) { 4634ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4635ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 4636ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 4637ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 463806656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4639c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 464006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 464106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 464206656605SStefano Zampini } 4643ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4644abc8f43dSstefano_zampini } 46455b782168SStefano Zampini if (B_C) { 4646ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 4647ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 4648ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 4649ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 4650ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4651c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 4652ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4653ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 465406656605SStefano Zampini } 4655ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 46565b782168SStefano Zampini } 465706656605SStefano Zampini /* coarse basis functions */ 465806656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 465906656605SStefano Zampini PetscScalar *y; 466006656605SStefano Zampini 4661ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 466206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 466306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 466406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 466506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 466606656605SStefano Zampini if (i<n_vertices) { 466706656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 466806656605SStefano Zampini } 466906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 467006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 467106656605SStefano Zampini 467206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 467306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 467406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 467506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 467606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 467706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 467806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 467906656605SStefano Zampini } 468006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 468106656605SStefano Zampini } 4682ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 4683ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 468406656605SStefano Zampini } 4685a6e023c1Sstefano_zampini 4686d62866d3SStefano Zampini /* free memory */ 468788ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 468806656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 468906656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 469006656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 469106656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 4692d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4693d62866d3SStefano Zampini if (n_vertices) { 4694d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 4695d62866d3SStefano Zampini } 4696d62866d3SStefano Zampini if (n_constraints) { 4697d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 4698d62866d3SStefano Zampini } 469988ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 470088ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 470188ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 4702d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 470388ebb749SStefano Zampini Mat coarse_sub_mat; 470425084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 470588ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 470688ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 470788ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 47088bec7fa6SStefano Zampini Mat C_B,CPHI; 47098bec7fa6SStefano Zampini IS is_dummy; 47108bec7fa6SStefano Zampini Vec mones; 471188ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 471288ebb749SStefano Zampini PetscReal real_value; 471388ebb749SStefano Zampini 4714a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 4715a3df083aSStefano Zampini Mat A; 4716a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 47177dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 47187dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 47197dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 47207dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4721a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 4722a3df083aSStefano Zampini } else { 472388ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 472488ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 472588ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 472688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4727a3df083aSStefano Zampini } 472888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 472988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 4730ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 473188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 473288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 473388ebb749SStefano Zampini } 473488ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 473588ebb749SStefano Zampini 473625084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47373301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 473825084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4739ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 474088ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 474188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 474288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 474388ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 474488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 474588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 474688ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 474788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 474888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 474988ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 475088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 475188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 475288ebb749SStefano Zampini } else { 475388ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 475488ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 475588ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 475688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 475788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 475888ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 475988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 476088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 476188ebb749SStefano Zampini } 476288ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 476388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 476488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4765511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 47664f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4767fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 47681683a169SBarry Smith const PetscScalar *data2; 47691683a169SBarry Smith PetscScalar *data; 47704f1b2e48SStefano Zampini PetscInt j; 4771d12edf2fSStefano Zampini 47724f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 47737dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4774d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 477586c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4776d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 47771683a169SBarry Smith ierr = MatDenseGetArrayRead(B0_BPHI,&data2);CHKERRQ(ierr); 47784f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 47794f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4780d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 47814f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 47824f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 47834f1b2e48SStefano Zampini } 4784d12edf2fSStefano Zampini } 4785d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 47861683a169SBarry Smith ierr = MatDenseRestoreArrayRead(B0_BPHI,&data2);CHKERRQ(ierr); 4787d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4788d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4789d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4790d12edf2fSStefano Zampini } 4791d12edf2fSStefano Zampini #if 0 4792d12edf2fSStefano Zampini { 4793d12edf2fSStefano Zampini PetscViewer viewer; 4794d12edf2fSStefano Zampini char filename[256]; 4795ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4796d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4797a7414863SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4798ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4799ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4800ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4801d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 4802a7414863SStefano Zampini if (pcbddc->coarse_phi_B) { 4803ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4804ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 480572b8c272SStefano Zampini } 4806ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4807ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4808ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4809ffd830a3SStefano Zampini } 4810ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4811ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4812ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4813ffd830a3SStefano Zampini } 481472b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4815ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4816ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4817ffd830a3SStefano Zampini } 4818fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->local_mat,"A");CHKERRQ(ierr); 4819fb6280fbSStefano Zampini ierr = MatView(pcbddc->local_mat,viewer);CHKERRQ(ierr); 4820fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->ConstraintMatrix,"C");CHKERRQ(ierr); 4821fb6280fbSStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,viewer);CHKERRQ(ierr); 4822fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_I_local,"I");CHKERRQ(ierr); 4823fb6280fbSStefano Zampini ierr = ISView(pcis->is_I_local,viewer);CHKERRQ(ierr); 4824fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_B_local,"B");CHKERRQ(ierr); 4825fb6280fbSStefano Zampini ierr = ISView(pcis->is_B_local,viewer);CHKERRQ(ierr); 4826fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->is_R_local,"R");CHKERRQ(ierr); 4827fb6280fbSStefano Zampini ierr = ISView(pcbddc->is_R_local,viewer);CHKERRQ(ierr); 4828d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4829d12edf2fSStefano Zampini } 4830d12edf2fSStefano Zampini #endif 483181d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 48328bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 48331575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 483406656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 48358bec7fa6SStefano Zampini 48368bec7fa6SStefano Zampini /* check constraints */ 4837a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 48387dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 48394f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 48408bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4841a00504b5SStefano Zampini } else { 4842a00504b5SStefano Zampini PetscScalar *data; 4843a00504b5SStefano Zampini Mat tmat; 4844a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4845a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4846a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4847a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4848a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4849a00504b5SStefano Zampini } 48508bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 48518bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 48528bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 48538bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4854bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4855ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4856bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4857bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4858bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4859bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4860bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 486188ebb749SStefano Zampini } 48628bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 48638bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 48648bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 48658bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 486625084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 486788ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 486888ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 486988ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 487088ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 487188ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 487288ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 487388ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 487488ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 487588ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 487688ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4877ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 487888ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 487988ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 488088ebb749SStefano Zampini } 488188ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 488288ebb749SStefano Zampini } 48838629588bSStefano Zampini /* get back data */ 48848629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 488543371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CorrectionSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 488688ebb749SStefano Zampini PetscFunctionReturn(0); 488788ebb749SStefano Zampini } 488888ebb749SStefano Zampini 48897dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4890aa0d41d4SStefano Zampini { 4891d65f70fdSStefano Zampini Mat *work_mat; 4892d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4893d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4894c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4895aa0d41d4SStefano Zampini PetscErrorCode ierr; 4896aa0d41d4SStefano Zampini 4897aa0d41d4SStefano Zampini PetscFunctionBegin; 4898d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4899d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4900d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4901d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4902aa0d41d4SStefano Zampini 4903d65f70fdSStefano Zampini if (!rsorted) { 4904906d46d4SStefano Zampini const PetscInt *idxs; 4905906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4906aa0d41d4SStefano Zampini 4907d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4908d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4909d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4910d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4911aa0d41d4SStefano Zampini } 4912d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4913d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4914d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4915d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4916aa0d41d4SStefano Zampini } 4917d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4918d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4919d65f70fdSStefano Zampini } else { 4920d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4921d65f70fdSStefano Zampini isrow_s = isrow; 4922aa0d41d4SStefano Zampini } 4923906d46d4SStefano Zampini 4924d65f70fdSStefano Zampini if (!csorted) { 4925d65f70fdSStefano Zampini if (isrow == iscol) { 4926d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4927d65f70fdSStefano Zampini iscol_s = isrow_s; 4928d65f70fdSStefano Zampini } else { 4929d65f70fdSStefano Zampini const PetscInt *idxs; 4930d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4931906d46d4SStefano Zampini 4932d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4933d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4934d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4935d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4936d65f70fdSStefano Zampini } 4937d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4938d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4939d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4940d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4941d65f70fdSStefano Zampini } 4942d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4943d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4944d65f70fdSStefano Zampini } 4945d65f70fdSStefano Zampini } else { 4946d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4947d65f70fdSStefano Zampini iscol_s = iscol; 4948d65f70fdSStefano Zampini } 4949d65f70fdSStefano Zampini 49507dae84e0SHong Zhang ierr = MatCreateSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4951d65f70fdSStefano Zampini 4952d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4953906d46d4SStefano Zampini Mat new_mat; 4954d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4955906d46d4SStefano Zampini 4956d65f70fdSStefano Zampini if (!rsorted) { 4957d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4958d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4959d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4960d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4961906d46d4SStefano Zampini } 4962d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4963d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 4964d65f70fdSStefano Zampini } else { 4965d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 4966906d46d4SStefano Zampini } 4967d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 4968d65f70fdSStefano Zampini 4969d65f70fdSStefano Zampini if (!csorted) { 4970d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 4971d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 4972d65f70fdSStefano Zampini is_perm_c = is_perm_r; 4973d65f70fdSStefano Zampini } else { 4974d65f70fdSStefano Zampini PetscInt *idxs_c,i; 4975f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 4976d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 4977d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4978d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 4979d65f70fdSStefano Zampini } 4980d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 4981d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 4982d65f70fdSStefano Zampini } 4983d65f70fdSStefano Zampini } else { 4984d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 4985d65f70fdSStefano Zampini } 4986d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 4987d65f70fdSStefano Zampini 4988d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 4989d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 4990d65f70fdSStefano Zampini work_mat[0] = new_mat; 4991d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 4992d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 4993d65f70fdSStefano Zampini } 4994d65f70fdSStefano Zampini 4995d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 4996d65f70fdSStefano Zampini *B = work_mat[0]; 4997d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 4998d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 4999d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 5000d65f70fdSStefano Zampini PetscFunctionReturn(0); 5001d65f70fdSStefano Zampini } 5002d65f70fdSStefano Zampini 50035e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 5004aa0d41d4SStefano Zampini { 5005aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 50065e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5007022d8d2bSstefano_zampini Mat new_mat,lA; 50085e8657edSStefano Zampini IS is_local,is_global; 5009d65f70fdSStefano Zampini PetscInt local_size; 5010d65f70fdSStefano Zampini PetscBool isseqaij; 5011aa0d41d4SStefano Zampini PetscErrorCode ierr; 5012aa0d41d4SStefano Zampini 5013aa0d41d4SStefano Zampini PetscFunctionBegin; 5014aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 50155e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 50165e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 5017b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 5018aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 50197dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 5020aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 5021906d46d4SStefano Zampini 5022906d46d4SStefano Zampini /* check */ 5023906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 5024906d46d4SStefano Zampini Vec x,x_change; 5025906d46d4SStefano Zampini PetscReal error; 5026906d46d4SStefano Zampini 50275e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 5028906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 50295e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 5030e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5031e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5032d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 503388428137SStefano Zampini if (!pcbddc->change_interior) { 503488428137SStefano Zampini const PetscScalar *x,*y,*v; 503588428137SStefano Zampini PetscReal lerror = 0.; 503688428137SStefano Zampini PetscInt i; 503788428137SStefano Zampini 503888428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 503988428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 504088428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 504188428137SStefano Zampini for (i=0;i<local_size;i++) 504288428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 504388428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 504488428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 504588428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 504688428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 504788428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5048637e8532SStefano Zampini if (error > PETSC_SMALL) { 5049637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 50506080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on I: %1.6e",error); 5051637e8532SStefano Zampini } else { 50526080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on I: %1.6e",error); 5053637e8532SStefano Zampini } 5054637e8532SStefano Zampini } 505588428137SStefano Zampini } 5056e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5057e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5058906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 5059906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 5060637e8532SStefano Zampini if (error > PETSC_SMALL) { 5061637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 50626080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e",error); 5063637e8532SStefano Zampini } else { 50646080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on N: %1.6e",error); 5065637e8532SStefano Zampini } 5066637e8532SStefano Zampini } 5067906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 5068906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 5069906d46d4SStefano Zampini } 5070906d46d4SStefano Zampini 5071022d8d2bSstefano_zampini /* lA is present if we are setting up an inner BDDC for a saddle point FETI-DP */ 5072022d8d2bSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 5073022d8d2bSstefano_zampini 507422d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 50759b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 507622d5777bSStefano Zampini if (isseqaij) { 5077a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 5078a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 5079022d8d2bSstefano_zampini if (lA) { 5080022d8d2bSstefano_zampini Mat work; 5081022d8d2bSstefano_zampini ierr = MatPtAP(lA,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 5082022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 5083022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 5084022d8d2bSstefano_zampini } 5085aa0d41d4SStefano Zampini } else { 5086a00504b5SStefano Zampini Mat work_mat; 50871cf9b237SStefano Zampini 5088a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 5089aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 5090a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 50911d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 5092022d8d2bSstefano_zampini if (lA) { 5093022d8d2bSstefano_zampini Mat work; 5094022d8d2bSstefano_zampini ierr = MatConvert(lA,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 5095022d8d2bSstefano_zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 5096022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 5097022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 5098022d8d2bSstefano_zampini } 5099aa0d41d4SStefano Zampini } 51003301b35fSStefano Zampini if (matis->A->symmetric_set) { 51013301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 5102e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 51033301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 5104e496cd5dSStefano Zampini #endif 51053301b35fSStefano Zampini } 5106d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 5107aa0d41d4SStefano Zampini PetscFunctionReturn(0); 5108aa0d41d4SStefano Zampini } 5109aa0d41d4SStefano Zampini 51108ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 5111a64d13efSStefano Zampini { 5112a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5113a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5114d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 511553892102SStefano Zampini PetscInt *idx_R_local=NULL; 51163a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 51173a50541eSStefano Zampini PetscInt vbs,bs; 51186816873aSStefano Zampini PetscBT bitmask=NULL; 5119a64d13efSStefano Zampini PetscErrorCode ierr; 5120a64d13efSStefano Zampini 5121a64d13efSStefano Zampini PetscFunctionBegin; 5122b23d619eSStefano Zampini /* 5123b23d619eSStefano Zampini No need to setup local scatters if 5124b23d619eSStefano Zampini - primal space is unchanged 5125b23d619eSStefano Zampini AND 5126b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 5127b23d619eSStefano Zampini AND 5128b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 5129b23d619eSStefano Zampini */ 5130b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 5131f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 5132f4ddd8eeSStefano Zampini } 5133f4ddd8eeSStefano Zampini /* destroy old objects */ 5134f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 5135f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 5136f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 5137a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 5138b371cd4fSStefano Zampini n_B = pcis->n_B; 5139b371cd4fSStefano Zampini n_D = pcis->n - n_B; 5140b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 51413a50541eSStefano Zampini 5142a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 51436816873aSStefano Zampini 514453892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 5145b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 5146854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 5147a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 5148a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 51490e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 5150a64d13efSStefano Zampini } 5151a64d13efSStefano Zampini 5152a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 51534641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 51546816873aSStefano Zampini idx_R_local[n_R++] = i; 5155a64d13efSStefano Zampini } 5156a64d13efSStefano Zampini } 5157df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 5158df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 51596816873aSStefano Zampini 5160df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5161df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 51626816873aSStefano Zampini } 51633a50541eSStefano Zampini 51643a50541eSStefano Zampini /* Block code */ 51653a50541eSStefano Zampini vbs = 1; 51663a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 51673a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 51683a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 51693a50541eSStefano Zampini PetscInt *vary; 5170b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 5171785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 5172*580bdb30SBarry Smith ierr = PetscArrayzero(vary,pcis->n/bs);CHKERRQ(ierr); 5173d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 5174d3df7717SStefano 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 */ 51750e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 5176d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 51773a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 51783a50541eSStefano Zampini is_blocked = PETSC_FALSE; 51793a50541eSStefano Zampini break; 51803a50541eSStefano Zampini } 51813a50541eSStefano Zampini } 5182d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 5183d3df7717SStefano Zampini } else { 5184d3df7717SStefano Zampini /* Verify directly the R set */ 5185d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 5186d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 5187d3df7717SStefano Zampini for (j=1; j<bs; j++) { 5188d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 5189d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 5190d3df7717SStefano Zampini break; 5191d3df7717SStefano Zampini } 5192d3df7717SStefano Zampini } 5193d3df7717SStefano Zampini } 5194d3df7717SStefano Zampini } 51953a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 51963a50541eSStefano Zampini vbs = bs; 51973a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 51983a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 51993a50541eSStefano Zampini } 52003a50541eSStefano Zampini } 52013a50541eSStefano Zampini } 52023a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 5203b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5204df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 520553892102SStefano Zampini 5206df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5207df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 520853892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 5209df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 521053892102SStefano Zampini } else { 52113a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 521253892102SStefano Zampini } 5213a64d13efSStefano Zampini 5214a64d13efSStefano Zampini /* print some info if requested */ 5215a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 5216a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5217a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 52181575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5219a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 52206080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %D, dirichlet_size = %D, boundary_size = %D\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 52216080607fSStefano 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); 5222a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5223a64d13efSStefano Zampini } 5224a64d13efSStefano Zampini 5225a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 5226b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 52276816873aSStefano Zampini IS is_aux1,is_aux2; 52286816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 52296816873aSStefano Zampini 52303a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5231854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 5232854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 5233a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 52344641a718SStefano Zampini for (i=0; i<n_D; i++) { 52354641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 52364641a718SStefano Zampini } 5237a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5238a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 52394641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 52404641a718SStefano Zampini aux_array1[j++] = i; 5241a64d13efSStefano Zampini } 5242a64d13efSStefano Zampini } 5243a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 5244a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5245a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 52464641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 52474641a718SStefano Zampini aux_array2[j++] = i; 5248a64d13efSStefano Zampini } 5249a64d13efSStefano Zampini } 5250a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5251a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 52529448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 5253a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 5254a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 5255a64d13efSStefano Zampini 52568eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 5257785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 5258a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 52594641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 52604641a718SStefano Zampini aux_array1[j++] = i; 5261a64d13efSStefano Zampini } 5262a64d13efSStefano Zampini } 5263a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 52649448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 5265a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 5266a64d13efSStefano Zampini } 52674641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 52683a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5269d62866d3SStefano Zampini } else { 5270df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 52716816873aSStefano Zampini IS tis; 52726816873aSStefano Zampini PetscInt schur_size; 52736816873aSStefano Zampini 5274df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 52756816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 52769448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 52776816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 52786816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 52796816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 52809448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 52816816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 5282d62866d3SStefano Zampini } 5283d62866d3SStefano Zampini } 5284a64d13efSStefano Zampini PetscFunctionReturn(0); 5285a64d13efSStefano Zampini } 5286a64d13efSStefano Zampini 528792cccca0SStefano Zampini static PetscErrorCode MatNullSpacePropagate_Private(Mat A, IS is, Mat B) 528892cccca0SStefano Zampini { 528992cccca0SStefano Zampini MatNullSpace NullSpace; 529092cccca0SStefano Zampini Mat dmat; 529192cccca0SStefano Zampini const Vec *nullvecs; 529292cccca0SStefano Zampini Vec v,v2,*nullvecs2; 529392cccca0SStefano Zampini VecScatter sct; 529492cccca0SStefano Zampini PetscInt k,nnsp_size,bsiz,n,N,bs; 529592cccca0SStefano Zampini PetscBool nnsp_has_cnst; 529692cccca0SStefano Zampini PetscErrorCode ierr; 529792cccca0SStefano Zampini 529892cccca0SStefano Zampini PetscFunctionBegin; 529992cccca0SStefano Zampini ierr = MatGetNullSpace(B,&NullSpace);CHKERRQ(ierr); 530092cccca0SStefano Zampini if (!NullSpace) { 530192cccca0SStefano Zampini ierr = MatGetNearNullSpace(B,&NullSpace);CHKERRQ(ierr); 530292cccca0SStefano Zampini } 530392cccca0SStefano Zampini if (NullSpace) PetscFunctionReturn(0); 530492cccca0SStefano Zampini ierr = MatGetNullSpace(A,&NullSpace);CHKERRQ(ierr); 530592cccca0SStefano Zampini if (!NullSpace) { 530692cccca0SStefano Zampini ierr = MatGetNearNullSpace(A,&NullSpace);CHKERRQ(ierr); 530792cccca0SStefano Zampini } 530892cccca0SStefano Zampini if (!NullSpace) PetscFunctionReturn(0); 530992cccca0SStefano Zampini ierr = MatCreateVecs(A,&v,NULL);CHKERRQ(ierr); 531092cccca0SStefano Zampini ierr = MatCreateVecs(B,&v2,NULL);CHKERRQ(ierr); 53119448b7f1SJunchao Zhang ierr = VecScatterCreate(v,is,v2,NULL,&sct);CHKERRQ(ierr); 531292cccca0SStefano Zampini ierr = MatNullSpaceGetVecs(NullSpace,&nnsp_has_cnst,&nnsp_size,(const Vec**)&nullvecs);CHKERRQ(ierr); 531392cccca0SStefano Zampini bsiz = nnsp_size+!!nnsp_has_cnst; 531492cccca0SStefano Zampini ierr = PetscMalloc1(bsiz,&nullvecs2);CHKERRQ(ierr); 531592cccca0SStefano Zampini ierr = VecGetBlockSize(v2,&bs);CHKERRQ(ierr); 531692cccca0SStefano Zampini ierr = VecGetSize(v2,&N);CHKERRQ(ierr); 531792cccca0SStefano Zampini ierr = VecGetLocalSize(v2,&n);CHKERRQ(ierr); 531892cccca0SStefano Zampini ierr = MatCreateDense(PetscObjectComm((PetscObject)B),n,PETSC_DECIDE,N,bsiz,NULL,&dmat);CHKERRQ(ierr); 531992cccca0SStefano Zampini for (k=0;k<nnsp_size;k++) { 532092cccca0SStefano Zampini PetscScalar *arr; 532192cccca0SStefano Zampini 532292cccca0SStefano Zampini ierr = MatDenseGetColumn(dmat,k,&arr);CHKERRQ(ierr); 532392cccca0SStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)B),bs,n,N,arr,&nullvecs2[k]);CHKERRQ(ierr); 532492cccca0SStefano Zampini ierr = VecScatterBegin(sct,nullvecs[k],nullvecs2[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 532592cccca0SStefano Zampini ierr = VecScatterEnd(sct,nullvecs[k],nullvecs2[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 532692cccca0SStefano Zampini ierr = MatDenseRestoreColumn(dmat,&arr);CHKERRQ(ierr); 532792cccca0SStefano Zampini } 532892cccca0SStefano Zampini if (nnsp_has_cnst) { 532992cccca0SStefano Zampini PetscScalar *arr; 533092cccca0SStefano Zampini 533192cccca0SStefano Zampini ierr = MatDenseGetColumn(dmat,nnsp_size,&arr);CHKERRQ(ierr); 533292cccca0SStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)B),bs,n,N,arr,&nullvecs2[nnsp_size]);CHKERRQ(ierr); 533392cccca0SStefano Zampini ierr = VecSet(nullvecs2[nnsp_size],1.0);CHKERRQ(ierr); 533492cccca0SStefano Zampini ierr = MatDenseRestoreColumn(dmat,&arr);CHKERRQ(ierr); 533592cccca0SStefano Zampini } 533692cccca0SStefano Zampini ierr = PCBDDCOrthonormalizeVecs(bsiz,nullvecs2);CHKERRQ(ierr); 533792cccca0SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)B),PETSC_FALSE,bsiz,nullvecs2,&NullSpace);CHKERRQ(ierr); 533892cccca0SStefano Zampini ierr = PetscObjectCompose((PetscObject)NullSpace,"_PBDDC_Null_dmat",(PetscObject)dmat);CHKERRQ(ierr); 533992cccca0SStefano Zampini ierr = MatDestroy(&dmat);CHKERRQ(ierr); 534092cccca0SStefano Zampini for (k=0;k<bsiz;k++) { 534192cccca0SStefano Zampini ierr = VecDestroy(&nullvecs2[k]);CHKERRQ(ierr); 534292cccca0SStefano Zampini } 534392cccca0SStefano Zampini ierr = PetscFree(nullvecs2);CHKERRQ(ierr); 534492cccca0SStefano Zampini ierr = MatSetNearNullSpace(B,NullSpace);CHKERRQ(ierr); 534592cccca0SStefano Zampini ierr = MatNullSpaceDestroy(&NullSpace);CHKERRQ(ierr); 534692cccca0SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 534792cccca0SStefano Zampini ierr = VecDestroy(&v2);CHKERRQ(ierr); 534892cccca0SStefano Zampini ierr = VecScatterDestroy(&sct);CHKERRQ(ierr); 534992cccca0SStefano Zampini PetscFunctionReturn(0); 535092cccca0SStefano Zampini } 5351304d26faSStefano Zampini 5352684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 5353304d26faSStefano Zampini { 5354304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5355304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 5356304d26faSStefano Zampini PC pc_temp; 5357304d26faSStefano Zampini Mat A_RR; 535892cccca0SStefano Zampini MatNullSpace nnsp; 5359f4ddd8eeSStefano Zampini MatReuse reuse; 5360304d26faSStefano Zampini PetscScalar m_one = -1.0; 5361304d26faSStefano Zampini PetscReal value; 536204708bb6SStefano Zampini PetscInt n_D,n_R; 536392cccca0SStefano Zampini PetscBool issbaij,opts; 5364304d26faSStefano Zampini PetscErrorCode ierr; 536592cccca0SStefano Zampini void (*f)(void) = 0; 5366312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 5367e604994aSStefano Zampini size_t len; 5368304d26faSStefano Zampini 5369304d26faSStefano Zampini PetscFunctionBegin; 537043371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalSolvers[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 5371e604994aSStefano Zampini /* compute prefixes */ 5372e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 5373e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 5374e604994aSStefano Zampini if (!pcbddc->current_level) { 5375a126751eSBarry Smith ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,sizeof(dir_prefix));CHKERRQ(ierr); 5376a126751eSBarry Smith ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,sizeof(neu_prefix));CHKERRQ(ierr); 5377a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,"pc_bddc_dirichlet_",sizeof(dir_prefix));CHKERRQ(ierr); 5378a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,"pc_bddc_neumann_",sizeof(neu_prefix));CHKERRQ(ierr); 5379e604994aSStefano Zampini } else { 538035529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 5381e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5382e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 5383312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5384312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 5385a126751eSBarry Smith /* Nonstandard use of PetscStrncpy() to only copy a portion of the input string */ 538634d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 538734d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5388a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,"pc_bddc_dirichlet_",sizeof(dir_prefix));CHKERRQ(ierr); 5389a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,"pc_bddc_neumann_",sizeof(neu_prefix));CHKERRQ(ierr); 5390a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,str_level,sizeof(dir_prefix));CHKERRQ(ierr); 5391a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,str_level,sizeof(neu_prefix));CHKERRQ(ierr); 5392e604994aSStefano Zampini } 5393e604994aSStefano Zampini 5394304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 5395684f6988SStefano Zampini if (dirichlet) { 5396d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5397450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 53986080607fSStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 5399450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 5400a3df083aSStefano Zampini Mat A_IIn; 5401a3df083aSStefano Zampini 5402a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 5403a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 5404a3df083aSStefano Zampini pcis->A_II = A_IIn; 5405a3df083aSStefano Zampini } 5406450f8f5eSStefano Zampini } 54073301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 5408d1e098c7SStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric);CHKERRQ(ierr); 5409964fefecSStefano Zampini } 5410ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 5411964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 541292cccca0SStefano Zampini opts = PETSC_FALSE; 5413304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 541492cccca0SStefano Zampini opts = PETSC_TRUE; 5415304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 5416304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 5417304d26faSStefano Zampini /* default */ 5418304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 5419e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 54202f37b69bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->pA_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 5421304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 54229577ea80SStefano Zampini if (issbaij) { 54239577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 54249577ea80SStefano Zampini } else { 5425304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 54269577ea80SStefano Zampini } 5427399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->ksp_D,pc->erroriffailure);CHKERRQ(ierr); 542892cccca0SStefano Zampini } 542992cccca0SStefano Zampini ierr = MatSetOptionsPrefix(pcis->pA_II,((PetscObject)pcbddc->ksp_D)->prefix);CHKERRQ(ierr); 54302f37b69bSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->pA_II);CHKERRQ(ierr); 5431304d26faSStefano Zampini /* Allow user's customization */ 543292cccca0SStefano Zampini if (opts) { 5433304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 543492cccca0SStefano Zampini } 543592cccca0SStefano Zampini if (pcbddc->NullSpace_corr[0]) { /* approximate solver, propagate NearNullSpace */ 543692cccca0SStefano Zampini ierr = MatNullSpacePropagate_Private(pcbddc->local_mat,pcis->is_I_local,pcis->pA_II);CHKERRQ(ierr); 543792cccca0SStefano Zampini } 543892cccca0SStefano Zampini ierr = MatGetNearNullSpace(pcis->pA_II,&nnsp);CHKERRQ(ierr); 543992cccca0SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5440cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 544192cccca0SStefano Zampini if (f && pcbddc->mat_graph->cloc && !nnsp) { 5442cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5443cd18cfedSStefano Zampini const PetscInt *idxs; 5444cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5445cd18cfedSStefano Zampini 5446cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcis->is_I_local,&nl);CHKERRQ(ierr); 5447cd18cfedSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5448cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5449cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5450cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5451cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5452cd18cfedSStefano Zampini } 5453cd18cfedSStefano Zampini } 5454cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5455cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5456cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5457cd18cfedSStefano Zampini } 5458b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5459df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5460d62866d3SStefano Zampini 5461df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 5462d5574798SStefano Zampini } 546392cccca0SStefano Zampini 5464304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5465304d26faSStefano Zampini if (!n_D) { 5466304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5467304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5468304d26faSStefano Zampini } 5469304d26faSStefano Zampini /* set ksp_D into pcis data */ 5470304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 547192cccca0SStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 5472304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 5473684f6988SStefano Zampini } 5474304d26faSStefano Zampini 5475304d26faSStefano Zampini /* NEUMANN PROBLEM */ 5476684f6988SStefano Zampini A_RR = 0; 5477684f6988SStefano Zampini if (neumann) { 5478d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 547904708bb6SStefano Zampini PetscInt ibs,mbs; 54800aa714b2SStefano Zampini PetscBool issbaij, reuse_neumann_solver; 548104708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 54820aa714b2SStefano Zampini 54830aa714b2SStefano Zampini reuse_neumann_solver = PETSC_FALSE; 54840aa714b2SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 54850aa714b2SStefano Zampini IS iP; 54860aa714b2SStefano Zampini 54870aa714b2SStefano Zampini reuse_neumann_solver = PETSC_TRUE; 54880aa714b2SStefano Zampini ierr = PetscObjectQuery((PetscObject)sub_schurs->A,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 54890aa714b2SStefano Zampini if (iP) reuse_neumann_solver = PETSC_FALSE; 54900aa714b2SStefano Zampini } 5491f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 54928ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 5493f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 5494f4ddd8eeSStefano Zampini PetscInt nn_R; 549581d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 5496f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5497f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 5498f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 5499f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 5500f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5501f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5502f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 5503727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 5504f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5505f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5506f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 5507f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 5508f4ddd8eeSStefano Zampini } 5509f4ddd8eeSStefano Zampini } 5510f4ddd8eeSStefano Zampini /* last check */ 5511d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 5512f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5513f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5514f4ddd8eeSStefano Zampini } 5515f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 5516f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5517f4ddd8eeSStefano Zampini } 5518a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 5519af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 5520af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 552104708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 552204708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 552304708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 552404708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 552504708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 5526af732b37SStefano Zampini } else { 5527511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 55286816873aSStefano Zampini } 552904708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 553004708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 553104708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 553204708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 553304708bb6SStefano Zampini } else { 5534511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 553504708bb6SStefano Zampini } 553604708bb6SStefano Zampini } 5537a00504b5SStefano Zampini /* extract A_RR */ 55380aa714b2SStefano Zampini if (reuse_neumann_solver) { 5539a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5540a00504b5SStefano Zampini 5541a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 554216e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5543a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 554416e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 554516e386b8SStefano Zampini } else { 55467dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 5547a00504b5SStefano Zampini } 5548a00504b5SStefano Zampini } else { 5549a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5550a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 5551a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5552a00504b5SStefano Zampini } 5553a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 55547dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 555516e386b8SStefano Zampini } 55563301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 5557d1e098c7SStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric);CHKERRQ(ierr); 55586816873aSStefano Zampini } 555992cccca0SStefano Zampini opts = PETSC_FALSE; 5560f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 556192cccca0SStefano Zampini opts = PETSC_TRUE; 5562304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 5563304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 5564304d26faSStefano Zampini /* default */ 5565304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 5566e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 5567304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 55689577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 55699577ea80SStefano Zampini if (issbaij) { 55709577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 55719577ea80SStefano Zampini } else { 5572304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 55739577ea80SStefano Zampini } 5574399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->ksp_R,pc->erroriffailure);CHKERRQ(ierr); 557592cccca0SStefano Zampini } 55762f37b69bSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 557792cccca0SStefano Zampini ierr = MatSetOptionsPrefix(A_RR,((PetscObject)pcbddc->ksp_R)->prefix);CHKERRQ(ierr); 557892cccca0SStefano Zampini if (opts) { /* Allow user's customization once */ 5579304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 558092cccca0SStefano Zampini } 558192cccca0SStefano Zampini if (pcbddc->NullSpace_corr[2]) { /* approximate solver, propagate NearNullSpace */ 558292cccca0SStefano Zampini ierr = MatNullSpacePropagate_Private(pcbddc->local_mat,pcbddc->is_R_local,A_RR);CHKERRQ(ierr); 558392cccca0SStefano Zampini } 558492cccca0SStefano Zampini ierr = MatGetNearNullSpace(A_RR,&nnsp);CHKERRQ(ierr); 558592cccca0SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5586cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 558792cccca0SStefano Zampini if (f && pcbddc->mat_graph->cloc && !nnsp) { 5588cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5589cd18cfedSStefano Zampini const PetscInt *idxs; 5590cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5591cd18cfedSStefano Zampini 5592cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcbddc->is_R_local,&nl);CHKERRQ(ierr); 5593cd18cfedSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5594cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5595cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5596cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5597cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5598cd18cfedSStefano Zampini } 5599cd18cfedSStefano Zampini } 5600cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5601cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5602cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5603cd18cfedSStefano Zampini } 560492cccca0SStefano Zampini 5605304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5606304d26faSStefano Zampini if (!n_R) { 5607304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5608304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5609304d26faSStefano Zampini } 5610df4d28bfSStefano Zampini /* Reuse solver if it is present */ 56110aa714b2SStefano Zampini if (reuse_neumann_solver) { 5612df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5613d62866d3SStefano Zampini 5614df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 5615d62866d3SStefano Zampini } 5616684f6988SStefano Zampini } 5617304d26faSStefano Zampini 5618684f6988SStefano Zampini if (pcbddc->dbg_flag) { 5619684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 56201575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5621684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5622684f6988SStefano Zampini } 5623c7017625SStefano Zampini 5624c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 5625c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 5626c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 5627c7017625SStefano Zampini } 5628c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 5629c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 5630c7017625SStefano Zampini } 5631c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 5632c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 5633c7017625SStefano Zampini } 5634c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 5635c7017625SStefano Zampini if (pcbddc->dbg_flag) { 5636684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 56370fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 56380fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 56390fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 5640c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 56410fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 56420fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 5643e604994aSStefano 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); 5644304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5645304d26faSStefano Zampini } 5646684f6988SStefano Zampini if (neumann) { /* Neumann */ 56470fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 56480fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 56490fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 5650c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 56510fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 56520fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 5653e604994aSStefano 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); 5654304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5655304d26faSStefano Zampini } 5656684f6988SStefano Zampini } 56575cbda25cSStefano Zampini /* free Neumann problem's matrix */ 56585cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 565943371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalSolvers[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 5660304d26faSStefano Zampini PetscFunctionReturn(0); 5661304d26faSStefano Zampini } 5662304d26faSStefano Zampini 566380677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 5664674ae819SStefano Zampini { 5665674ae819SStefano Zampini PetscErrorCode ierr; 5666674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5667be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5668b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 5669674ae819SStefano Zampini 5670674ae819SStefano Zampini PetscFunctionBegin; 5671b334f244SStefano Zampini if (!reuse_solver) { 567280677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 567320c7b377SStefano Zampini } 567480677318SStefano Zampini if (!pcbddc->switch_static) { 567580677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 567680677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 567780677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 567820c7b377SStefano Zampini } 5679b334f244SStefano Zampini if (!reuse_solver) { 568080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 568180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 568220c7b377SStefano Zampini } else { 5683df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5684be83ff47SStefano Zampini 5685df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5686df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 568720c7b377SStefano Zampini } 5688be83ff47SStefano Zampini } else { 568980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 569080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 569180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 569280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 569380677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 569480677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 569580677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 569680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 569780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5698674ae819SStefano Zampini } 5699674ae819SStefano Zampini } 5700b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 570180677318SStefano Zampini if (applytranspose) { 570280677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 570380677318SStefano Zampini } else { 570480677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 570580677318SStefano Zampini } 5706c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec1_R);CHKERRQ(ierr); 5707be83ff47SStefano Zampini } else { 5708df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5709be83ff47SStefano Zampini 5710be83ff47SStefano Zampini if (applytranspose) { 5711df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5712be83ff47SStefano Zampini } else { 5713df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5714be83ff47SStefano Zampini } 5715be83ff47SStefano Zampini } 571680677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 571780677318SStefano Zampini if (!pcbddc->switch_static) { 5718b334f244SStefano Zampini if (!reuse_solver) { 571980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 572080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5721be83ff47SStefano Zampini } else { 5722df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5723be83ff47SStefano Zampini 5724df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5725df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5726be83ff47SStefano Zampini } 572780677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 572880677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 572980677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 573080677318SStefano Zampini } 573180677318SStefano Zampini } else { 573280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 573380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 573480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 573580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 573680677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 573780677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 573880677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 573980677318SStefano Zampini } 574080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 574180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 574280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 574380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5744674ae819SStefano Zampini } 5745674ae819SStefano Zampini PetscFunctionReturn(0); 5746674ae819SStefano Zampini } 5747674ae819SStefano Zampini 5748dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 5749dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 5750674ae819SStefano Zampini { 5751674ae819SStefano Zampini PetscErrorCode ierr; 5752674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5753674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 5754674ae819SStefano Zampini const PetscScalar zero = 0.0; 5755674ae819SStefano Zampini 5756674ae819SStefano Zampini PetscFunctionBegin; 5757dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 57584fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5759dc359a40SStefano Zampini if (applytranspose) { 5760674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 57618eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 5762dc359a40SStefano Zampini } else { 5763674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 5764674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 576515aaf578SStefano Zampini } 57664fee134fSStefano Zampini } else { 57674fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 57684fee134fSStefano Zampini } 5769efc2fbd9SStefano Zampini 5770efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 57714f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5772efc2fbd9SStefano Zampini PetscScalar *array; 57734f1b2e48SStefano Zampini PetscInt j; 5774efc2fbd9SStefano Zampini 5775efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 57764f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 5777efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5778efc2fbd9SStefano Zampini } 5779efc2fbd9SStefano Zampini 578012edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 578112edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 578212edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 578312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 578412edc857SStefano Zampini 57859f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 578612edc857SStefano Zampini if (pcbddc->coarse_ksp) { 578751694757SStefano Zampini Mat coarse_mat; 5788964fefecSStefano Zampini Vec rhs,sol; 578951694757SStefano Zampini MatNullSpace nullsp; 579027b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 5791964fefecSStefano Zampini 579227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 579327b6a85dSStefano Zampini PC coarse_pc; 579427b6a85dSStefano Zampini 579527b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 579627b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 579727b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 579827b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 579927b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 580027b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 58013bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 580227b6a85dSStefano Zampini } 580327b6a85dSStefano Zampini } 5804964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 5805964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 580651694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 580712edc857SStefano Zampini if (applytranspose) { 58089a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 5809964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 5810c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->coarse_ksp,pc,sol);CHKERRQ(ierr); 58119bfcb8eaSStefano Zampini ierr = MatGetTransposeNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 58129bfcb8eaSStefano Zampini if (nullsp) { 58139bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 58149bfcb8eaSStefano Zampini } 58152701bc32SStefano Zampini } else { 58169bfcb8eaSStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 58171f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 58182701bc32SStefano Zampini PC coarse_pc; 58192701bc32SStefano Zampini 58209bfcb8eaSStefano Zampini if (nullsp) { 58219bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 58229bfcb8eaSStefano Zampini } 58232701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 58242701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 58253e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 58262701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 582712edc857SStefano Zampini } else { 5828964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 5829c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->coarse_ksp,pc,sol);CHKERRQ(ierr); 58309bfcb8eaSStefano Zampini if (nullsp) { 58319bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 58329bfcb8eaSStefano Zampini } 583312edc857SStefano Zampini } 58342701bc32SStefano Zampini } 58351d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 583627b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 583727b6a85dSStefano Zampini PC coarse_pc; 583827b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 583927b6a85dSStefano Zampini 584027b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 584127b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 584227b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 58433bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 584427b6a85dSStefano Zampini } 584512edc857SStefano Zampini } 5846674ae819SStefano Zampini 5847674ae819SStefano Zampini /* Local solution on R nodes */ 58484fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 584980677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 58509f00e9b4SStefano Zampini } 58519f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 58529f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 585312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5854674ae819SStefano Zampini 58554fee134fSStefano Zampini /* Sum contributions from the two levels */ 58564fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5857dc359a40SStefano Zampini if (applytranspose) { 5858dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5859dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5860dc359a40SStefano Zampini } else { 5861674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 58628eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5863dc359a40SStefano Zampini } 5864efc2fbd9SStefano Zampini /* store p0 */ 58654f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5866efc2fbd9SStefano Zampini PetscScalar *array; 58674f1b2e48SStefano Zampini PetscInt j; 5868efc2fbd9SStefano Zampini 5869efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 58704f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 5871efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5872efc2fbd9SStefano Zampini } 58734fee134fSStefano Zampini } else { /* expand the coarse solution */ 58744fee134fSStefano Zampini if (applytranspose) { 58754fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 58764fee134fSStefano Zampini } else { 58774fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 58784fee134fSStefano Zampini } 58794fee134fSStefano Zampini } 5880674ae819SStefano Zampini PetscFunctionReturn(0); 5881674ae819SStefano Zampini } 5882674ae819SStefano Zampini 588312edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 5884674ae819SStefano Zampini { 5885674ae819SStefano Zampini PetscErrorCode ierr; 5886674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 588758da7f69SStefano Zampini PetscScalar *array; 588812edc857SStefano Zampini Vec from,to; 5889674ae819SStefano Zampini 5890674ae819SStefano Zampini PetscFunctionBegin; 589112edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 589212edc857SStefano Zampini from = pcbddc->coarse_vec; 589312edc857SStefano Zampini to = pcbddc->vec1_P; 589412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 589512edc857SStefano Zampini Vec tvec; 589658da7f69SStefano Zampini 589758da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 589858da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 589912edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 590058da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 590158da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 590258da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 590312edc857SStefano Zampini } 590412edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 590512edc857SStefano Zampini from = pcbddc->vec1_P; 590612edc857SStefano Zampini to = pcbddc->coarse_vec; 590712edc857SStefano Zampini } 590812edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 5909674ae819SStefano Zampini PetscFunctionReturn(0); 5910674ae819SStefano Zampini } 5911674ae819SStefano Zampini 591212edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 5913674ae819SStefano Zampini { 5914674ae819SStefano Zampini PetscErrorCode ierr; 5915674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 591658da7f69SStefano Zampini PetscScalar *array; 591712edc857SStefano Zampini Vec from,to; 5918674ae819SStefano Zampini 5919674ae819SStefano Zampini PetscFunctionBegin; 592012edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 592112edc857SStefano Zampini from = pcbddc->coarse_vec; 592212edc857SStefano Zampini to = pcbddc->vec1_P; 592312edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 592412edc857SStefano Zampini from = pcbddc->vec1_P; 592512edc857SStefano Zampini to = pcbddc->coarse_vec; 592612edc857SStefano Zampini } 592712edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 592812edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 592912edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 593012edc857SStefano Zampini Vec tvec; 593158da7f69SStefano Zampini 593212edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 593358da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 593458da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 593558da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 593658da7f69SStefano Zampini } 593758da7f69SStefano Zampini } else { 593858da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 593958da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 594012edc857SStefano Zampini } 594112edc857SStefano Zampini } 5942674ae819SStefano Zampini PetscFunctionReturn(0); 5943674ae819SStefano Zampini } 5944674ae819SStefano Zampini 5945984c4197SStefano Zampini /* uncomment for testing purposes */ 5946984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 5947674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 5948674ae819SStefano Zampini { 5949674ae819SStefano Zampini PetscErrorCode ierr; 5950674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5951674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5952674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5953984c4197SStefano Zampini /* one and zero */ 5954984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 5955984c4197SStefano Zampini /* space to store constraints and their local indices */ 59569162d606SStefano Zampini PetscScalar *constraints_data; 59579162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 59589162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 59599162d606SStefano Zampini PetscInt *constraints_n; 5960984c4197SStefano Zampini /* iterators */ 5961b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 5962984c4197SStefano Zampini /* BLAS integers */ 5963e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 5964e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 5965c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 5966727cdba6SStefano Zampini /* reuse */ 59670e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 59680e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 5969984c4197SStefano Zampini /* change of basis */ 5970b3d85658SStefano Zampini PetscBool qr_needed; 59719162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 5972984c4197SStefano Zampini /* auxiliary stuff */ 597364efe560SStefano Zampini PetscInt *nnz,*is_indices; 59748a0068c3SStefano Zampini PetscInt ncc; 5975984c4197SStefano Zampini /* some quantities */ 597645a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 5977a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 597857715f18SStefano Zampini PetscReal tol; /* tolerance for retaining eigenmodes */ 5979984c4197SStefano Zampini 5980674ae819SStefano Zampini PetscFunctionBegin; 598157715f18SStefano Zampini tol = PetscSqrtReal(PETSC_SMALL); 59828e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 59838e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 59848e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 598516909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 5986088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 5987088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 59880e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 59890e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 5990*580bdb30SBarry Smith ierr = PetscArraycpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc);CHKERRQ(ierr); 5991*580bdb30SBarry Smith ierr = PetscArraycpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc);CHKERRQ(ierr); 59920e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 5993088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5994cf5a6209SStefano Zampini 5995cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 59969162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 5997cf5a6209SStefano Zampini MatNullSpace nearnullsp; 5998cf5a6209SStefano Zampini const Vec *nearnullvecs; 5999cf5a6209SStefano Zampini Vec *localnearnullsp; 6000cf5a6209SStefano Zampini PetscScalar *array; 6001cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 6002cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 6003674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 6004b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 6005674ae819SStefano Zampini PetscScalar *work; 6006674ae819SStefano Zampini PetscReal *singular_vals; 6007674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6008674ae819SStefano Zampini PetscReal *rwork; 6009674ae819SStefano Zampini #endif 6010674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 6011674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 6012674ae819SStefano Zampini #else 6013964fefecSStefano Zampini PetscBLASInt dummy_int=1; 6014964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 6015674ae819SStefano Zampini #endif 6016674ae819SStefano Zampini 6017674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 6018d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 6019e4d548c7SStefano Zampini /* print some info */ 60205c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 6021e4d548c7SStefano Zampini PetscInt nv; 6022e4d548c7SStefano Zampini 6023c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6024e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 6025e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6026e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 60276080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%D)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 60286080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%D)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 60296080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%D)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 6030e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6031e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6032e4d548c7SStefano Zampini } 6033e4d548c7SStefano Zampini 6034d06fc5fdSStefano Zampini /* free unneeded index sets */ 6035d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 6036d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 6037674ae819SStefano Zampini } 6038d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 6039d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 6040d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 6041d06fc5fdSStefano Zampini } 6042d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 6043d06fc5fdSStefano Zampini n_ISForEdges = 0; 6044d06fc5fdSStefano Zampini } 6045d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 6046d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 6047d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 6048d06fc5fdSStefano Zampini } 6049d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 6050d06fc5fdSStefano Zampini n_ISForFaces = 0; 6051d06fc5fdSStefano Zampini } 605270022509SStefano Zampini 6053674ae819SStefano Zampini /* check if near null space is attached to global mat */ 6054674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 6055674ae819SStefano Zampini if (nearnullsp) { 6056674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 6057f4ddd8eeSStefano Zampini /* remove any stored info */ 6058f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 6059f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 6060f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 6061f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 6062f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 6063473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 6064f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 6065f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 6066f4ddd8eeSStefano Zampini } 6067984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 6068984c4197SStefano Zampini nnsp_size = 0; 6069674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 6070674ae819SStefano Zampini } 6071984c4197SStefano Zampini /* get max number of constraints on a single cc */ 6072984c4197SStefano Zampini max_constraints = nnsp_size; 6073984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 6074984c4197SStefano Zampini 6075674ae819SStefano Zampini /* 6076674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 60779162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 60789162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 60799162d606SStefano Zampini There can be multiple constraints per connected component 6080674ae819SStefano Zampini */ 6081674ae819SStefano Zampini n_vertices = 0; 6082674ae819SStefano Zampini if (ISForVertices) { 6083674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 6084674ae819SStefano Zampini } 60859162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 60869162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 60879162d606SStefano Zampini 60889162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 60899162d606SStefano Zampini total_counts *= max_constraints; 6090674ae819SStefano Zampini total_counts += n_vertices; 60914641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 60929162d606SStefano Zampini 6093674ae819SStefano Zampini total_counts = 0; 6094674ae819SStefano Zampini max_size_of_constraint = 0; 6095674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 60969162d606SStefano Zampini IS used_is; 6097674ae819SStefano Zampini if (i<n_ISForEdges) { 60989162d606SStefano Zampini used_is = ISForEdges[i]; 6099674ae819SStefano Zampini } else { 61009162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 6101674ae819SStefano Zampini } 61029162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 6103674ae819SStefano Zampini total_counts += j; 6104674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 6105674ae819SStefano Zampini } 61069162d606SStefano 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); 61079162d606SStefano Zampini 6108984c4197SStefano Zampini /* get local part of global near null space vectors */ 6109785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 6110984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 6111984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 6112e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6113e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6114984c4197SStefano Zampini } 6115674ae819SStefano Zampini 6116242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 6117242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 6118a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 6119242a89d7SStefano Zampini 6120984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 6121a773dcb8SStefano Zampini if (!skip_lapack) { 6122674ae819SStefano Zampini PetscScalar temp_work; 6123911cabfeSStefano Zampini 6124674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 6125984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 6126785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 6127785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 6128785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 6129674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6130785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 6131674ae819SStefano Zampini #endif 6132674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 6133c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 6134c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 6135674ae819SStefano Zampini lwork = -1; 6136674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6137674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 6138c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 6139674ae819SStefano Zampini #else 6140c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 6141674ae819SStefano Zampini #endif 6142674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6143984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 6144674ae819SStefano Zampini #else /* on missing GESVD */ 6145674ae819SStefano Zampini /* SVD */ 6146674ae819SStefano Zampini PetscInt max_n,min_n; 6147674ae819SStefano Zampini max_n = max_size_of_constraint; 6148984c4197SStefano Zampini min_n = max_constraints; 6149984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 6150674ae819SStefano Zampini min_n = max_size_of_constraint; 6151984c4197SStefano Zampini max_n = max_constraints; 6152674ae819SStefano Zampini } 6153785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 6154674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6155785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 6156674ae819SStefano Zampini #endif 6157674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 6158674ae819SStefano Zampini lwork = -1; 6159e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 6160e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 6161b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 6162674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6163674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 61649162d606SStefano 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)); 6165674ae819SStefano Zampini #else 61669162d606SStefano 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)); 6167674ae819SStefano Zampini #endif 6168674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6169984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 6170984c4197SStefano Zampini #endif /* on missing GESVD */ 6171674ae819SStefano Zampini /* Allocate optimal workspace */ 6172674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 6173854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 6174674ae819SStefano Zampini } 6175674ae819SStefano Zampini /* Now we can loop on constraining sets */ 6176674ae819SStefano Zampini total_counts = 0; 61779162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 61789162d606SStefano Zampini constraints_data_ptr[0] = 0; 6179674ae819SStefano Zampini /* vertices */ 61809162d606SStefano Zampini if (n_vertices) { 6181674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6182*580bdb30SBarry Smith ierr = PetscArraycpy(constraints_idxs,is_indices,n_vertices);CHKERRQ(ierr); 6183674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 61849162d606SStefano Zampini constraints_n[total_counts] = 1; 61859162d606SStefano Zampini constraints_data[total_counts] = 1.0; 61869162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 61879162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 6188674ae819SStefano Zampini total_counts++; 6189674ae819SStefano Zampini } 6190674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6191674ae819SStefano Zampini n_vertices = total_counts; 6192674ae819SStefano Zampini } 6193984c4197SStefano Zampini 6194674ae819SStefano Zampini /* edges and faces */ 61959162d606SStefano Zampini total_counts_cc = total_counts; 6196911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 61979162d606SStefano Zampini IS used_is; 61989162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 61999162d606SStefano Zampini 6200911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 62019162d606SStefano Zampini used_is = ISForEdges[ncc]; 6202984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 6203674ae819SStefano Zampini } else { 62049162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 6205984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 6206674ae819SStefano Zampini } 6207674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 62089162d606SStefano Zampini 62099162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 62109162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6211984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 6212984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 6213674ae819SStefano Zampini if (nnsp_has_cnst) { 62145b08dc53SStefano Zampini PetscScalar quad_value; 62159162d606SStefano Zampini 6216*580bdb30SBarry Smith ierr = PetscArraycpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint);CHKERRQ(ierr); 62179162d606SStefano Zampini idxs_copied = PETSC_TRUE; 62189162d606SStefano Zampini 6219a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 6220674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 6221a773dcb8SStefano Zampini } else { 6222a773dcb8SStefano Zampini quad_value = 1.0; 6223a773dcb8SStefano Zampini } 6224674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 62259162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 6226674ae819SStefano Zampini } 62279162d606SStefano Zampini temp_constraints++; 6228674ae819SStefano Zampini total_counts++; 6229674ae819SStefano Zampini } 6230674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 6231984c4197SStefano Zampini PetscReal real_value; 62329162d606SStefano Zampini PetscScalar *ptr_to_data; 62339162d606SStefano Zampini 6234984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 62359162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 6236674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 62379162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 6238674ae819SStefano Zampini } 6239984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 6240984c4197SStefano Zampini /* check if array is null on the connected component */ 6241e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 62429162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 624357715f18SStefano Zampini if (real_value > tol*size_of_constraint) { /* keep indices and values */ 6244674ae819SStefano Zampini temp_constraints++; 6245674ae819SStefano Zampini total_counts++; 62469162d606SStefano Zampini if (!idxs_copied) { 6247*580bdb30SBarry Smith ierr = PetscArraycpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint);CHKERRQ(ierr); 62489162d606SStefano Zampini idxs_copied = PETSC_TRUE; 6249674ae819SStefano Zampini } 6250674ae819SStefano Zampini } 62519162d606SStefano Zampini } 62529162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 625345a1bb75SStefano Zampini valid_constraints = temp_constraints; 6254eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 6255a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 62569162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 62579162d606SStefano Zampini 62589162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 6259a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 62609162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 6261a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 62629162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 6263a773dcb8SStefano Zampini } else { /* perform SVD */ 62649162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 6265674ae819SStefano Zampini 6266674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 6267984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 6268984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 6269984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 6270984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 6271984c4197SStefano Zampini from that computed using LAPACKgesvd 6272984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 6273984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 6274*580bdb30SBarry Smith ierr = PetscArrayzero(correlation_mat,temp_constraints*temp_constraints);CHKERRQ(ierr); 6275674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 6276e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6277984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6278674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 6279674ae819SStefano Zampini for (k=0;k<j+1;k++) { 62809162d606SStefano 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)); 6281674ae819SStefano Zampini } 6282674ae819SStefano Zampini } 6283e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 6284e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6285e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 6286674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 6287c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 6288674ae819SStefano Zampini #else 6289c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 6290674ae819SStefano Zampini #endif 6291674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6292984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 6293984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 6294674ae819SStefano Zampini j = 0; 629587b3baaaSStefano Zampini while (j < temp_constraints && singular_vals[j]/singular_vals[temp_constraints-1] < tol) j++; 6296674ae819SStefano Zampini total_counts = total_counts-j; 629745a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 6298e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 6299c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 6300c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6301c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 6302c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6303c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 6304c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6305674ae819SStefano Zampini if (j<temp_constraints) { 6306984c4197SStefano Zampini PetscInt ii; 6307984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 6308674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 63099162d606SStefano 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)); 6310674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6311984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 6312674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 63139162d606SStefano 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]; 6314674ae819SStefano Zampini } 6315674ae819SStefano Zampini } 6316674ae819SStefano Zampini } 6317674ae819SStefano Zampini #else /* on missing GESVD */ 6318e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 6319e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6320b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6321674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6322674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 63239162d606SStefano 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)); 6324674ae819SStefano Zampini #else 63259162d606SStefano 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)); 6326674ae819SStefano Zampini #endif 6327984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 6328674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6329984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 6330e310c8b4SStefano Zampini k = temp_constraints; 6331e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 6332674ae819SStefano Zampini j = 0; 633387b3baaaSStefano Zampini while (j < k && singular_vals[k-j-1]/singular_vals[0] < tol) j++; 633445a1bb75SStefano Zampini valid_constraints = k-j; 6335911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 6336984c4197SStefano Zampini #endif /* on missing GESVD */ 6337674ae819SStefano Zampini } 6338a773dcb8SStefano Zampini } 63399162d606SStefano Zampini /* update pointers information */ 63409162d606SStefano Zampini if (valid_constraints) { 63419162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 63429162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 63439162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 63449162d606SStefano Zampini /* set change_of_basis flag */ 634545a1bb75SStefano Zampini if (boolforchange) { 6346b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 63479162d606SStefano Zampini } 6348b3d85658SStefano Zampini total_counts_cc++; 634945a1bb75SStefano Zampini } 635045a1bb75SStefano Zampini } 6351984c4197SStefano Zampini /* free workspace */ 63528f1c130eSStefano Zampini if (!skip_lapack) { 6353984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 6354984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6355984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 6356984c4197SStefano Zampini #endif 6357984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 6358984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 6359984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 6360984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 6361984c4197SStefano Zampini #endif 6362984c4197SStefano Zampini } 6363984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 6364984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 6365984c4197SStefano Zampini } 6366984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 6367cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 6368cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 6369cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 6370cf5a6209SStefano Zampini } 6371cf5a6209SStefano Zampini if (n_ISForFaces) { 6372cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 6373cf5a6209SStefano Zampini } 6374cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 6375cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 6376cf5a6209SStefano Zampini } 6377cf5a6209SStefano Zampini if (n_ISForEdges) { 6378cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 6379cf5a6209SStefano Zampini } 6380cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 638108122e43SStefano Zampini } else { 638208122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 6383984c4197SStefano Zampini 638408122e43SStefano Zampini total_counts = 0; 638508122e43SStefano Zampini n_vertices = 0; 6386d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 6387d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 638808122e43SStefano Zampini } 638908122e43SStefano Zampini max_constraints = 0; 63909162d606SStefano Zampini total_counts_cc = 0; 639108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 639208122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 63939162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 639408122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 639508122e43SStefano Zampini } 63969162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 63979162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 63989162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 63999162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 640074d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 64019162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 64029162d606SStefano Zampini total_counts_cc = 0; 64039162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 64049162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 64059162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 640608122e43SStefano Zampini } 640708122e43SStefano Zampini } 640808122e43SStefano Zampini 64098bec7fa6SStefano Zampini max_size_of_constraint = 0; 64109162d606SStefano 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]); 64119162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 641208122e43SStefano Zampini /* Change of basis */ 6413b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 641408122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 641508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 641608122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 6417b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 641808122e43SStefano Zampini } 641908122e43SStefano Zampini } 642008122e43SStefano Zampini } 642108122e43SStefano Zampini } 6422984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 64234f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 642408122e43SStefano Zampini 64259162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 64269162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 64276080607fSStefano 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",constraints_idxs_ptr[total_counts_cc],i); 6428674ae819SStefano Zampini 6429674ae819SStefano Zampini /* Create constraint matrix */ 6430674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 643116f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 6432984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 6433984c4197SStefano Zampini 6434984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 6435a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 64365a52fde0SStefano Zampini qr_needed = pcbddc->use_qr_single; 643774d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 6438984c4197SStefano Zampini total_primal_vertices=0; 6439b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 64409162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 64419162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 644272b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 64439162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 6444b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 644564efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 64469162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 64479162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 6448a717540cSStefano Zampini } 6449b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 645091af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 6451a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 6452a717540cSStefano Zampini qr_needed = PETSC_TRUE; 6453a717540cSStefano Zampini } 6454fa434743SStefano Zampini } else { 6455b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 6456fa434743SStefano Zampini } 6457a717540cSStefano Zampini } 6458b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 6459b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 6460674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 646170022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 64624f1b2e48SStefano 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); 6463*580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices);CHKERRQ(ierr); 64640e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 6465984c4197SStefano Zampini 6466984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 646774d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 6468785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 6469984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 647074d5cdf7SStefano Zampini 6471984c4197SStefano Zampini j = total_primal_vertices; 647274d5cdf7SStefano Zampini total_counts = total_primal_vertices; 6473b3d85658SStefano Zampini cum = total_primal_vertices; 64749162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 64754641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 6476b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 6477b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 6478b3d85658SStefano Zampini cum++; 64799162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 648074d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 648174d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 648274d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 648374d5cdf7SStefano Zampini } 64849162d606SStefano Zampini j += constraints_n[i]; 6485674ae819SStefano Zampini } 6486674ae819SStefano Zampini } 6487674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 6488e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->ConstraintMatrix,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 6489674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 6490088faed8SStefano Zampini 6491674ae819SStefano Zampini /* set values in constraint matrix */ 6492984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 64930e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6494674ae819SStefano Zampini } 6495984c4197SStefano Zampini total_counts = total_primal_vertices; 64969162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 64974641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 64989162d606SStefano Zampini PetscInt *cols; 64999162d606SStefano Zampini 65009162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 65019162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 65029162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 65039162d606SStefano Zampini PetscInt row = total_counts+k; 65049162d606SStefano Zampini PetscScalar *vals; 65059162d606SStefano Zampini 65069162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 65079162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 65089162d606SStefano Zampini } 65099162d606SStefano Zampini total_counts += constraints_n[i]; 6510674ae819SStefano Zampini } 6511674ae819SStefano Zampini } 6512674ae819SStefano Zampini /* assembling */ 6513674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6514674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 65153272d46bSStefano Zampini ierr = MatViewFromOptions(pcbddc->ConstraintMatrix,NULL,"-pc_bddc_constraint_mat_view");CHKERRQ(ierr); 6516088faed8SStefano Zampini 6517674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 6518674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 6519026de310SStefano Zampini /* dual and primal dofs on a single cc */ 6520984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 6521984c4197SStefano Zampini /* working stuff for GEQRF */ 65225a52fde0SStefano Zampini PetscScalar *qr_basis = NULL,*qr_tau = NULL,*qr_work = NULL,lqr_work_t; 6523984c4197SStefano Zampini PetscBLASInt lqr_work; 6524984c4197SStefano Zampini /* working stuff for UNGQR */ 65255a52fde0SStefano Zampini PetscScalar *gqr_work = NULL,lgqr_work_t; 6526984c4197SStefano Zampini PetscBLASInt lgqr_work; 6527984c4197SStefano Zampini /* working stuff for TRTRS */ 65285a52fde0SStefano Zampini PetscScalar *trs_rhs = NULL; 65293f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 6530984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 6531984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 6532984c4197SStefano Zampini PetscScalar *start_vals; 6533984c4197SStefano Zampini /* working stuff for values insertion */ 65344641a718SStefano Zampini PetscBT is_primal; 653564efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 6536906d46d4SStefano Zampini /* matrix sizes */ 6537906d46d4SStefano Zampini PetscInt global_size,local_size; 6538906d46d4SStefano Zampini /* temporary change of basis */ 6539906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 6540cf5a6209SStefano Zampini /* extra space for debugging */ 65415a52fde0SStefano Zampini PetscScalar *dbg_work = NULL; 6542984c4197SStefano Zampini 6543906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 6544906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 654516f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 6546bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 6547906d46d4SStefano Zampini /* nonzeros for local mat */ 6548bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 65491dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6550bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 65511dd7afcfSStefano Zampini } else { 65521dd7afcfSStefano Zampini const PetscInt *ii; 65531dd7afcfSStefano Zampini PetscInt n; 65541dd7afcfSStefano Zampini PetscBool flg_row; 65551dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 65561dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 65571dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 65581dd7afcfSStefano Zampini } 65599162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 6560a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 65619162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 6562a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 65639162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 6564a717540cSStefano Zampini } else { 65659162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 65669162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 6567a717540cSStefano Zampini } 6568a717540cSStefano Zampini } 6569a717540cSStefano Zampini } 6570906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 6571e1b21442SStefano Zampini ierr = MatSetOption(localChangeOfBasisMatrix,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 6572bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 65731dd7afcfSStefano Zampini /* Set interior change in the matrix */ 65741dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6575bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 6576906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 6577a717540cSStefano Zampini } 65781dd7afcfSStefano Zampini } else { 65791dd7afcfSStefano Zampini const PetscInt *ii,*jj; 65801dd7afcfSStefano Zampini PetscScalar *aa; 65811dd7afcfSStefano Zampini PetscInt n; 65821dd7afcfSStefano Zampini PetscBool flg_row; 65831dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 65841dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 65851dd7afcfSStefano Zampini for (i=0;i<n;i++) { 65861dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 65871dd7afcfSStefano Zampini } 65881dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 65891dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 65901dd7afcfSStefano Zampini } 6591a717540cSStefano Zampini 6592a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6593a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6594a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6595a717540cSStefano Zampini } 6596a717540cSStefano Zampini 6597a717540cSStefano Zampini 6598a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 6599a717540cSStefano Zampini /* 6600a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 6601a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 6602a717540cSStefano Zampini 6603a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 6604a717540cSStefano Zampini 6605a6b551f4SStefano 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) 6606a6b551f4SStefano Zampini 6607a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 6608a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 6609a717540cSStefano Zampini | ... | 6610a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 6611a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 6612a717540cSStefano Zampini 6613a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 6614a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 6615a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 6616a6b551f4SStefano Zampini 6617a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 6618a717540cSStefano Zampini */ 66195a52fde0SStefano Zampini if (qr_needed && max_size_of_constraint) { 6620984c4197SStefano Zampini /* space to store Q */ 6621854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 66224e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 66234e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 6624984c4197SStefano Zampini /* first we issue queries for optimal work */ 66253f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 66263f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 66273f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6628984c4197SStefano Zampini lqr_work = -1; 66293f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 6630984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 6631984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 6632785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 6633984c4197SStefano Zampini lgqr_work = -1; 66343f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 66353f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 66363f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 66373f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 66383f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 6639c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 6640c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to ORGQR/UNGQR Lapack routine %d",(int)lierr); 6641984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 6642785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 6643984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 6644785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 6645a717540cSStefano Zampini /* allocating workspace for check */ 6646a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6647cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 6648a717540cSStefano Zampini } 6649a717540cSStefano Zampini } 6650984c4197SStefano Zampini /* array to store whether a node is primal or not */ 66514641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 6652473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 66530e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 66546080607fSStefano Zampini if (i != total_primal_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D",total_primal_vertices,i); 665539e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 665639e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 665739e2fb2aSStefano Zampini } 665839e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 6659984c4197SStefano Zampini 6660a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 66619162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 66629162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 66634641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 6664984c4197SStefano Zampini /* get constraint info */ 66659162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 6666984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 6667984c4197SStefano Zampini 6668984c4197SStefano Zampini if (pcbddc->dbg_flag) { 66696080607fSStefano 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); 6670674ae819SStefano Zampini } 6671984c4197SStefano Zampini 6672fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 6673a717540cSStefano Zampini 6674a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 6675a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6676*580bdb30SBarry Smith ierr = PetscArraycpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs);CHKERRQ(ierr); 6677a717540cSStefano Zampini } 6678984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 6679*580bdb30SBarry Smith ierr = PetscArraycpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs);CHKERRQ(ierr); 6680984c4197SStefano Zampini 6681984c4197SStefano Zampini /* compute QR decomposition of constraints */ 66823f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 66833f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 66843f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6685674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 66863f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 6687984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 6688674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6689984c4197SStefano Zampini 6690984c4197SStefano Zampini /* explictly compute R^-T */ 6691*580bdb30SBarry Smith ierr = PetscArrayzero(trs_rhs,primal_dofs*primal_dofs);CHKERRQ(ierr); 6692984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 66933f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 66943f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 66953f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 66963f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 6697984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 66983f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 6699984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 6700984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6701984c4197SStefano Zampini 6702a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 67033f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 67043f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 67053f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 67063f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6707984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6708c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 6709c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in ORGQR/UNGQR Lapack routine %d",(int)lierr); 6710984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6711984c4197SStefano Zampini 6712984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 6713984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 6714984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 67153f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 67163f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 67173f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 67183f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 67193f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 67203f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6721984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 67229162d606SStefano 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)); 6723984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6724*580bdb30SBarry Smith ierr = PetscArraycpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs);CHKERRQ(ierr); 6725984c4197SStefano Zampini 6726984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 67279162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 6728984c4197SStefano Zampini /* insert cols for primal dofs */ 6729984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 6730984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 67319162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6732906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6733984c4197SStefano Zampini } 6734984c4197SStefano Zampini /* insert cols for dual dofs */ 6735984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 67369162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 6737984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 67389162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6739906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6740984c4197SStefano Zampini j++; 6741674ae819SStefano Zampini } 6742674ae819SStefano Zampini } 6743984c4197SStefano Zampini 6744984c4197SStefano Zampini /* check change of basis */ 6745984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6746984c4197SStefano Zampini PetscInt ii,jj; 6747984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 6748c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 6749c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6750c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 6751c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6752c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 6753c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 6754984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6755cf5a6209SStefano 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)); 6756984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6757984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6758984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6759cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 6760c068d9bbSLisandro Dalcin if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-(PetscReal)1) > 1.e-12) valid_qr = PETSC_FALSE; 6761674ae819SStefano Zampini } 6762674ae819SStefano Zampini } 6763984c4197SStefano Zampini if (!valid_qr) { 676422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 6765984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6766984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6767cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 67686080607fSStefano Zampini ierr = 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]));CHKERRQ(ierr); 6769674ae819SStefano Zampini } 6770c068d9bbSLisandro Dalcin if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-(PetscReal)1) > 1.e-12) { 67716080607fSStefano Zampini ierr = 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]));CHKERRQ(ierr); 6772984c4197SStefano Zampini } 6773984c4197SStefano Zampini } 6774984c4197SStefano Zampini } 6775674ae819SStefano Zampini } else { 677622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 6777674ae819SStefano Zampini } 6778674ae819SStefano Zampini } 6779a717540cSStefano Zampini } else { /* simple transformation block */ 6780a717540cSStefano Zampini PetscInt row,col; 6781a6b551f4SStefano Zampini PetscScalar val,norm; 6782a6b551f4SStefano Zampini 6783a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 67849162d606SStefano 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)); 6785a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 67869162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 67879162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6788bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 67899162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 6790906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 67919162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 6792a717540cSStefano Zampini } else { 6793a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 67949162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6795a717540cSStefano Zampini if (row != col) { 67969162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 6797a717540cSStefano Zampini } else { 67989162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 6799a717540cSStefano Zampini } 6800906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 6801a717540cSStefano Zampini } 6802a717540cSStefano Zampini } 6803a717540cSStefano Zampini } 680498a51de6SStefano Zampini if (pcbddc->dbg_flag) { 680522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 6806a717540cSStefano Zampini } 6807674ae819SStefano Zampini } 6808984c4197SStefano Zampini } else { 6809984c4197SStefano Zampini if (pcbddc->dbg_flag) { 68106080607fSStefano 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); 6811674ae819SStefano Zampini } 6812674ae819SStefano Zampini } 6813674ae819SStefano Zampini } 6814a717540cSStefano Zampini 6815a717540cSStefano Zampini /* free workspace */ 6816a717540cSStefano Zampini if (qr_needed) { 6817984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6818cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 6819984c4197SStefano Zampini } 6820984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 6821984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 6822984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 6823984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 6824984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 6825674ae819SStefano Zampini } 6826a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 6827906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6828906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6829906d46d4SStefano Zampini 6830906d46d4SStefano Zampini /* assembling of global change of variable */ 683188c03ad3SStefano Zampini if (!pcbddc->fake_change) { 6832bbb9e6c6SStefano Zampini Mat tmat; 683316f15bc4SStefano Zampini PetscInt bs; 683416f15bc4SStefano Zampini 6835906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 6836906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 6837bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6838bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 6839487b449aSStefano Zampini ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6840487b449aSStefano Zampini ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6841bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6842bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 684316f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 684416f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 6845906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 6846bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 6847487b449aSStefano Zampini ierr = MatConvert(tmat,MATAIJ,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6848bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6849bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6850bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6851e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6852e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6853bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 6854bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 685588c03ad3SStefano Zampini 6856906d46d4SStefano Zampini /* check */ 6857906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 6858906d46d4SStefano Zampini PetscReal error; 6859906d46d4SStefano Zampini Vec x,x_change; 6860906d46d4SStefano Zampini 6861906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 6862906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 6863906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 6864906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 6865e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6866e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6867bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 6868e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6869e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6870906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 6871906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 6872906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 6873637e8532SStefano Zampini if (error > PETSC_SMALL) { 68746080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e",error); 6875637e8532SStefano Zampini } 6876906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 6877906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 6878906d46d4SStefano Zampini } 6879b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 6880b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6881b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6882bf3a8328SStefano Zampini 688313903a91SSatish Balay if (pcbddc->use_change_of_basis && pcbddc->adaptive_userdefined) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot mix automatic change of basis, adaptive selection and user-defined constraints"); 6884b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6885ac632422SStefano Zampini Mat S_new,tmat; 6886bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6887bbb9e6c6SStefano Zampini 6888bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 68897dae84e0SHong Zhang ierr = MatCreateSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 6890bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6891bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 6892bf3a8328SStefano Zampini IS is_V; 6893b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 6894b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 6895b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 6896b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 6897b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 6898bf3a8328SStefano Zampini } 6899bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 6900ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6901b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 6902ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6903bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6904bf3a8328SStefano Zampini const PetscScalar *array; 6905bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6906bf3a8328SStefano Zampini PetscInt i,n_V; 6907bf3a8328SStefano Zampini 6908b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6909b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6910b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6911b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6912b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6913b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6914b087196eSStefano Zampini PetscScalar val; 6915b087196eSStefano Zampini PetscInt idx; 6916b087196eSStefano Zampini 6917b087196eSStefano Zampini idx = idxs_V[i]; 6918b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6919b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6920b087196eSStefano Zampini } 6921b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6922b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6923bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 6924bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6925bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6926bf3a8328SStefano Zampini } 6927ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 6928ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6929ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 6930ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6931b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 6932ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6933bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6934b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6935bf3a8328SStefano Zampini } 6936ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 6937ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6938ac632422SStefano Zampini } 6939b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 694088c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6941b96c3477SStefano Zampini } 6942c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 6943b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 6944c9db6a07SStefano Zampini PetscInt i; 6945c9db6a07SStefano Zampini 6946c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6947c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 6948c9db6a07SStefano Zampini } 6949c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 6950c9db6a07SStefano Zampini } 6951b96c3477SStefano Zampini } 695216909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 695316909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 695416909a7fSStefano Zampini } else { 6955906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 695616909a7fSStefano Zampini } 69571dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 695827b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 695972b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 696072b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 696172b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 696272b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 696372b8c272SStefano Zampini } 69641dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 696527b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 6966b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 6967b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 6968906d46d4SStefano Zampini } else { 69691dd7afcfSStefano Zampini Mat benign_global = NULL; 697027b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 69711dd7afcfSStefano Zampini Mat M; 69721dd7afcfSStefano Zampini 69739e9b7b1fSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 69749e9b7b1fSStefano Zampini ierr = VecCopy(matis->counter,pcis->vec1_N);CHKERRQ(ierr); 69759e9b7b1fSStefano Zampini ierr = VecReciprocal(pcis->vec1_N);CHKERRQ(ierr); 69769e9b7b1fSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&benign_global);CHKERRQ(ierr); 69779e9b7b1fSStefano Zampini if (pcbddc->benign_change) { 69781dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 69791dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 6980906d46d4SStefano Zampini } else { 69819e9b7b1fSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&M);CHKERRQ(ierr); 69829e9b7b1fSStefano Zampini ierr = MatDiagonalSet(M,pcis->vec1_N,INSERT_VALUES);CHKERRQ(ierr); 6983906d46d4SStefano Zampini } 69849e9b7b1fSStefano Zampini ierr = MatISSetLocalMat(benign_global,M);CHKERRQ(ierr); 69859e9b7b1fSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 69869e9b7b1fSStefano Zampini ierr = MatAssemblyBegin(benign_global,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 69879e9b7b1fSStefano Zampini ierr = MatAssemblyEnd(benign_global,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 69881dd7afcfSStefano Zampini } 69891dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 69901dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 69911dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 699227b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 69931dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 69941dd7afcfSStefano Zampini } 69951dd7afcfSStefano Zampini } 699616909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 699716909a7fSStefano Zampini IS is_global; 699816909a7fSStefano Zampini const PetscInt *gidxs; 699916909a7fSStefano Zampini 700016909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 700116909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 700216909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 70037dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 700416909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 700516909a7fSStefano Zampini } 70061dd7afcfSStefano Zampini } 70071dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 70081dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 7009b9b85e73SStefano Zampini } 7010a717540cSStefano Zampini 701172b8c272SStefano Zampini if (!pcbddc->fake_change) { 70124f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 70134f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 70144f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 70154f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 7016019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 7017019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 7018019a44ceSStefano Zampini pcbddc->local_primal_size++; 7019019a44ceSStefano Zampini } 7020019a44ceSStefano Zampini 7021019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 7022727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 7023727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 7024*580bdb30SBarry Smith ierr = PetscArraycmp(pcbddc->local_primal_ref_node,olocal_primal_ref_node,olocal_primal_size_cc,&pcbddc->new_primal_space_local);CHKERRQ(ierr); 7025c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 70260e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 7027*580bdb30SBarry Smith ierr = PetscArraycmp(pcbddc->local_primal_ref_mult,olocal_primal_ref_mult,olocal_primal_size_cc,&pcbddc->new_primal_space_local);CHKERRQ(ierr); 7028727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 7029727cdba6SStefano Zampini } 70300e6343abSStefano Zampini } 7031727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 7032b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 703372b8c272SStefano Zampini } 703472b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 7035727cdba6SStefano Zampini 7036a717540cSStefano Zampini /* flush dbg viewer */ 7037b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 7038b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7039b8ffe317SStefano Zampini } 7040a717540cSStefano Zampini 7041e310c8b4SStefano Zampini /* free workspace */ 7042a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 70434641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 704408122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 70459162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 70469162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 704708122e43SStefano Zampini } else { 70489162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 70499162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 70509162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 705108122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 705208122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 70539162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 70549162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 705508122e43SStefano Zampini } 7056674ae819SStefano Zampini PetscFunctionReturn(0); 7057674ae819SStefano Zampini } 705804a6f24aSStefano Zampini /* #undef PETSC_MISSING_LAPACK_GESVD */ 7059674ae819SStefano Zampini 7060674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 7061674ae819SStefano Zampini { 706271582508SStefano Zampini ISLocalToGlobalMapping map; 7063674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7064674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 706566da6bd7Sstefano_zampini PetscInt i,N; 706666da6bd7Sstefano_zampini PetscBool rcsr = PETSC_FALSE; 706766da6bd7Sstefano_zampini PetscErrorCode ierr; 7068674ae819SStefano Zampini 7069674ae819SStefano Zampini PetscFunctionBegin; 70708af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 7071b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 70728e61c736SStefano Zampini /* Reset previously computed graph */ 70738e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 7074674ae819SStefano Zampini /* Init local Graph struct */ 70757fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 707671582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 7077be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 7078674ae819SStefano Zampini 70797a0e7b2cSstefano_zampini if (pcbddc->user_primal_vertices_local && !pcbddc->user_primal_vertices) { 70807a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 70817a0e7b2cSstefano_zampini } 7082575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 70836080607fSStefano 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",pcbddc->mat_graph->nvtxs_csr,pcbddc->mat_graph->nvtxs); 70849577ea80SStefano Zampini 7085674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 708666da6bd7Sstefano_zampini if (!pcbddc->mat_graph->xadj && pcbddc->use_local_adj) { 70874d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 70884d379d7bSStefano Zampini PetscInt nvtxs; 7089e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 7090674ae819SStefano Zampini 70912fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 70922fffb893SStefano Zampini if (flg_row) { 70934d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 7094b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 70952fffb893SStefano Zampini } 70962fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 709766da6bd7Sstefano_zampini rcsr = PETSC_TRUE; 7098674ae819SStefano Zampini } 70999b28b941SStefano Zampini if (pcbddc->dbg_flag) { 71009b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7101674ae819SStefano Zampini } 7102674ae819SStefano Zampini 7103ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cdim && !pcbddc->mat_graph->cloc) { 7104ab8c8b98SStefano Zampini PetscReal *lcoords; 7105ab8c8b98SStefano Zampini PetscInt n; 7106ab8c8b98SStefano Zampini MPI_Datatype dimrealtype; 7107ab8c8b98SStefano Zampini 71084f819b78SStefano Zampini /* TODO: support for blocked */ 7109ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cnloc != pc->pmat->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid number of local coordinates! Got %D, expected %D",pcbddc->mat_graph->cnloc,pc->pmat->rmap->n); 7110ab8c8b98SStefano Zampini ierr = MatGetLocalSize(matis->A,&n,NULL);CHKERRQ(ierr); 7111ab8c8b98SStefano Zampini ierr = PetscMalloc1(pcbddc->mat_graph->cdim*n,&lcoords);CHKERRQ(ierr); 7112ab8c8b98SStefano Zampini ierr = MPI_Type_contiguous(pcbddc->mat_graph->cdim,MPIU_REAL,&dimrealtype);CHKERRQ(ierr); 7113ab8c8b98SStefano Zampini ierr = MPI_Type_commit(&dimrealtype);CHKERRQ(ierr); 7114ab8c8b98SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 7115ab8c8b98SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 7116ab8c8b98SStefano Zampini ierr = MPI_Type_free(&dimrealtype);CHKERRQ(ierr); 7117ab8c8b98SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->coords);CHKERRQ(ierr); 7118ab8c8b98SStefano Zampini 7119ab8c8b98SStefano Zampini pcbddc->mat_graph->coords = lcoords; 7120ab8c8b98SStefano Zampini pcbddc->mat_graph->cloc = PETSC_TRUE; 7121ab8c8b98SStefano Zampini pcbddc->mat_graph->cnloc = n; 7122ab8c8b98SStefano Zampini } 7123ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cnloc && pcbddc->mat_graph->cnloc != pcbddc->mat_graph->nvtxs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid number of local subdomain coordinates! Got %D, expected %D",pcbddc->mat_graph->cnloc,pcbddc->mat_graph->nvtxs); 71241c7a958bSStefano Zampini pcbddc->mat_graph->active_coords = (PetscBool)(pcbddc->corner_selection && !pcbddc->corner_selected); 7125ab8c8b98SStefano Zampini 7126674ae819SStefano Zampini /* Setup of Graph */ 71274b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 712814f95afaSStefano 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); 7129674ae819SStefano Zampini 71304f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 71314f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 713220c3699dSStefano Zampini PetscInt *local_subs,n,totn; 71334f1b2e48SStefano Zampini 713420c3699dSStefano Zampini ierr = MatGetLocalSize(matis->A,&n,NULL);CHKERRQ(ierr); 713520c3699dSStefano Zampini ierr = PetscMalloc1(n,&local_subs);CHKERRQ(ierr); 713620c3699dSStefano Zampini for (i=0;i<n;i++) local_subs[i] = pcbddc->n_local_subs; 71374f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 71384f1b2e48SStefano Zampini const PetscInt *idxs; 71394f1b2e48SStefano Zampini PetscInt nl,j; 71404f1b2e48SStefano Zampini 71414f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 71424f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 714371582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 71444f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 71454f1b2e48SStefano Zampini } 714620c3699dSStefano Zampini for (i=0,totn=0;i<n;i++) totn = PetscMax(totn,local_subs[i]); 714720c3699dSStefano Zampini pcbddc->mat_graph->n_local_subs = totn + 1; 71484f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 71494f1b2e48SStefano Zampini } 71508af8fcf9SStefano Zampini } 71514f1b2e48SStefano Zampini 7152cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 7153674ae819SStefano Zampini /* Graph's connected components analysis */ 7154674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 715571582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 71564f819b78SStefano Zampini pcbddc->corner_selected = pcbddc->corner_selection; 71578af8fcf9SStefano Zampini } 715866da6bd7Sstefano_zampini if (rcsr) pcbddc->mat_graph->nvtxs_csr = 0; 7159674ae819SStefano Zampini PetscFunctionReturn(0); 7160674ae819SStefano Zampini } 7161674ae819SStefano Zampini 71629a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 71639a7d3425SStefano Zampini { 71649a7d3425SStefano Zampini PetscInt i,j; 71659a7d3425SStefano Zampini PetscScalar *alphas; 716692cccca0SStefano Zampini PetscReal norm; 71679a7d3425SStefano Zampini PetscErrorCode ierr; 71689a7d3425SStefano Zampini 71699a7d3425SStefano Zampini PetscFunctionBegin; 71708c0031efSStefano Zampini if (!n) PetscFunctionReturn(0); 7171785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 717292cccca0SStefano Zampini ierr = VecNormalize(vecs[0],&norm);CHKERRQ(ierr); 717392cccca0SStefano Zampini if (norm < PETSC_SMALL) { 717492cccca0SStefano Zampini ierr = VecSet(vecs[0],0.0);CHKERRQ(ierr); 717592cccca0SStefano Zampini } 71768c0031efSStefano Zampini for (i=1;i<n;i++) { 71778c0031efSStefano Zampini ierr = VecMDot(vecs[i],i,vecs,alphas);CHKERRQ(ierr); 71788c0031efSStefano Zampini for (j=0;j<i;j++) alphas[j] = PetscConj(-alphas[j]); 71798c0031efSStefano Zampini ierr = VecMAXPY(vecs[i],i,alphas,vecs);CHKERRQ(ierr); 718092cccca0SStefano Zampini ierr = VecNormalize(vecs[i],&norm);CHKERRQ(ierr); 718192cccca0SStefano Zampini if (norm < PETSC_SMALL) { 718292cccca0SStefano Zampini ierr = VecSet(vecs[i],0.0);CHKERRQ(ierr); 718392cccca0SStefano Zampini } 71849a7d3425SStefano Zampini } 71859a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 71869a7d3425SStefano Zampini PetscFunctionReturn(0); 71879a7d3425SStefano Zampini } 71889a7d3425SStefano Zampini 7189bb360cb4SStefano Zampini PetscErrorCode PCBDDCMatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 7190e7931f94SStefano Zampini { 719157de7509SStefano Zampini Mat A; 7192e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 7193e7931f94SStefano Zampini PetscMPIInt size,rank,color; 719452e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 719552e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 7196bb360cb4SStefano Zampini PetscInt im_active,active_procs,N,n,i,j,threshold = 2; 719757de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 719827b6a85dSStefano Zampini PetscInt xadj_count,*count; 719927b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 720027b6a85dSStefano Zampini PetscSubcomm psubcomm; 720127b6a85dSStefano Zampini MPI_Comm subcomm; 720252e5ac9dSStefano Zampini PetscErrorCode ierr; 7203a57a6d2fSStefano Zampini 7204e7931f94SStefano Zampini PetscFunctionBegin; 720557de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 720657de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7207fbfcfee5SBarry Smith if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",PETSC_FUNCTION_NAME); 720857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 720957de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 72106080607fSStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %D",*n_subdomains); 721157de7509SStefano Zampini 721257de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 721357de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 721457de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 721557de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 721657de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 7217bb360cb4SStefano Zampini im_active = !!n; 721857de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 721957de7509SStefano Zampini void_procs = size - active_procs; 722057de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 722157de7509SStefano Zampini if (void_procs) { 722257de7509SStefano Zampini PetscInt ncand; 722357de7509SStefano Zampini 722457de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 722557de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 722657de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 722757de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 722857de7509SStefano Zampini if (!procs_candidates[i]) { 722957de7509SStefano Zampini procs_candidates[ncand++] = i; 723057de7509SStefano Zampini } 723157de7509SStefano Zampini } 723257de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 723357de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 723457de7509SStefano Zampini } 723557de7509SStefano Zampini 7236bb360cb4SStefano Zampini /* number of subdomains requested greater than active processes or matrix size -> just shift the matrix 723714f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 7238bb360cb4SStefano Zampini ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 7239bb360cb4SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1 || N <= *n_subdomains) { 724014f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 724114f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 724214f0bfb9SStefano Zampini else dest = rank; 724357de7509SStefano Zampini if (im_active) { 724457de7509SStefano Zampini issize = 1; 724557de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 724614f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 724757de7509SStefano Zampini } else { 724814f0bfb9SStefano Zampini isidx = dest; 724957de7509SStefano Zampini } 725057de7509SStefano Zampini } else { 725157de7509SStefano Zampini issize = 0; 725257de7509SStefano Zampini isidx = -1; 725357de7509SStefano Zampini } 7254bb360cb4SStefano Zampini if (*n_subdomains != 1) *n_subdomains = active_procs; 725557de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 7256daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 725757de7509SStefano Zampini PetscFunctionReturn(0); 725857de7509SStefano Zampini } 7259c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 7260c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 726127b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 7262e7931f94SStefano Zampini 7263e7931f94SStefano Zampini /* Get info on mapping */ 72643bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 7265e7931f94SStefano Zampini 7266e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 7267785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 7268e7931f94SStefano Zampini xadj[0] = 0; 7269e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 7270785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 7271785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 7272bb360cb4SStefano Zampini ierr = PetscCalloc1(n,&count);CHKERRQ(ierr); 727327b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 727427b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 727527b6a85dSStefano Zampini count[shared[i][j]] += 1; 7276e7931f94SStefano Zampini 727727b6a85dSStefano Zampini xadj_count = 0; 72782b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 727927b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 728027b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 7281d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 7282d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 7283d023bfaeSStefano Zampini xadj_count++; 728427b6a85dSStefano Zampini break; 728527b6a85dSStefano Zampini } 7286e7931f94SStefano Zampini } 7287e7931f94SStefano Zampini } 7288d023bfaeSStefano Zampini xadj[1] = xadj_count; 728927b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 72903bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 7291e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 7292e7931f94SStefano Zampini 72933837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 7294e7931f94SStefano Zampini 729527b6a85dSStefano Zampini /* Restrict work on active processes only */ 729627b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 729727b6a85dSStefano Zampini if (void_procs) { 729827b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 729927b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 730027b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 730127b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 730227b6a85dSStefano Zampini } else { 730327b6a85dSStefano Zampini psubcomm = NULL; 730427b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 730527b6a85dSStefano Zampini } 730627b6a85dSStefano Zampini 730727b6a85dSStefano Zampini v_wgt = NULL; 730827b6a85dSStefano Zampini if (!color) { 7309e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 7310e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 7311e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7312c8587f34SStefano Zampini } else { 731352e5ac9dSStefano Zampini Mat subdomain_adj; 731452e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 731552e5ac9dSStefano Zampini MatPartitioning partitioner; 731627b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 731752e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 731857de7509SStefano Zampini PetscMPIInt size; 7319b0c7d250SStefano Zampini PetscBool aggregate; 7320b0c7d250SStefano Zampini 732127b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 732227b6a85dSStefano Zampini if (void_procs) { 732327b6a85dSStefano Zampini PetscInt prank = rank; 7324785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 732527b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 7326e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 7327e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 7328c8587f34SStefano Zampini } 7329e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 733027b6a85dSStefano Zampini } else { 733127b6a85dSStefano Zampini oldranks = NULL; 733227b6a85dSStefano Zampini } 7333b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 733427b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 7335b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 7336b0c7d250SStefano Zampini PetscMPIInt nrank; 7337b0c7d250SStefano Zampini PetscScalar *vals; 7338b0c7d250SStefano Zampini 733927b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 7340b0c7d250SStefano Zampini lrows = 0; 7341b0c7d250SStefano Zampini if (nrank<redprocs) { 7342b0c7d250SStefano Zampini lrows = size/redprocs; 7343b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 7344b0c7d250SStefano Zampini } 734527b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 7346b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 7347b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7348b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7349b0c7d250SStefano Zampini row = nrank; 7350b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 7351b0c7d250SStefano Zampini cols = adjncy; 7352b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 7353b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 7354b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 7355b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7356b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 735752e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 735852e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 735952e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7360b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 736127b6a85dSStefano Zampini if (use_vwgt) { 736227b6a85dSStefano Zampini Vec v; 736327b6a85dSStefano Zampini const PetscScalar *array; 736427b6a85dSStefano Zampini PetscInt nl; 736527b6a85dSStefano Zampini 736627b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 7367bb360cb4SStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)n,INSERT_VALUES);CHKERRQ(ierr); 736827b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 736927b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 737027b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 737127b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 737227b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 737322db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 737427b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 737527b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 737627b6a85dSStefano Zampini } 7377b0c7d250SStefano Zampini } else { 737827b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 737927b6a85dSStefano Zampini if (use_vwgt) { 738027b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 7381bb360cb4SStefano Zampini v_wgt[0] = n; 738227b6a85dSStefano Zampini } 7383b0c7d250SStefano Zampini } 738422b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 7385e7931f94SStefano Zampini 7386e7931f94SStefano Zampini /* Partition */ 738727b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 7388ce64c636SStefano Zampini #if defined(PETSC_HAVE_PTSCOTCH) 7389ce64c636SStefano Zampini ierr = MatPartitioningSetType(partitioner,MATPARTITIONINGPTSCOTCH);CHKERRQ(ierr); 7390ce64c636SStefano Zampini #elif defined(PETSC_HAVE_PARMETIS) 7391ce64c636SStefano Zampini ierr = MatPartitioningSetType(partitioner,MATPARTITIONINGPARMETIS);CHKERRQ(ierr); 7392ce64c636SStefano Zampini #else 7393ce64c636SStefano Zampini ierr = MatPartitioningSetType(partitioner,MATPARTITIONINGAVERAGE);CHKERRQ(ierr); 7394ce64c636SStefano Zampini #endif 7395e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 739627b6a85dSStefano Zampini if (v_wgt) { 7397e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 7398c8587f34SStefano Zampini } 739957de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 740057de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 7401e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 7402e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 740322b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 7404e7931f94SStefano Zampini 740552e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 74066583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 740752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 740852e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 740957de7509SStefano Zampini if (!aggregate) { 741057de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 741127b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 741227b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 741327b6a85dSStefano Zampini #endif 741457de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 741527b6a85dSStefano Zampini } else if (oldranks) { 7416b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 741727b6a85dSStefano Zampini } else { 741827b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 741957de7509SStefano Zampini } 742028143c3dSStefano Zampini } else { 74217fb8a5e4SKarl Rupp PetscInt idx = 0; 7422b0c7d250SStefano Zampini PetscMPIInt tag; 7423b0c7d250SStefano Zampini MPI_Request *reqs; 7424b0c7d250SStefano Zampini 7425b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 7426b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 7427b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 742827b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 742928143c3dSStefano Zampini } 74307fb8a5e4SKarl Rupp ierr = MPI_Recv(&idx,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 7431b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7432b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 743357de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 743427b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 743527b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 743627b6a85dSStefano Zampini #endif 74377fb8a5e4SKarl Rupp ranks_send_to_idx[0] = procs_candidates[oldranks[idx]]; 743827b6a85dSStefano Zampini } else if (oldranks) { 74397fb8a5e4SKarl Rupp ranks_send_to_idx[0] = oldranks[idx]; 744027b6a85dSStefano Zampini } else { 74417fb8a5e4SKarl Rupp ranks_send_to_idx[0] = idx; 7442e7931f94SStefano Zampini } 744357de7509SStefano Zampini } 744452e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 7445e7931f94SStefano Zampini /* clean up */ 7446e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 744752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 7448e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 7449e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 7450e7931f94SStefano Zampini } 745127b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 745257de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 7453e7931f94SStefano Zampini 7454e7931f94SStefano Zampini /* assemble parallel IS for sends */ 7455e7931f94SStefano Zampini i = 1; 745627b6a85dSStefano Zampini if (!color) i=0; 745757de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 7458e7931f94SStefano Zampini PetscFunctionReturn(0); 7459e7931f94SStefano Zampini } 7460e7931f94SStefano Zampini 7461e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 7462e7931f94SStefano Zampini 74631e0482f5SStefano 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[]) 7464e7931f94SStefano Zampini { 746570cf5478SStefano Zampini Mat local_mat; 7466e7931f94SStefano Zampini IS is_sends_internal; 74679d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 74681ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 74699d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 7470e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 7471e7931f94SStefano Zampini PetscInt* l2gmap_indices; 7472e7931f94SStefano Zampini const PetscInt* is_indices; 7473e7931f94SStefano Zampini MatType new_local_type; 7474e7931f94SStefano Zampini /* buffers */ 7475e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 747628143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 74779d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 74781683a169SBarry Smith PetscScalar *ptr_vals,*recv_buffer_vals; 74791683a169SBarry Smith const PetscScalar *send_buffer_vals; 74801ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 7481e7931f94SStefano Zampini /* MPI */ 748228143c3dSStefano Zampini MPI_Comm comm,comm_n; 748328143c3dSStefano Zampini PetscSubcomm subcomm; 7484e569e4e1SStefano Zampini PetscMPIInt n_sends,n_recvs,size; 748528143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 748628143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 74871ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 74881ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 74891ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 7490e7931f94SStefano Zampini PetscErrorCode ierr; 7491e7931f94SStefano Zampini 7492e7931f94SStefano Zampini PetscFunctionBegin; 749357de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7494e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7495fbfcfee5SBarry Smith if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",PETSC_FUNCTION_NAME); 749657de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 749757de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 749857de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 749957de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 750057de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 75011ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 75021ae86dd6SStefano Zampini if (nvecs) { 75031ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 75041ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 75051ae86dd6SStefano Zampini } 750657de7509SStefano Zampini /* further checks */ 7507e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7508e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 7509e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 7510e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 7511e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 751257de7509SStefano Zampini if (reuse && *mat_n) { 751370cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 751457de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 751570cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 751628143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 751770cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 751870cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 751970cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 752070cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 752170cf5478SStefano Zampini } 7522e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 7523e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 752457de7509SStefano Zampini 7525e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 7526e7931f94SStefano Zampini if (!is_sends) { 752728143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 7528bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 7529c8587f34SStefano Zampini } else { 7530e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 7531e7931f94SStefano Zampini is_sends_internal = is_sends; 7532c8587f34SStefano Zampini } 7533e7931f94SStefano Zampini 7534e7931f94SStefano Zampini /* get comm */ 7535a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 7536e7931f94SStefano Zampini 7537e7931f94SStefano Zampini /* compute number of sends */ 7538e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 7539e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 7540e7931f94SStefano Zampini 7541e7931f94SStefano Zampini /* compute number of receives */ 7542e569e4e1SStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 7543e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&iflags);CHKERRQ(ierr); 7544*580bdb30SBarry Smith ierr = PetscArrayzero(iflags,size);CHKERRQ(ierr); 7545e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7546e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 7547e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 7548e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 7549e7931f94SStefano Zampini 755028143c3dSStefano Zampini /* restrict comm if requested */ 755128143c3dSStefano Zampini subcomm = 0; 755228143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 755328143c3dSStefano Zampini if (restrict_comm) { 7554779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 7555779c1cceSStefano Zampini 755628143c3dSStefano Zampini color = 0; 755753a05cb3SStefano Zampini if (restrict_full) { 755853a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 755953a05cb3SStefano Zampini } else { 756053a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 756153a05cb3SStefano Zampini } 7562b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 7563e569e4e1SStefano Zampini subcommsize = size - subcommsize; 756428143c3dSStefano Zampini /* check if reuse has been requested */ 756557de7509SStefano Zampini if (reuse) { 756628143c3dSStefano Zampini if (*mat_n) { 756728143c3dSStefano Zampini PetscMPIInt subcommsize2; 756828143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 756928143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 757028143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 757128143c3dSStefano Zampini } else { 757228143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 757328143c3dSStefano Zampini } 757428143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 7575779c1cceSStefano Zampini PetscMPIInt rank; 7576779c1cceSStefano Zampini 7577779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 757828143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 757928143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 758028143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 7581306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 758228143c3dSStefano Zampini } 758328143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 758428143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 758528143c3dSStefano Zampini } else { 758628143c3dSStefano Zampini comm_n = comm; 758728143c3dSStefano Zampini } 758828143c3dSStefano Zampini 7589e7931f94SStefano Zampini /* prepare send/receive buffers */ 7590e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&ilengths_idxs);CHKERRQ(ierr); 7591*580bdb30SBarry Smith ierr = PetscArrayzero(ilengths_idxs,size);CHKERRQ(ierr); 7592e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&ilengths_vals);CHKERRQ(ierr); 7593*580bdb30SBarry Smith ierr = PetscArrayzero(ilengths_vals,size);CHKERRQ(ierr); 759428143c3dSStefano Zampini if (nis) { 7595e569e4e1SStefano Zampini ierr = PetscCalloc1(size,&ilengths_idxs_is);CHKERRQ(ierr); 759628143c3dSStefano Zampini } 7597e7931f94SStefano Zampini 759828143c3dSStefano Zampini /* Get data from local matrices */ 75996c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 7600e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 7601e7931f94SStefano Zampini /* 7602e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 7603e7931f94SStefano Zampini send_buffer_idxs should contain: 7604e7931f94SStefano Zampini - MatType_PRIVATE type 7605e7931f94SStefano Zampini - PetscInt size_of_l2gmap 7606e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 7607e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 7608e7931f94SStefano Zampini */ 76096c4ed002SBarry Smith else { 76101683a169SBarry Smith ierr = MatDenseGetArrayRead(local_mat,&send_buffer_vals);CHKERRQ(ierr); 76113bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 7612854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 7613e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 7614e7931f94SStefano Zampini send_buffer_idxs[1] = i; 76153bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7616*580bdb30SBarry Smith ierr = PetscArraycpy(&send_buffer_idxs[2],ptr_idxs,i);CHKERRQ(ierr); 76173bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7618e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 7619e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7620e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 7621e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 7622c8587f34SStefano Zampini } 7623c8587f34SStefano Zampini } 7624e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 762528143c3dSStefano Zampini /* additional is (if any) */ 762628143c3dSStefano Zampini if (nis) { 762728143c3dSStefano Zampini PetscMPIInt psum; 762828143c3dSStefano Zampini PetscInt j; 762928143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 763028143c3dSStefano Zampini PetscInt plen; 763128143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 763228143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 763328143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 763428143c3dSStefano Zampini } 7635854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 763628143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 763728143c3dSStefano Zampini PetscInt plen; 763828143c3dSStefano Zampini const PetscInt *is_array_idxs; 763928143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 764028143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 764128143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 7642*580bdb30SBarry Smith ierr = PetscArraycpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen);CHKERRQ(ierr); 764328143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 764428143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 764528143c3dSStefano Zampini } 764628143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 764728143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 764828143c3dSStefano Zampini } 764928143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 765028143c3dSStefano Zampini } 76513b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 765228143c3dSStefano Zampini 7653e7931f94SStefano Zampini buf_size_idxs = 0; 7654e7931f94SStefano Zampini buf_size_vals = 0; 765528143c3dSStefano Zampini buf_size_idxs_is = 0; 76561ae86dd6SStefano Zampini buf_size_vecs = 0; 7657e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7658e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 7659e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 766028143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 76611ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 7662e7931f94SStefano Zampini } 7663785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 7664785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 766595ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 76661ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 7667e7931f94SStefano Zampini 7668e7931f94SStefano Zampini /* get new tags for clean communications */ 7669e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 7670e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 767128143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 76721ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 7673e7931f94SStefano Zampini 7674e7931f94SStefano Zampini /* allocate for requests */ 7675785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 7676785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 767795ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 76781ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 7679785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 7680785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 768195ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 76821ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 7683e7931f94SStefano Zampini 7684e7931f94SStefano Zampini /* communications */ 7685e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7686e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 768728143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 76881ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 7689e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7690e7931f94SStefano Zampini source_dest = onodes[i]; 7691e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 7692e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 7693e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7694e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 769528143c3dSStefano Zampini if (nis) { 769657de7509SStefano Zampini source_dest = onodes_is[i]; 769728143c3dSStefano 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); 769828143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 769928143c3dSStefano Zampini } 77001ae86dd6SStefano Zampini if (nvecs) { 77011ae86dd6SStefano Zampini source_dest = onodes[i]; 77021ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 77031ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 77041ae86dd6SStefano Zampini } 7705e7931f94SStefano Zampini } 7706e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7707e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 7708e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 7709e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 771028143c3dSStefano Zampini if (nis) { 771128143c3dSStefano 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); 771228143c3dSStefano Zampini } 77131ae86dd6SStefano Zampini if (nvecs) { 77141ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 77151ae86dd6SStefano 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); 77161ae86dd6SStefano Zampini } 7717e7931f94SStefano Zampini } 7718e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7719e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 7720e7931f94SStefano Zampini 7721e7931f94SStefano Zampini /* assemble new l2g map */ 7722e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7723e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 77249d30be91SStefano Zampini new_local_rows = 0; 7725e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 77269d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7727e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7728e7931f94SStefano Zampini } 77299d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 7730e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 77319d30be91SStefano Zampini new_local_rows = 0; 7732e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7733*580bdb30SBarry Smith ierr = PetscArraycpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,*(ptr_idxs+1));CHKERRQ(ierr); 77349d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7735e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7736e7931f94SStefano Zampini } 77379d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 77389d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 7739e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 7740e7931f94SStefano Zampini 7741e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 7742e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 7743e7931f94SStefano 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) */ 7744e7931f94SStefano Zampini if (n_recvs) { 774528143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 7746e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7747e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7748e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 7749e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 7750e7931f94SStefano Zampini break; 7751e7931f94SStefano Zampini } 7752e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7753e7931f94SStefano Zampini } 7754e7931f94SStefano Zampini switch (new_local_type_private) { 775528143c3dSStefano Zampini case MATDENSE_PRIVATE: 7756e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7757e7931f94SStefano Zampini bs = 1; 7758e7931f94SStefano Zampini break; 7759e7931f94SStefano Zampini case MATAIJ_PRIVATE: 7760e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7761e7931f94SStefano Zampini bs = 1; 7762e7931f94SStefano Zampini break; 7763e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 7764e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 7765e7931f94SStefano Zampini break; 7766e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 7767e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 7768e7931f94SStefano Zampini break; 7769e7931f94SStefano Zampini default: 7770fbfcfee5SBarry Smith SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,PETSC_FUNCTION_NAME); 7771e7931f94SStefano Zampini break; 7772e7931f94SStefano Zampini } 7773ed8ed4edSstefano_zampini } else { /* by default, new_local_type is seqaij */ 7774ed8ed4edSstefano_zampini new_local_type = MATSEQAIJ; 777528143c3dSStefano Zampini bs = 1; 7776e7931f94SStefano Zampini } 7777e7931f94SStefano Zampini 777870cf5478SStefano Zampini /* create MATIS object if needed */ 777957de7509SStefano Zampini if (!reuse) { 7780e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 7781e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 778270cf5478SStefano Zampini } else { 778370cf5478SStefano Zampini /* it also destroys the local matrices */ 778457de7509SStefano Zampini if (*mat_n) { 778570cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 778657de7509SStefano Zampini } else { /* this is a fake object */ 778757de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 778857de7509SStefano Zampini } 778970cf5478SStefano Zampini } 779070cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 7791e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 77929d30be91SStefano Zampini 77939d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 77949d30be91SStefano Zampini 77959d30be91SStefano Zampini /* Global to local map of received indices */ 77969d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 77979d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 77989d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 77999d30be91SStefano Zampini 78009d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 78019d30be91SStefano Zampini buf_size_idxs = 0; 78029d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 78039d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 78049d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 78059d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 78069d30be91SStefano Zampini } 78079d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 78089d30be91SStefano Zampini 78099d30be91SStefano Zampini /* set preallocation */ 78109d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 78119d30be91SStefano Zampini if (!newisdense) { 78129d30be91SStefano Zampini PetscInt *new_local_nnz=0; 78139d30be91SStefano Zampini 78149d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 78159d30be91SStefano Zampini if (n_recvs) { 78169d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 78179d30be91SStefano Zampini } 78189d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 78199d30be91SStefano Zampini PetscInt j; 78209d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 78219d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 78229d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 78239d30be91SStefano Zampini } 78249d30be91SStefano Zampini } else { 78259d30be91SStefano Zampini /* TODO */ 78269d30be91SStefano Zampini } 78279d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 78289d30be91SStefano Zampini } 78299d30be91SStefano Zampini if (new_local_nnz) { 78309d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 78319d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 78329d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 78339d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 78349d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 78359d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 78369d30be91SStefano Zampini } else { 78379d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 78389d30be91SStefano Zampini } 78399d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 78409d30be91SStefano Zampini } else { 78419d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 78429d30be91SStefano Zampini } 7843e7931f94SStefano Zampini 7844e7931f94SStefano Zampini /* set values */ 7845e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 78469d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 7847e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7848e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 7849e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 78509d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 7851e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7852e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7853e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 785428143c3dSStefano Zampini } else { 785528143c3dSStefano Zampini /* TODO */ 7856e7931f94SStefano Zampini } 7857e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7858e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 7859e7931f94SStefano Zampini } 7860e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7861e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 78623b3b1effSJed Brown ierr = MatISRestoreLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 786370cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 786470cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 78659d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 7866e7931f94SStefano Zampini 7867dfd14d43SStefano Zampini #if 0 786828143c3dSStefano Zampini if (!restrict_comm) { /* check */ 7869e7931f94SStefano Zampini Vec lvec,rvec; 7870e7931f94SStefano Zampini PetscReal infty_error; 7871e7931f94SStefano Zampini 78722a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 7873e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 7874e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 7875e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 787670cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 7877e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 7878e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 7879e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 7880e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 7881e7931f94SStefano Zampini } 788228143c3dSStefano Zampini #endif 7883e7931f94SStefano Zampini 788428143c3dSStefano Zampini /* assemble new additional is (if any) */ 788528143c3dSStefano Zampini if (nis) { 788628143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 788728143c3dSStefano Zampini 788828143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7889854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 789028143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 789128143c3dSStefano Zampini psum = 0; 789228143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 789328143c3dSStefano Zampini for (j=0;j<nis;j++) { 789428143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 789528143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 789628143c3dSStefano Zampini psum += plen; 789728143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 789828143c3dSStefano Zampini } 789928143c3dSStefano Zampini } 7900854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 7901854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 790228143c3dSStefano Zampini for (i=1;i<nis;i++) { 790328143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 790428143c3dSStefano Zampini } 7905*580bdb30SBarry Smith ierr = PetscArrayzero(count_is,nis);CHKERRQ(ierr); 790628143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 790728143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 790828143c3dSStefano Zampini for (j=0;j<nis;j++) { 790928143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 7910*580bdb30SBarry Smith ierr = PetscArraycpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen);CHKERRQ(ierr); 791128143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 791228143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 791328143c3dSStefano Zampini } 791428143c3dSStefano Zampini } 791528143c3dSStefano Zampini for (i=0;i<nis;i++) { 791628143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 791728143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 791828143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 791928143c3dSStefano Zampini } 792028143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 792128143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 792228143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 792328143c3dSStefano Zampini } 7924e7931f94SStefano Zampini /* free workspace */ 792528143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 7926e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7927e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 7928e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7929e7931f94SStefano Zampini if (isdense) { 7930e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 79311683a169SBarry Smith ierr = MatDenseRestoreArrayRead(local_mat,&send_buffer_vals);CHKERRQ(ierr); 79323b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 7933e7931f94SStefano Zampini } else { 7934e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 7935e7931f94SStefano Zampini } 793628143c3dSStefano Zampini if (nis) { 793728143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 793828143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 793928143c3dSStefano Zampini } 79401ae86dd6SStefano Zampini 79411ae86dd6SStefano Zampini if (nvecs) { 79421ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 79431ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 79441ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 79451ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 79461ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 79471ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 79481ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 79491ae86dd6SStefano Zampini /* set values */ 79501ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 79511ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 79521ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 79531ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 79541ae86dd6SStefano Zampini PetscInt j; 79551ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 79561ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 79571ae86dd6SStefano Zampini } 79581ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 79591ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 79601ae86dd6SStefano Zampini } 79611ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 79621ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 79631ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 79641ae86dd6SStefano Zampini } 79651ae86dd6SStefano Zampini 79661ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 79671ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 7968e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 7969e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 79701ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 797128143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 7972e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 7973e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 79741ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 797528143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 7976e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 7977e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 7978e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 7979e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 7980e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 798128143c3dSStefano Zampini if (nis) { 798228143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 798328143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 798428143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 798528143c3dSStefano Zampini } 798628143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 798728143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 798828143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 798928143c3dSStefano Zampini for (i=0;i<nis;i++) { 799028143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 799128143c3dSStefano Zampini } 79921ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 79931ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 79941ae86dd6SStefano Zampini } 799553a05cb3SStefano Zampini *mat_n = NULL; 799628143c3dSStefano Zampini } 7997e7931f94SStefano Zampini PetscFunctionReturn(0); 7998e7931f94SStefano Zampini } 7999a57a6d2fSStefano Zampini 800012edc857SStefano Zampini /* temporary hack into ksp private data structure */ 8001af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 800212edc857SStefano Zampini 8003c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 8004c8587f34SStefano Zampini { 8005c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 8006c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 800720a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 80081ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 80091e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 80109881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 801120a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 80124f819b78SStefano Zampini IS coarse_is,*isarray,corners; 80136e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 801430368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 8015e569e4e1SStefano Zampini PetscInt coarse_eqs_per_proc; 8016f9eb5b7dSStefano Zampini PC pc_temp; 8017c8587f34SStefano Zampini PCType coarse_pc_type; 8018c8587f34SStefano Zampini KSPType coarse_ksp_type; 8019f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 80207274672aSStefano Zampini PetscBool coarse_reuse; 80211e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 802268457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 802322bc73bbSStefano Zampini PetscScalar *array; 802457de7509SStefano Zampini MatReuse coarse_mat_reuse; 802557de7509SStefano Zampini PetscBool restr, full_restr, have_void; 8026e569e4e1SStefano Zampini PetscMPIInt size; 80279881197aSStefano Zampini PetscErrorCode ierr; 8028fdc09c96SStefano Zampini 8029c8587f34SStefano Zampini PetscFunctionBegin; 803043371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CoarseSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8031c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 803268457ee5SStefano 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 */ 8033fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 80345a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 80357de4f681Sstefano_zampini 80367de4f681Sstefano_zampini pcbddc->new_primal_space = PETSC_TRUE; 8037fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 8038f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 8039f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 8040f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 8041fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 804251bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 804351bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 8044727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 8045fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 8046fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 8047fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 8048f4ddd8eeSStefano Zampini } 8049fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 8050fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 8051f4ddd8eeSStefano Zampini } 805270cf5478SStefano Zampini /* reset any subassembling information */ 805357de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 805470cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 805557de7509SStefano Zampini } 80566e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 8057fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 8058f4ddd8eeSStefano Zampini } 805957de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 806057de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 806157de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 806257de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 806318a45a71SStefano Zampini } else { 806457de7509SStefano Zampini coarse_mat = NULL; 806557de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 80666e683305SStefano Zampini } 8067e7931f94SStefano Zampini 8068abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 8069abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 8070abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 8071abbbba34SStefano Zampini 8072abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 80734f819b78SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_submat_dense);CHKERRQ(ierr); 8074e176bc59SStefano 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); 80756e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 80766e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 80776e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 8078abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 8079abbbba34SStefano Zampini 808057de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 808157de7509SStefano Zampini im_active = !!(pcis->n); 808257de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 808357de7509SStefano Zampini 808414f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 808557de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 808657de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 8087e569e4e1SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 808857de7509SStefano Zampini coarse_mat_is = NULL; 808957de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 809057de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 8091e569e4e1SStefano Zampini coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 8092ce64c636SStefano Zampini if (coarse_eqs_per_proc < 0) coarse_eqs_per_proc = pcbddc->coarse_size; 809357de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 8094e569e4e1SStefano Zampini if (pcbddc->coarse_size <= pcbddc->coarse_eqs_limit) multilevel_requested = PETSC_FALSE; 809557de7509SStefano Zampini if (multilevel_requested) { 809657de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 809757de7509SStefano Zampini restr = PETSC_FALSE; 809857de7509SStefano Zampini full_restr = PETSC_FALSE; 809957de7509SStefano Zampini } else { 8100e569e4e1SStefano Zampini ncoarse = pcbddc->coarse_size/coarse_eqs_per_proc + !!(pcbddc->coarse_size%coarse_eqs_per_proc); 810157de7509SStefano Zampini restr = PETSC_TRUE; 810257de7509SStefano Zampini full_restr = PETSC_TRUE; 810357de7509SStefano Zampini } 8104e569e4e1SStefano Zampini if (!pcbddc->coarse_size || size == 1) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 810557de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 810657de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 8107a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 8108bb360cb4SStefano Zampini if (multilevel_requested) { 8109bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 8110bb360cb4SStefano Zampini } else { 8111bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 8112bb360cb4SStefano Zampini } 8113a198735bSStefano Zampini } else { 81147de4f681Sstefano_zampini PetscMPIInt rank; 8115a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 8116e569e4e1SStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 8117a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 8118a198735bSStefano Zampini } 811957de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 812057de7509SStefano Zampini PetscInt psum; 812157de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 812257de7509SStefano Zampini else psum = 0; 812357de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8124075e25bcSStefano Zampini have_void = ncoarse < size ? PETSC_TRUE : PETSC_FALSE; 812557de7509SStefano Zampini } 812657de7509SStefano Zampini /* determine if we can go multilevel */ 812757de7509SStefano Zampini if (multilevel_requested) { 812857de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 812957de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 813057de7509SStefano Zampini } 813157de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 813257de7509SStefano Zampini 8133e4d548c7SStefano Zampini /* dump subassembling pattern */ 8134e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 8135e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 8136e4d548c7SStefano Zampini } 81376e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 81381e0482f5SStefano Zampini nedcfield = -1; 81394f819b78SStefano Zampini corners = NULL; 81404f819b78SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal || pcbddc->corner_selected)) { /* protects from unneded computations */ 81416e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 81426e683305SStefano Zampini const PetscInt *idxs; 81436e683305SStefano Zampini ISLocalToGlobalMapping tmap; 81446e683305SStefano Zampini 81456e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 81460be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 81476e683305SStefano Zampini /* allocate space for temporary storage */ 8148854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 8149854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 81506e683305SStefano Zampini /* allocate for IS array */ 81516e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 81521e0482f5SStefano Zampini if (pcbddc->nedclocal) { 81531e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 81541e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 81551e0482f5SStefano Zampini } else { 81561e0482f5SStefano Zampini nedcfield = 0; 81576080607fSStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%D)",nisdofs); 81581e0482f5SStefano Zampini nisdofs = 1; 81591e0482f5SStefano Zampini } 81601e0482f5SStefano Zampini } 81616e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 816227b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 816330368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 8164854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 81656e683305SStefano Zampini /* dofs splitting */ 81666e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 81676e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 81681e0482f5SStefano Zampini if (nedcfield != i) { 81696e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 81706e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 81716e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 81726e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 81731e0482f5SStefano Zampini } else { 81741e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 81751e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 81761e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 81776080607fSStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %D != %D",tsize,nout); 81781e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 81791e0482f5SStefano Zampini } 81806e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 818130368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 81826e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 81836e683305SStefano Zampini } 81846e683305SStefano Zampini /* neumann boundaries */ 81856e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 81866e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 81876e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 81886e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 81896e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 81906e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 81916e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 819230368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 81936e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 81946e683305SStefano Zampini } 81954f819b78SStefano Zampini /* coordinates */ 81964f819b78SStefano Zampini if (pcbddc->corner_selected) { 81974f819b78SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&corners);CHKERRQ(ierr); 81984f819b78SStefano Zampini ierr = ISGetLocalSize(corners,&tsize);CHKERRQ(ierr); 81994f819b78SStefano Zampini ierr = ISGetIndices(corners,&idxs);CHKERRQ(ierr); 82004f819b78SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 82014f819b78SStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping corners! %D != %D",tsize,nout); 82024f819b78SStefano Zampini ierr = ISRestoreIndices(corners,&idxs);CHKERRQ(ierr); 82034f819b78SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&corners);CHKERRQ(ierr); 82044f819b78SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 82054f819b78SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&corners);CHKERRQ(ierr); 82064f819b78SStefano Zampini } 82076e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 82086e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 82096e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 82106e683305SStefano Zampini } else { 82116e683305SStefano Zampini nis = 0; 82126e683305SStefano Zampini nisdofs = 0; 82136e683305SStefano Zampini nisneu = 0; 821430368db7SStefano Zampini nisvert = 0; 82156e683305SStefano Zampini isarray = NULL; 82166e683305SStefano Zampini } 82176e683305SStefano Zampini /* destroy no longer needed map */ 82186e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 82196e683305SStefano Zampini 822057de7509SStefano Zampini /* subassemble */ 822157de7509SStefano Zampini if (multilevel_allowed) { 82221ae86dd6SStefano Zampini Vec vp[1]; 82231ae86dd6SStefano Zampini PetscInt nvecs = 0; 822457de7509SStefano Zampini PetscBool reuse,reuser; 82251ae86dd6SStefano Zampini 822657de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 822757de7509SStefano Zampini else reuse = PETSC_FALSE; 822857de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 82291ae86dd6SStefano Zampini vp[0] = NULL; 82301ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 82311ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 82321ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 82331ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 82341ae86dd6SStefano Zampini nvecs = 1; 82351ae86dd6SStefano Zampini 82361ae86dd6SStefano Zampini if (pcbddc->divudotp) { 8237a198735bSStefano Zampini Mat B,loc_divudotp; 82381ae86dd6SStefano Zampini Vec v,p; 82391ae86dd6SStefano Zampini IS dummy; 82401ae86dd6SStefano Zampini PetscInt np; 82411ae86dd6SStefano Zampini 8242a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 8243a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 82441ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 82457dae84e0SHong Zhang ierr = MatCreateSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 82461ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 82471ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 82481ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 82491ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 82501ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 82511ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 82521ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 82531ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 82541ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 82551ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 82561ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 82571ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 825874e2c79eSStefano Zampini } 82591ae86dd6SStefano Zampini } 82601ae86dd6SStefano Zampini if (reuser) { 82611e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 826274e2c79eSStefano Zampini } else { 82631e0482f5SStefano 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); 82641ae86dd6SStefano Zampini } 82651ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 82661683a169SBarry Smith PetscScalar *arraym; 82671683a169SBarry Smith const PetscScalar *arrayv; 82681ae86dd6SStefano Zampini PetscInt nl; 82691ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 82701ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 82711ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 82721683a169SBarry Smith ierr = VecGetArrayRead(vp[0],&arrayv);CHKERRQ(ierr); 8273*580bdb30SBarry Smith ierr = PetscArraycpy(arraym,arrayv,nl);CHKERRQ(ierr); 82741683a169SBarry Smith ierr = VecRestoreArrayRead(vp[0],&arrayv);CHKERRQ(ierr); 82751ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 82761ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 8277a198735bSStefano Zampini } else { 8278a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 82791ae86dd6SStefano Zampini } 82801ae86dd6SStefano Zampini } else { 82811e0482f5SStefano 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); 82826e683305SStefano Zampini } 828357de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 828457de7509SStefano Zampini if (!multilevel_allowed) { 8285487b449aSStefano Zampini ierr = MatConvert(coarse_mat_is,MATAIJ,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 82866e683305SStefano Zampini } else { 828757de7509SStefano Zampini Mat A; 8288779c1cceSStefano Zampini 828957de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 829057de7509SStefano Zampini if (coarse_mat_is) { 829157de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 829257de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 829357de7509SStefano Zampini coarse_mat = coarse_mat_is; 829457de7509SStefano Zampini } 829557de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 829657de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 829757de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 8298779c1cceSStefano Zampini } 8299779c1cceSStefano Zampini } 830057de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 830157de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 83026e683305SStefano Zampini 83036e683305SStefano Zampini /* create local to global scatters for coarse problem */ 830468457ee5SStefano Zampini if (compute_vecs) { 83056e683305SStefano Zampini PetscInt lrows; 83066e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 830757de7509SStefano Zampini if (coarse_mat) { 830857de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 83096e683305SStefano Zampini } else { 83106e683305SStefano Zampini lrows = 0; 83116e683305SStefano Zampini } 83126e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 83136e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 831489535278SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,coarse_mat ? coarse_mat->defaultvectype : VECSTANDARD);CHKERRQ(ierr); 83156e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 83169448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 83176e683305SStefano Zampini } 83186e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 8319c8587f34SStefano Zampini 8320f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 8321f9eb5b7dSStefano Zampini if (multilevel_allowed) { 8322f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 8323f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 8324f9eb5b7dSStefano Zampini } else { 8325f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 8326f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 8327c8587f34SStefano Zampini } 8328c8587f34SStefano Zampini 83296e683305SStefano Zampini /* print some info if requested */ 83306e683305SStefano Zampini if (pcbddc->dbg_flag) { 83316e683305SStefano Zampini if (!multilevel_allowed) { 83326e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 83336e683305SStefano Zampini if (multilevel_requested) { 83346080607fSStefano 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); 83356e683305SStefano Zampini } else if (pcbddc->max_levels) { 83366080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%D)\n",pcbddc->max_levels);CHKERRQ(ierr); 83376e683305SStefano Zampini } 83386e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 83396e683305SStefano Zampini } 83406e683305SStefano Zampini } 83416e683305SStefano Zampini 83421e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 83431e0482f5SStefano Zampini coarseG = NULL; 83441e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 83451e0482f5SStefano Zampini MPI_Comm ccomm; 83461e0482f5SStefano Zampini if (coarse_mat) { 83471e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 83481e0482f5SStefano Zampini } else { 83491e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 83501e0482f5SStefano Zampini } 83511e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 83521e0482f5SStefano Zampini } 83531e0482f5SStefano Zampini 8354f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 835557de7509SStefano Zampini if (coarse_mat) { 83567274672aSStefano Zampini PetscBool isredundant,isnn,isbddc; 83576a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 83587274672aSStefano Zampini 83596e683305SStefano Zampini if (pcbddc->dbg_flag) { 836057de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 83616e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 83626e683305SStefano Zampini } 8363f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 8364312be037SStefano Zampini char prefix[256],str_level[16]; 8365e604994aSStefano Zampini size_t len; 83661e0482f5SStefano Zampini 836757de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 8368422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 8369c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 8370f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 837157de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8372c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 83736e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 8374c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 83751e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 8376c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8377e604994aSStefano Zampini /* prefix */ 8378e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 8379e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 8380e604994aSStefano Zampini if (!pcbddc->current_level) { 8381a126751eSBarry Smith ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,sizeof(prefix));CHKERRQ(ierr); 8382a126751eSBarry Smith ierr = PetscStrlcat(prefix,"pc_bddc_coarse_",sizeof(prefix));CHKERRQ(ierr); 8383c8587f34SStefano Zampini } else { 8384e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 8385312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 8386312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 8387a126751eSBarry Smith /* Nonstandard use of PetscStrncpy() to copy only a portion of the string */ 838834d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 838935529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 8390a126751eSBarry Smith ierr = PetscStrlcat(prefix,str_level,sizeof(prefix));CHKERRQ(ierr); 8391e604994aSStefano Zampini } 8392e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 83933e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 83943e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 83953e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 83963e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 8397f9eb5b7dSStefano Zampini /* allow user customization */ 8398f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 8399e569e4e1SStefano Zampini /* get some info after set from options */ 8400e569e4e1SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 8401e569e4e1SStefano Zampini /* multilevel cannot be done with coarse PCs different from BDDC or NN */ 8402e569e4e1SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 8403e569e4e1SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 8404e569e4e1SStefano Zampini if (multilevel_allowed && !isbddc && !isnn) { 8405e569e4e1SStefano Zampini isbddc = PETSC_TRUE; 8406e569e4e1SStefano Zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 8407e569e4e1SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 8408e569e4e1SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 8409e569e4e1SStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 84104f819b78SStefano Zampini if (pc_temp->ops->setfromoptions) { /* need to setfromoptions again, skipping the pc_type */ 84114f819b78SStefano Zampini ierr = PetscObjectOptionsBegin((PetscObject)pc_temp);CHKERRQ(ierr); 84124f819b78SStefano Zampini ierr = (*pc_temp->ops->setfromoptions)(PetscOptionsObject,pc_temp);CHKERRQ(ierr); 84134f819b78SStefano Zampini ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pc_temp);CHKERRQ(ierr); 84144f819b78SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 84154f819b78SStefano Zampini pc_temp->setfromoptionscalled++; 84164f819b78SStefano Zampini } 8417e569e4e1SStefano Zampini } 84183e3c6dadSStefano Zampini } 84193e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 842051bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 84213e3c6dadSStefano Zampini if (nisdofs) { 84223e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 84233e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 84243e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 84253e3c6dadSStefano Zampini } 84263e3c6dadSStefano Zampini } 84273e3c6dadSStefano Zampini if (nisneu) { 84283e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 84293e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 8430312be037SStefano Zampini } 843130368db7SStefano Zampini if (nisvert) { 843230368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 843330368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 843430368db7SStefano Zampini } 84351e0482f5SStefano Zampini if (coarseG) { 84361e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 84371e0482f5SStefano Zampini } 8438f9eb5b7dSStefano Zampini 8439f9eb5b7dSStefano Zampini /* get some info after set from options */ 8440f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 84414f819b78SStefano Zampini 8442b76f3995Sstefano_zampini /* multilevel can only be requested via -pc_bddc_levels or PCBDDCSetLevels */ 8443b76f3995Sstefano_zampini if (isbddc && !multilevel_allowed) { 8444f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8445f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 8446f9eb5b7dSStefano Zampini } 8447b76f3995Sstefano_zampini /* multilevel cannot be done with coarse PCs different from BDDC or NN */ 84487274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 84497274672aSStefano Zampini if (multilevel_requested && multilevel_allowed && !isbddc && !isnn) { 8450b76f3995Sstefano_zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 8451b76f3995Sstefano_zampini isbddc = PETSC_TRUE; 8452b76f3995Sstefano_zampini } 84537274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 84544f3a063dSStefano Zampini if (isredundant) { 84554f3a063dSStefano Zampini KSP inner_ksp; 84564f3a063dSStefano Zampini PC inner_pc; 84579326c5c6Sstefano_zampini 84584f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 84594f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 84604f3a063dSStefano Zampini } 8461f9eb5b7dSStefano Zampini 846257de7509SStefano Zampini /* parameters which miss an API */ 84637274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 846457de7509SStefano Zampini if (isbddc) { 8465720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 84667274672aSStefano Zampini 8467720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 846857de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 8469e569e4e1SStefano Zampini pcbddc_coarse->coarse_eqs_limit = pcbddc->coarse_eqs_limit; 847027b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 847127b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 8472a198735bSStefano Zampini Mat coarsedivudotp_is; 8473a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 8474a198735bSStefano Zampini IS row,col; 8475a198735bSStefano Zampini const PetscInt *gidxs; 8476a198735bSStefano Zampini PetscInt n,st,M,N; 8477a198735bSStefano Zampini 8478a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 8479a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 8480a198735bSStefano Zampini st = st-n; 8481a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 8482a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 8483a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 8484a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8485a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 8486a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8487a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 8488a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 8489a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 8490a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 8491a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 8492a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 8493a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 8494a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 8495a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 8496a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 8497a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 8498a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 8499a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 8500a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 85018ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 8502a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 8503720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 8504bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[0] == 0.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 8505720d30f9SStefano Zampini } 8506d4d8cf7bSStefano Zampini } 85079881197aSStefano Zampini 85083301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 85095a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 85103301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 85113301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 85123301b35fSStefano Zampini } 85133301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 85143301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 85153301b35fSStefano Zampini } 85163301b35fSStefano Zampini if (pc->pmat->spd_set) { 85173301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 85183301b35fSStefano Zampini } 851927b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 852027b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 852127b6a85dSStefano Zampini } 85226e683305SStefano Zampini /* set operators */ 852304fe1396SStefano Zampini ierr = MatViewFromOptions(coarse_mat,(PetscObject)pc,"-pc_bddc_coarse_mat_view");CHKERRQ(ierr); 85243007b4efSStefano Zampini ierr = MatSetOptionsPrefix(coarse_mat,((PetscObject)pcbddc->coarse_ksp)->prefix);CHKERRQ(ierr); 85255f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 85266e683305SStefano Zampini if (pcbddc->dbg_flag) { 85276e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 85286e683305SStefano Zampini } 85296e683305SStefano Zampini } 85301e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 85316e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 8532b1ecc7b1SStefano Zampini #if 0 8533b9b85e73SStefano Zampini { 8534b9b85e73SStefano Zampini PetscViewer viewer; 8535b9b85e73SStefano Zampini char filename[256]; 8536b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 8537b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 85386a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 8539b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 8540f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 8541b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 8542b9b85e73SStefano Zampini } 8543b9b85e73SStefano Zampini #endif 8544f9eb5b7dSStefano Zampini 85454f819b78SStefano Zampini if (corners) { 85464f819b78SStefano Zampini Vec gv; 85474f819b78SStefano Zampini IS is; 85484f819b78SStefano Zampini const PetscInt *idxs; 85494f819b78SStefano Zampini PetscInt i,d,N,n,cdim = pcbddc->mat_graph->cdim; 85504f819b78SStefano Zampini PetscScalar *coords; 85514f819b78SStefano Zampini 85524f819b78SStefano Zampini if (!pcbddc->mat_graph->cloc) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing local coordinates"); 85534f819b78SStefano Zampini ierr = VecGetSize(pcbddc->coarse_vec,&N);CHKERRQ(ierr); 85544f819b78SStefano Zampini ierr = VecGetLocalSize(pcbddc->coarse_vec,&n);CHKERRQ(ierr); 85554f819b78SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcbddc->coarse_vec),&gv);CHKERRQ(ierr); 85564f819b78SStefano Zampini ierr = VecSetBlockSize(gv,cdim);CHKERRQ(ierr); 85574f819b78SStefano Zampini ierr = VecSetSizes(gv,n*cdim,N*cdim);CHKERRQ(ierr); 85584f819b78SStefano Zampini ierr = VecSetType(gv,VECSTANDARD);CHKERRQ(ierr); 85594f819b78SStefano Zampini ierr = VecSetFromOptions(gv);CHKERRQ(ierr); 85604f819b78SStefano Zampini ierr = VecSet(gv,PETSC_MAX_REAL);CHKERRQ(ierr); /* we only propagate coordinates from vertices constraints */ 85614f819b78SStefano Zampini 85624f819b78SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&is);CHKERRQ(ierr); 85634f819b78SStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 85644f819b78SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 85654f819b78SStefano Zampini ierr = PetscMalloc1(n*cdim,&coords);CHKERRQ(ierr); 85664f819b78SStefano Zampini for (i=0;i<n;i++) { 85674f819b78SStefano Zampini for (d=0;d<cdim;d++) { 85684f819b78SStefano Zampini coords[cdim*i+d] = pcbddc->mat_graph->coords[cdim*idxs[i]+d]; 85694f819b78SStefano Zampini } 85704f819b78SStefano Zampini } 85714f819b78SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 85724f819b78SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&is);CHKERRQ(ierr); 85734f819b78SStefano Zampini 85744f819b78SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 85754f819b78SStefano Zampini ierr = ISGetIndices(corners,&idxs);CHKERRQ(ierr); 85764f819b78SStefano Zampini ierr = VecSetValuesBlocked(gv,n,idxs,coords,INSERT_VALUES);CHKERRQ(ierr); 85774f819b78SStefano Zampini ierr = ISRestoreIndices(corners,&idxs);CHKERRQ(ierr); 85784f819b78SStefano Zampini ierr = PetscFree(coords);CHKERRQ(ierr); 85794f819b78SStefano Zampini ierr = VecAssemblyBegin(gv);CHKERRQ(ierr); 85804f819b78SStefano Zampini ierr = VecAssemblyEnd(gv);CHKERRQ(ierr); 85814f819b78SStefano Zampini ierr = VecGetArray(gv,&coords);CHKERRQ(ierr); 85824f819b78SStefano Zampini if (pcbddc->coarse_ksp) { 85834f819b78SStefano Zampini PC coarse_pc; 85844f819b78SStefano Zampini PetscBool isbddc; 85854f819b78SStefano Zampini 85864f819b78SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 85874f819b78SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 85884f819b78SStefano Zampini if (isbddc) { /* coarse coordinates have PETSC_MAX_REAL, specific for BDDC */ 85894f819b78SStefano Zampini PetscReal *realcoords; 85904f819b78SStefano Zampini 85914f819b78SStefano Zampini ierr = VecGetLocalSize(gv,&n);CHKERRQ(ierr); 85924f819b78SStefano Zampini #if defined(PETSC_USE_COMPLEX) 85934f819b78SStefano Zampini ierr = PetscMalloc1(n,&realcoords);CHKERRQ(ierr); 85944f819b78SStefano Zampini for (i=0;i<n;i++) realcoords[i] = PetscRealPart(coords[i]); 85954f819b78SStefano Zampini #else 85964f819b78SStefano Zampini realcoords = coords; 85974f819b78SStefano Zampini #endif 85984f819b78SStefano Zampini ierr = PCSetCoordinates(coarse_pc,cdim,n/cdim,realcoords);CHKERRQ(ierr); 85994f819b78SStefano Zampini #if defined(PETSC_USE_COMPLEX) 86004f819b78SStefano Zampini ierr = PetscFree(realcoords);CHKERRQ(ierr); 86014f819b78SStefano Zampini #endif 86024f819b78SStefano Zampini } 86034f819b78SStefano Zampini } 86044f819b78SStefano Zampini ierr = VecRestoreArray(gv,&coords);CHKERRQ(ierr); 86054f819b78SStefano Zampini ierr = VecDestroy(&gv);CHKERRQ(ierr); 86064f819b78SStefano Zampini } 86074f819b78SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 86084f819b78SStefano Zampini 860998a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 861098a51de6SStefano Zampini Vec crhs,csol; 861104708bb6SStefano Zampini 8612f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 8613f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 8614f347579bSStefano Zampini if (!csol) { 86152a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 8616f9eb5b7dSStefano Zampini } 8617f347579bSStefano Zampini if (!crhs) { 86182a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 8619f347579bSStefano Zampini } 8620b0f5fe93SStefano Zampini } 86211ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 8622b0f5fe93SStefano Zampini 8623b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 8624b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 8625b0f5fe93SStefano Zampini 8626b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 86274f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 86284f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 86294f1b2e48SStefano Zampini } 8630b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 8631b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 8632b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8633b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8634b0f5fe93SStefano Zampini if (coarse_mat) { 8635b0f5fe93SStefano Zampini Vec nullv; 8636b0f5fe93SStefano Zampini PetscScalar *array,*array2; 8637b0f5fe93SStefano Zampini PetscInt nl; 8638b0f5fe93SStefano Zampini 8639b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 8640b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 8641b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8642b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 8643*580bdb30SBarry Smith ierr = PetscArraycpy(array2,array,nl);CHKERRQ(ierr); 8644b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 8645b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8646b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 8647b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 8648b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 8649b0f5fe93SStefano Zampini } 8650b0f5fe93SStefano Zampini } 865143371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CoarseSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8652b0f5fe93SStefano Zampini 865343371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CoarseSolver[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8654b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 8655b0f5fe93SStefano Zampini PetscBool ispreonly; 8656b0f5fe93SStefano Zampini 8657b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8658b0f5fe93SStefano Zampini PetscBool isnull; 8659b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 8660bef83e63SStefano Zampini if (isnull) { 8661b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 8662b0f5fe93SStefano Zampini } 8663bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 8664b0f5fe93SStefano Zampini } 8665b0f5fe93SStefano Zampini /* setup coarse ksp */ 8666b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 8667cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 8668cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 86696e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 8670c8587f34SStefano Zampini KSP check_ksp; 86712b510759SStefano Zampini KSPType check_ksp_type; 8672c8587f34SStefano Zampini PC check_pc; 86736e683305SStefano Zampini Vec check_vec,coarse_vec; 86746a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 86752b510759SStefano Zampini PetscInt its; 86766e683305SStefano Zampini PetscBool compute_eigs; 86776e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 86786e683305SStefano Zampini PetscInt neigs; 86798e185a42SStefano Zampini const char *prefix; 8680c8587f34SStefano Zampini 86812b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 86826e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 868315579a77SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)check_ksp,(PetscObject)pcbddc->coarse_ksp,0);CHKERRQ(ierr); 8684399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 868523ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8686f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 8687e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 8688e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 8689e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 86902b510759SStefano Zampini if (ispreonly) { 86912b510759SStefano Zampini check_ksp_type = KSPPREONLY; 86926e683305SStefano Zampini compute_eigs = PETSC_FALSE; 86932b510759SStefano Zampini } else { 8694cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 86956e683305SStefano Zampini compute_eigs = PETSC_TRUE; 8696c8587f34SStefano Zampini } 8697c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 86986e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 86996e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 87006e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 8701a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 8702a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 8703a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 8704a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 8705c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 8706c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 8707c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 8708c8587f34SStefano Zampini /* create random vec */ 87092701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 8710c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 87116e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 8712c8587f34SStefano Zampini /* solve coarse problem */ 87136e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 8714c0decd05SBarry Smith ierr = KSPCheckSolve(check_ksp,pc,coarse_vec);CHKERRQ(ierr); 8715cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 87166e683305SStefano Zampini if (compute_eigs) { 8717854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 8718854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 87196e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 87201ae86dd6SStefano Zampini if (neigs) { 87216e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 87226e683305SStefano Zampini lambda_min = eigs_r[0]; 87236e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 87242701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 87252701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 8726cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 8727cbcc2c2aSStefano Zampini } 8728c8587f34SStefano Zampini } 8729c8587f34SStefano Zampini } 87301ae86dd6SStefano Zampini } 8731cbcc2c2aSStefano Zampini 8732c8587f34SStefano Zampini /* check coarse problem residual error */ 87336e683305SStefano Zampini if (pcbddc->dbg_flag) { 87346e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 87356e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 87366e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 8737c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 87386e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 87396e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 8740779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 87416e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 87426e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 87436e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 87446e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 8745b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8746b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 8747b0f5fe93SStefano Zampini } 87486e683305SStefano Zampini if (compute_eigs) { 87496e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 8750b03ebc13SStefano Zampini KSPConvergedReason reason; 8751deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 8752c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 8753b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 87546e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 8755b03ebc13SStefano 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); 87566e683305SStefano Zampini for (i=0;i<neigs;i++) { 87576e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 8758c8587f34SStefano Zampini } 87596e683305SStefano Zampini } 87606e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 87616e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 87626e683305SStefano Zampini } 8763e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 87642701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 8765c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 87666e683305SStefano Zampini if (compute_eigs) { 87676e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 87686e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 8769c8587f34SStefano Zampini } 87706e683305SStefano Zampini } 87716e683305SStefano Zampini } 8772bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 8773cbcc2c2aSStefano Zampini /* print additional info */ 8774cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 87756e683305SStefano Zampini /* waits until all processes reaches this point */ 87766e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 87776080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %D\n",pcbddc->current_level);CHKERRQ(ierr); 8778cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8779cbcc2c2aSStefano Zampini } 8780cbcc2c2aSStefano Zampini 87812b510759SStefano Zampini /* free memory */ 8782fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 878343371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CoarseSolver[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8784c8587f34SStefano Zampini PetscFunctionReturn(0); 8785c8587f34SStefano Zampini } 8786674ae819SStefano Zampini 8787f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 8788f34684f1SStefano Zampini { 8789f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8790f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 8791f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 8792dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 8793dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 879473be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 8795dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 8796f34684f1SStefano Zampini PetscErrorCode ierr; 8797f34684f1SStefano Zampini 8798f34684f1SStefano Zampini PetscFunctionBegin; 8799f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 88006c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 8801dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 88023bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 8803dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8804dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 88056583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 8806dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 8807dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 8808dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 88096c4ed002SBarry 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); 8810dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 8811dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8812*580bdb30SBarry Smith ierr = PetscArraycpy(local_primal_indices,t_local_primal_indices,local_size);CHKERRQ(ierr); 8813dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8814dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8815f34684f1SStefano Zampini 8816f34684f1SStefano Zampini /* check numbering */ 8817f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 8818019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 8819dc456d91SStefano Zampini PetscInt i; 8820b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 8821f34684f1SStefano Zampini 8822f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8823f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8824f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 88251575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8826019a44ceSStefano Zampini /* counter */ 8827019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8828019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 8829019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8830019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8831019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8832019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8833f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 8834f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 8835727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 8836f34684f1SStefano Zampini } 8837f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8838f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8839f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8840e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8841e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8842e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8843e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8844f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8845019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8846f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8847019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 88482c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 884975c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 8850b9b85e73SStefano Zampini set_error = PETSC_TRUE; 88512c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 88526080607fSStefano 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); 8853f34684f1SStefano Zampini } 8854f34684f1SStefano Zampini } 8855019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8856b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8857f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8858f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8859f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 8860f34684f1SStefano Zampini } 8861f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8862f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8863e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8864e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8865f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 88666080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %D (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 8867b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 8868ca8b9ea9SStefano Zampini PetscInt *gidxs; 8869ca8b9ea9SStefano Zampini 8870ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 88713bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 8872f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 8873f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8874f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 8875f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 88766080607fSStefano 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); 8877f34684f1SStefano Zampini } 8878f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8879ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 8880f34684f1SStefano Zampini } 8881f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 88821575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8883302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 8884f34684f1SStefano Zampini } 88856080607fSStefano Zampini 8886f34684f1SStefano Zampini /* get back data */ 8887f34684f1SStefano Zampini *coarse_size_n = coarse_size; 8888f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 8889674ae819SStefano Zampini PetscFunctionReturn(0); 8890674ae819SStefano Zampini } 8891674ae819SStefano Zampini 8892a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 8893e456f2a8SStefano Zampini { 8894e456f2a8SStefano Zampini IS localis_t; 8895a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 8896e456f2a8SStefano Zampini PetscScalar *vals; 8897e456f2a8SStefano Zampini PetscErrorCode ierr; 8898e456f2a8SStefano Zampini 8899e456f2a8SStefano Zampini PetscFunctionBegin; 8900a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 8901e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 8902854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 8903e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 8904e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8905a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 8906a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 89071035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 89083151afb1SStefano Zampini ierr = VecSetOption(gwork,VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE);CHKERRQ(ierr); 8909a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 89101035eff8SStefano Zampini } 8911a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 8912e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8913e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 8914a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 8915a7dc3881SStefano Zampini /* now compute set in local ordering */ 8916a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8917a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8918a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8919a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 8920a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8921ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8922e456f2a8SStefano Zampini lsize++; 8923e456f2a8SStefano Zampini } 8924e456f2a8SStefano Zampini } 8925854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 8926a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8927ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8928e456f2a8SStefano Zampini idxs[lsize++] = i; 8929e456f2a8SStefano Zampini } 8930e456f2a8SStefano Zampini } 8931a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8932a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 8933e456f2a8SStefano Zampini *localis = localis_t; 8934e456f2a8SStefano Zampini PetscFunctionReturn(0); 8935e456f2a8SStefano Zampini } 8936906d46d4SStefano Zampini 893708122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 8938b96c3477SStefano Zampini { 8939a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8940b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8941b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 8942a64f4aa4SStefano Zampini Mat S_j; 8943b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 8944b96c3477SStefano Zampini PetscBool free_used_adj; 8945b96c3477SStefano Zampini PetscErrorCode ierr; 8946b96c3477SStefano Zampini 8947b96c3477SStefano Zampini PetscFunctionBegin; 894843371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Schurs[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8949b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 8950b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 895108122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 8952b96c3477SStefano Zampini used_xadj = NULL; 8953b96c3477SStefano Zampini used_adjncy = NULL; 8954b96c3477SStefano Zampini } else { 895508122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 895608122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 895708122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 895808122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 8959b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 8960b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 8961b96c3477SStefano Zampini } else { 89622fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 8963b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 8964b96c3477SStefano Zampini PetscInt nvtxs; 8965b96c3477SStefano Zampini 89662fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 89672fffb893SStefano Zampini if (flg_row) { 8968b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 8969*580bdb30SBarry Smith ierr = PetscArraycpy(used_xadj,xadj,nvtxs+1);CHKERRQ(ierr); 8970*580bdb30SBarry Smith ierr = PetscArraycpy(used_adjncy,adjncy,xadj[nvtxs]);CHKERRQ(ierr); 8971b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 89722fffb893SStefano Zampini } else { 89732fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 89742fffb893SStefano Zampini used_xadj = NULL; 89752fffb893SStefano Zampini used_adjncy = NULL; 89762fffb893SStefano Zampini } 89772fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 8978b96c3477SStefano Zampini } 8979b96c3477SStefano Zampini } 8980d5574798SStefano Zampini 8981d5574798SStefano Zampini /* setup sub_schurs data */ 89822f37b69bSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->pA_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8983df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 8984df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 8985a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 898691af6908SStefano 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); 8987a64f4aa4SStefano Zampini } else { 898872b8c272SStefano Zampini Mat change = NULL; 89899d54b7f4SStefano Zampini Vec scaling = NULL; 8990111315fdSstefano_zampini IS change_primal = NULL, iP; 8991111315fdSstefano_zampini PetscInt benign_n; 8992111315fdSstefano_zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 8993111315fdSstefano_zampini PetscBool isseqaij,need_change = PETSC_FALSE; 8994111315fdSstefano_zampini PetscBool discrete_harmonic = PETSC_FALSE; 8995a3df083aSStefano Zampini 89965feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 89975feab87aSStefano Zampini PetscInt n_vertices; 89985feab87aSStefano Zampini 89995feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 90002034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 90015feab87aSStefano Zampini } 900204708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 900304708bb6SStefano Zampini if (!isseqaij) { 900404708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 900504708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 900604708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 900704708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 900804708bb6SStefano Zampini } else { 9009511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 901004708bb6SStefano Zampini } 901104708bb6SStefano Zampini } 9012a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 9013a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 9014ca92afb2SStefano Zampini } else { 9015a3df083aSStefano Zampini benign_n = 0; 9016ca92afb2SStefano Zampini } 9017b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 9018b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 9019b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 902072b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 902122db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 9022b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 902322db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 9024b7ab4a40SStefano Zampini } 9025b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 9026b7ab4a40SStefano 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 */ 9027b7ab4a40SStefano Zampini if (need_change) { 902888c03ad3SStefano Zampini PC_IS *pcisf; 902988c03ad3SStefano Zampini PC_BDDC *pcbddcf; 903088c03ad3SStefano Zampini PC pcf; 903188c03ad3SStefano Zampini 9032e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 903388c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 903488c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 903588c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 9036b9be95fcSstefano_zampini 903788c03ad3SStefano Zampini /* hacks */ 903888c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 903972b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 904072b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 904172b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 904272b8c272SStefano Zampini pcisf->n = pcis->n; 904372b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 904488c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 904588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 904688c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 904788c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 904888c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 904988c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 905072b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 905188c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 9052b9be95fcSstefano_zampini 9053b9be95fcSstefano_zampini /* setup constraints so that we can get information on primal vertices and change of basis (in local numbering) */ 905488c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 905572b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 905672b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 905772b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 905872b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 9059b9be95fcSstefano_zampini 906088c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 906172b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 906288c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 906388c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 906488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 906588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 906688c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 906788c03ad3SStefano Zampini pcf->ops->destroy = NULL; 9068b9be95fcSstefano_zampini pcf->ops->reset = NULL; 906988c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 907088c03ad3SStefano Zampini } 90719d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 9072111315fdSstefano_zampini 9073111315fdSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 9074111315fdSstefano_zampini if (iP) { 9075111315fdSstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)iP),sub_schurs->prefix,"BDDC sub_schurs options","PC");CHKERRQ(ierr); 9076111315fdSstefano_zampini ierr = PetscOptionsBool("-sub_schurs_discrete_harmonic",NULL,NULL,discrete_harmonic,&discrete_harmonic,NULL);CHKERRQ(ierr); 9077111315fdSstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 9078111315fdSstefano_zampini } 9079111315fdSstefano_zampini if (discrete_harmonic) { 9080111315fdSstefano_zampini Mat A; 9081111315fdSstefano_zampini ierr = MatDuplicate(pcbddc->local_mat,MAT_COPY_VALUES,&A);CHKERRQ(ierr); 9082111315fdSstefano_zampini ierr = MatZeroRowsColumnsIS(A,iP,1.0,NULL,NULL);CHKERRQ(ierr); 9083111315fdSstefano_zampini ierr = PetscObjectCompose((PetscObject)A,"__KSPFETIDP_iP",(PetscObject)iP);CHKERRQ(ierr); 9084111315fdSstefano_zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,A,S_j,pcbddc->sub_schurs_exact_schur,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,scaling,pcbddc->adaptive_selection,reuse_solvers,pcbddc->benign_saddle_point,benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_zerodiag_subs,change,change_primal);CHKERRQ(ierr); 9085111315fdSstefano_zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 9086111315fdSstefano_zampini } else { 908791af6908SStefano 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); 9088111315fdSstefano_zampini } 908972b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 909072b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 9091ca92afb2SStefano Zampini } 9092d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 9093b96c3477SStefano Zampini 9094b96c3477SStefano Zampini /* free adjacency */ 9095b96c3477SStefano Zampini if (free_used_adj) { 9096b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 9097b96c3477SStefano Zampini } 909843371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Schurs[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 9099b96c3477SStefano Zampini PetscFunctionReturn(0); 9100b96c3477SStefano Zampini } 9101b96c3477SStefano Zampini 910208122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 9103b96c3477SStefano Zampini { 9104b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 9105b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 9106b96c3477SStefano Zampini PCBDDCGraph graph; 9107b96c3477SStefano Zampini PetscErrorCode ierr; 9108b96c3477SStefano Zampini 9109b96c3477SStefano Zampini PetscFunctionBegin; 9110b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 911108122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 91123301b35fSStefano Zampini IS verticesIS,verticescomm; 91133301b35fSStefano Zampini PetscInt vsize,*idxs; 9114b96c3477SStefano Zampini 9115b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 91163301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 91173301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 91183301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 91193301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 9120c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 9121b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 9122be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 9123441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 91243301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 9125b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 9126b96c3477SStefano Zampini } else { 9127b96c3477SStefano Zampini graph = pcbddc->mat_graph; 9128b96c3477SStefano Zampini } 9129e4d548c7SStefano Zampini /* print some info */ 91305c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 9131e4d548c7SStefano Zampini IS vertices; 9132e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 9133c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 9134e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 9135e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 9136e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 9137e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 91386080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%D)\n",PetscGlobalRank,(int)nv,pcbddc->use_vertices);CHKERRQ(ierr); 91396080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%D)\n",PetscGlobalRank,(int)nedges,pcbddc->use_edges);CHKERRQ(ierr); 91406080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%D)\n",PetscGlobalRank,(int)nfaces,pcbddc->use_faces);CHKERRQ(ierr); 9141e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 9142e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 9143c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 9144e4d548c7SStefano Zampini } 9145b96c3477SStefano Zampini 9146b96c3477SStefano Zampini /* sub_schurs init */ 9147b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 9148b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 9149b334f244SStefano Zampini } 915088113c35SStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,((PetscObject)pc)->prefix,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 9151a64f4aa4SStefano Zampini 9152b96c3477SStefano Zampini /* free graph struct */ 915308122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 9154b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 9155b96c3477SStefano Zampini } 9156b96c3477SStefano Zampini PetscFunctionReturn(0); 9157b96c3477SStefano Zampini } 9158fa34dd3eSStefano Zampini 9159fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 9160fa34dd3eSStefano Zampini { 9161fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 9162fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 9163fa34dd3eSStefano Zampini PetscErrorCode ierr; 9164fa34dd3eSStefano Zampini 9165fa34dd3eSStefano Zampini PetscFunctionBegin; 9166fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 9167fa34dd3eSStefano Zampini IS zerodiag = NULL; 91684f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 9169fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 91704f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 917175c01103SStefano Zampini PetscReal norm; 9172fa34dd3eSStefano Zampini PetscInt i; 9173fa34dd3eSStefano Zampini 9174fa34dd3eSStefano Zampini /* B0 and B0_B */ 9175fa34dd3eSStefano Zampini if (zerodiag) { 9176fa34dd3eSStefano Zampini IS dummy; 9177fa34dd3eSStefano Zampini 91784f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 91797dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 9180fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 9181fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 9182fa34dd3eSStefano Zampini } 9183fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 9184fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 9185fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 9186fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9187fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9188fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9189fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9190fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 9191fa34dd3eSStefano Zampini /* S_j */ 91922f37b69bSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->pA_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 9193fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 9194fa34dd3eSStefano Zampini 9195fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 9196fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 9197fa34dd3eSStefano Zampini /* continuous in primal space */ 9198fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 9199fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9200fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9201fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 92024f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 92034f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 9204fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 9205fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 9206fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 9207fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 9208fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9209fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9210fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 9211fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 9212fa34dd3eSStefano Zampini 9213fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 9214fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 9215fa34dd3eSStefano Zampini /* local with Schur */ 9216fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 9217fa34dd3eSStefano Zampini if (zerodiag) { 9218fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 92194f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 9220fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 9221fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 9222fa34dd3eSStefano Zampini } 9223fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 9224fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9225fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9226fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 9227fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 9228fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 9229fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 9230fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 9231fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 9232fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9233fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9234fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9235fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9236fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 9237fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 9238fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 9239fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 9240fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 9241fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 9242fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 9243fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9244fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9245fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 9246fa34dd3eSStefano Zampini if (zerodiag) { 9247fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 9248fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 92494f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 9250fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 9251fa34dd3eSStefano Zampini } 9252fa34dd3eSStefano Zampini /* BDDC */ 9253fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 9254fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 9255fa34dd3eSStefano Zampini 9256fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 9257fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 9258fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 92596080607fSStefano Zampini ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm);CHKERRQ(ierr); 92604f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 92616080607fSStefano Zampini ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%D] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i]));CHKERRQ(ierr); 9262fa34dd3eSStefano Zampini } 92634f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 9264fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 9265fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 9266fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 9267fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 9268fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 9269fa34dd3eSStefano Zampini } 9270fa34dd3eSStefano Zampini PetscFunctionReturn(0); 9271fa34dd3eSStefano Zampini } 92721e0482f5SStefano Zampini 92731e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 92741e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 92751e0482f5SStefano Zampini { 92761e0482f5SStefano Zampini Mat At; 92771e0482f5SStefano Zampini IS rows; 92781e0482f5SStefano Zampini PetscInt rst,ren; 92791e0482f5SStefano Zampini PetscErrorCode ierr; 92801e0482f5SStefano Zampini PetscLayout rmap; 92811e0482f5SStefano Zampini 92821e0482f5SStefano Zampini PetscFunctionBegin; 92831e0482f5SStefano Zampini rst = ren = 0; 92841e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 92851e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 92861e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 92871e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 92881e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 92891e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 92901e0482f5SStefano Zampini } 9291e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 92927dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 92931e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 92941e0482f5SStefano Zampini 92951e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 92961e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 92971e0482f5SStefano Zampini IS from,to; 92981e0482f5SStefano Zampini Vec gvec; 92991e0482f5SStefano Zampini PetscInt lsize; 93001e0482f5SStefano Zampini 93011e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 93021e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 93031e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 93041e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 93051e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 93061e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 93071e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 93081e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 93091e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 93101e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 93111e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 93121e0482f5SStefano Zampini b->A = a->A; 93131e0482f5SStefano Zampini b->B = a->B; 93141e0482f5SStefano Zampini 93151e0482f5SStefano Zampini b->donotstash = a->donotstash; 93161e0482f5SStefano Zampini b->roworiented = a->roworiented; 93171e0482f5SStefano Zampini b->rowindices = 0; 93181e0482f5SStefano Zampini b->rowvalues = 0; 93191e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 93201e0482f5SStefano Zampini 93211e0482f5SStefano Zampini (*B)->rmap = rmap; 93221e0482f5SStefano Zampini (*B)->factortype = A->factortype; 93231e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 93241e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 93251e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 93261e0482f5SStefano Zampini 93271e0482f5SStefano Zampini if (a->colmap) { 93281e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 93291e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 93301e0482f5SStefano Zampini #else 93311e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 93321e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 9333*580bdb30SBarry Smith ierr = PetscArraycpy(b->colmap,a->colmap,At->cmap->N);CHKERRQ(ierr); 93341e0482f5SStefano Zampini #endif 93351e0482f5SStefano Zampini } else b->colmap = 0; 93361e0482f5SStefano Zampini if (a->garray) { 93371e0482f5SStefano Zampini PetscInt len; 93381e0482f5SStefano Zampini len = a->B->cmap->n; 93391e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 93401e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 9341*580bdb30SBarry Smith if (len) { ierr = PetscArraycpy(b->garray,a->garray,len);CHKERRQ(ierr); } 93421e0482f5SStefano Zampini } else b->garray = 0; 93431e0482f5SStefano Zampini 93441e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 93451e0482f5SStefano Zampini b->lvec = a->lvec; 93461e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 93471e0482f5SStefano Zampini 93481e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 93491e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 93501e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 93511e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 93521e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 93539448b7f1SJunchao Zhang ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 93541e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 93551e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 93561e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 93571e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 93581e0482f5SStefano Zampini } 93591e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 93601e0482f5SStefano Zampini PetscFunctionReturn(0); 93611e0482f5SStefano Zampini } 9362