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); 68580bdb30SBarry 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); 72580bdb30SBarry 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 236580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,n);CHKERRQ(ierr); 237580bdb30SBarry 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) */ 323580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,n);CHKERRQ(ierr); 324580bdb30SBarry 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); 637580bdb30SBarry Smith ierr = PetscArrayzero(sfvleaves,nv);CHKERRQ(ierr); 638580bdb30SBarry 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 */ 803580bdb30SBarry 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); 936580bdb30SBarry 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 */ 1031580bdb30SBarry 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; 1139580bdb30SBarry 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); 1183580bdb30SBarry 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); 1604*b470e4b4SRichard Tran Mills ierr = VecBindToCPU(global,PETSC_TRUE);CHKERRQ(ierr); 1605*b470e4b4SRichard Tran Mills ierr = VecBindToCPU(local,PETSC_TRUE);CHKERRQ(ierr); 16066a8fc67bSStefano Zampini if (monolithic) { /* just get block size to properly compute vertices */ 16076a8fc67bSStefano Zampini if (pcbddc->vertex_size == 1) { 16086a8fc67bSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->vertex_size);CHKERRQ(ierr); 16096a8fc67bSStefano Zampini } 16106a8fc67bSStefano Zampini goto boundary; 16116a8fc67bSStefano Zampini } 16125c5e10d6SStefano Zampini 16131f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 16141f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 16151f4df5f7SStefano Zampini PetscInt i; 16160c85b387SStefano Zampini 16171f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16181f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 16190c85b387SStefano Zampini PetscInt bs; 16200c85b387SStefano Zampini 16211f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16220c85b387SStefano Zampini ierr = ISGetBlockSize(pcbddc->ISForDofs[i],&bs);CHKERRQ(ierr); 16230c85b387SStefano Zampini ierr = ISSetBlockSize(pcbddc->ISForDofsLocal[i],bs);CHKERRQ(ierr); 16241f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 16251f4df5f7SStefano Zampini } 16261f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 16271f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 16281f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 16291f4df5f7SStefano Zampini } 16301f4df5f7SStefano Zampini } else { 163121ef3d20SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present */ 163221ef3d20SStefano Zampini DM dm; 163321ef3d20SStefano Zampini 163421ef3d20SStefano Zampini ierr = MatGetDM(pc->pmat, &dm);CHKERRQ(ierr); 16354f819b78SStefano Zampini if (!dm) { 16364f819b78SStefano Zampini ierr = PCGetDM(pc, &dm);CHKERRQ(ierr); 163721ef3d20SStefano Zampini } 163821ef3d20SStefano Zampini if (dm) { 163921ef3d20SStefano Zampini IS *fields; 164021ef3d20SStefano Zampini PetscInt nf,i; 16410c85b387SStefano Zampini 164221ef3d20SStefano Zampini ierr = DMCreateFieldDecomposition(dm,&nf,NULL,&fields,NULL);CHKERRQ(ierr); 164321ef3d20SStefano Zampini ierr = PetscMalloc1(nf,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 164421ef3d20SStefano Zampini for (i=0;i<nf;i++) { 16450c85b387SStefano Zampini PetscInt bs; 16460c85b387SStefano Zampini 164721ef3d20SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,fields[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16480c85b387SStefano Zampini ierr = ISGetBlockSize(fields[i],&bs);CHKERRQ(ierr); 16490c85b387SStefano Zampini ierr = ISSetBlockSize(pcbddc->ISForDofsLocal[i],bs);CHKERRQ(ierr); 165021ef3d20SStefano Zampini ierr = ISDestroy(&fields[i]);CHKERRQ(ierr); 165121ef3d20SStefano Zampini } 165221ef3d20SStefano Zampini ierr = PetscFree(fields);CHKERRQ(ierr); 165321ef3d20SStefano Zampini pcbddc->n_ISForDofsLocal = nf; 165421ef3d20SStefano Zampini } else { /* See if MATIS has fields attached by the conversion from MatNest */ 165521ef3d20SStefano Zampini PetscContainer c; 165621ef3d20SStefano Zampini 165721ef3d20SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc->pmat,"_convert_nest_lfields",(PetscObject*)&c);CHKERRQ(ierr); 165821ef3d20SStefano Zampini if (c) { 165921ef3d20SStefano Zampini MatISLocalFields lf; 166021ef3d20SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&lf);CHKERRQ(ierr); 166121ef3d20SStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,lf->nr,lf->rf);CHKERRQ(ierr); 166221ef3d20SStefano Zampini } else { /* fallback, create the default fields if bs > 1 */ 16631f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1664986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 166521ef3d20SStefano Zampini if (i > 1) { 1666986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 16671f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16681f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16691f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16701f4df5f7SStefano Zampini } 16711f4df5f7SStefano Zampini } 167221ef3d20SStefano Zampini } 167321ef3d20SStefano Zampini } 16747a0e7b2cSstefano_zampini } else { 16757a0e7b2cSstefano_zampini PetscInt i; 16767a0e7b2cSstefano_zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16777a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16787a0e7b2cSstefano_zampini } 16791f4df5f7SStefano Zampini } 1680986cdee1SStefano Zampini } 16811f4df5f7SStefano Zampini 16825c5e10d6SStefano Zampini boundary: 16831f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 16841f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16857a0e7b2cSstefano_zampini } else if (pcbddc->DirichletBoundariesLocal) { 16867a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16871f4df5f7SStefano Zampini } 16881f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 16891f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16907a0e7b2cSstefano_zampini } else if (pcbddc->NeumannBoundariesLocal) { 16917a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16921f4df5f7SStefano Zampini } 16931f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 16941f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 16951f4df5f7SStefano Zampini } 16961f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 16971f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 16987620a527SStefano Zampini /* detect local disconnected subdomains if requested (use matis->A) */ 16997620a527SStefano Zampini if (pcbddc->detect_disconnected) { 17007620a527SStefano Zampini IS primalv = NULL; 17017620a527SStefano Zampini PetscInt i; 17028361f951SStefano Zampini PetscBool filter = pcbddc->detect_disconnected_filter; 17037a0e7b2cSstefano_zampini 17047620a527SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 17057620a527SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 17067620a527SStefano Zampini } 17077620a527SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 17088361f951SStefano Zampini ierr = PCBDDCDetectDisconnectedComponents(pc,filter,&pcbddc->n_local_subs,&pcbddc->local_subs,&primalv);CHKERRQ(ierr); 17097620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 17107620a527SStefano Zampini ierr = ISDestroy(&primalv);CHKERRQ(ierr); 17117620a527SStefano Zampini } 17127620a527SStefano Zampini /* early stage corner detection */ 17137620a527SStefano Zampini { 17147620a527SStefano Zampini DM dm; 17157620a527SStefano Zampini 17167620a527SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 17174f819b78SStefano Zampini if (!dm) { 17184f819b78SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 17194f819b78SStefano Zampini } 17207620a527SStefano Zampini if (dm) { 17217620a527SStefano Zampini PetscBool isda; 17227620a527SStefano Zampini 17237620a527SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&isda);CHKERRQ(ierr); 17247620a527SStefano Zampini if (isda) { 17257620a527SStefano Zampini ISLocalToGlobalMapping l2l; 17267620a527SStefano Zampini IS corners; 17277620a527SStefano Zampini Mat lA; 17284f819b78SStefano Zampini PetscBool gl,lo; 17297620a527SStefano Zampini 17304f819b78SStefano Zampini { 17314f819b78SStefano Zampini Vec cvec; 17324f819b78SStefano Zampini const PetscScalar *coords; 17334f819b78SStefano Zampini PetscInt dof,n,cdim; 17344f819b78SStefano Zampini PetscBool memc = PETSC_TRUE; 17354f819b78SStefano Zampini 17364f819b78SStefano Zampini ierr = DMDAGetInfo(dm,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dof,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 17374f819b78SStefano Zampini ierr = DMGetCoordinates(dm,&cvec);CHKERRQ(ierr); 17384f819b78SStefano Zampini ierr = VecGetLocalSize(cvec,&n);CHKERRQ(ierr); 17394f819b78SStefano Zampini ierr = VecGetBlockSize(cvec,&cdim);CHKERRQ(ierr); 17404f819b78SStefano Zampini n /= cdim; 17414f819b78SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->coords);CHKERRQ(ierr); 17424f819b78SStefano Zampini ierr = PetscMalloc1(dof*n*cdim,&pcbddc->mat_graph->coords);CHKERRQ(ierr); 17434f819b78SStefano Zampini ierr = VecGetArrayRead(cvec,&coords);CHKERRQ(ierr); 17444f819b78SStefano Zampini #if defined(PETSC_USE_COMPLEX) 17454f819b78SStefano Zampini memc = PETSC_FALSE; 17464f819b78SStefano Zampini #endif 17474f819b78SStefano Zampini if (dof != 1) memc = PETSC_FALSE; 17484f819b78SStefano Zampini if (memc) { 1749580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->mat_graph->coords,coords,cdim*n*dof);CHKERRQ(ierr); 17504f819b78SStefano Zampini } else { /* BDDC graph does not use any blocked information, we need to replicate the data */ 17514f819b78SStefano Zampini PetscReal *bcoords = pcbddc->mat_graph->coords; 17524f819b78SStefano Zampini PetscInt i, b, d; 17534f819b78SStefano Zampini 17544f819b78SStefano Zampini for (i=0;i<n;i++) { 17554f819b78SStefano Zampini for (b=0;b<dof;b++) { 17564f819b78SStefano Zampini for (d=0;d<cdim;d++) { 17574f819b78SStefano Zampini bcoords[i*dof*cdim + b*cdim + d] = PetscRealPart(coords[i*cdim+d]); 17584f819b78SStefano Zampini } 17594f819b78SStefano Zampini } 17604f819b78SStefano Zampini } 17614f819b78SStefano Zampini } 17624f819b78SStefano Zampini ierr = VecRestoreArrayRead(cvec,&coords);CHKERRQ(ierr); 17634f819b78SStefano Zampini pcbddc->mat_graph->cdim = cdim; 17644f819b78SStefano Zampini pcbddc->mat_graph->cnloc = dof*n; 17654f819b78SStefano Zampini pcbddc->mat_graph->cloc = PETSC_FALSE; 17664f819b78SStefano Zampini } 1767d4a6ed37SStefano Zampini ierr = DMDAGetSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17687620a527SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17697620a527SStefano Zampini ierr = MatGetLocalToGlobalMapping(lA,&l2l,NULL);CHKERRQ(ierr); 17707620a527SStefano Zampini ierr = MatISRestoreLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17714f819b78SStefano Zampini lo = (PetscBool)(l2l && corners); 17724f819b78SStefano Zampini ierr = MPIU_Allreduce(&lo,&gl,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 17734f819b78SStefano Zampini if (gl) { /* From PETSc's DMDA */ 17747620a527SStefano Zampini const PetscInt *idx; 177572ed36d8SStefano Zampini PetscInt dof,bs,*idxout,n; 17767620a527SStefano Zampini 177772ed36d8SStefano Zampini ierr = DMDAGetInfo(dm,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dof,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 17787620a527SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(l2l,&bs);CHKERRQ(ierr); 17797620a527SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 17807620a527SStefano Zampini ierr = ISGetIndices(corners,&idx);CHKERRQ(ierr); 178172ed36d8SStefano Zampini if (bs == dof) { 17827620a527SStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 17837620a527SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(l2l,n,idx,idxout);CHKERRQ(ierr); 178472ed36d8SStefano Zampini } else { /* the original DMDA local-to-local map have been modified */ 178572ed36d8SStefano Zampini PetscInt i,d; 178672ed36d8SStefano Zampini 178772ed36d8SStefano Zampini ierr = PetscMalloc1(dof*n,&idxout);CHKERRQ(ierr); 178872ed36d8SStefano Zampini for (i=0;i<n;i++) for (d=0;d<dof;d++) idxout[dof*i+d] = dof*idx[i]+d; 178972ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingApply(l2l,dof*n,idxout,idxout);CHKERRQ(ierr); 179072ed36d8SStefano Zampini 179172ed36d8SStefano Zampini bs = 1; 179272ed36d8SStefano Zampini n *= dof; 179372ed36d8SStefano Zampini } 17947620a527SStefano Zampini ierr = ISRestoreIndices(corners,&idx);CHKERRQ(ierr); 1795d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17967620a527SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)pc),bs,n,idxout,PETSC_OWN_POINTER,&corners);CHKERRQ(ierr); 17977620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,corners);CHKERRQ(ierr); 17987620a527SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 17991c7a958bSStefano Zampini pcbddc->corner_selected = PETSC_TRUE; 18004f819b78SStefano Zampini pcbddc->corner_selection = PETSC_TRUE; 18014f819b78SStefano Zampini } 18024f819b78SStefano Zampini if (corners) { 1803d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 18047620a527SStefano Zampini } 18057620a527SStefano Zampini } 18067620a527SStefano Zampini } 18077620a527SStefano Zampini } 18081c7a958bSStefano Zampini if (pcbddc->corner_selection && !pcbddc->mat_graph->cdim) { 18091c7a958bSStefano Zampini DM dm; 18101c7a958bSStefano Zampini 18111c7a958bSStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 18124f819b78SStefano Zampini if (!dm) { 18134f819b78SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 18141c7a958bSStefano Zampini } 18154f819b78SStefano Zampini if (dm) { /* this can get very expensive, I need to find a faster alternative */ 18161c7a958bSStefano Zampini Vec vcoords; 18171c7a958bSStefano Zampini PetscSection section; 18181c7a958bSStefano Zampini PetscReal *coords; 18191c7a958bSStefano Zampini PetscInt d,cdim,nl,nf,**ctxs; 18201c7a958bSStefano Zampini PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal *, PetscInt, PetscScalar *, void *); 18211c7a958bSStefano Zampini 18221c7a958bSStefano Zampini ierr = DMGetCoordinateDim(dm,&cdim);CHKERRQ(ierr); 182392fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 18241c7a958bSStefano Zampini ierr = PetscSectionGetNumFields(section,&nf);CHKERRQ(ierr); 18251c7a958bSStefano Zampini ierr = DMCreateGlobalVector(dm,&vcoords);CHKERRQ(ierr); 18261c7a958bSStefano Zampini ierr = VecGetLocalSize(vcoords,&nl);CHKERRQ(ierr); 18271c7a958bSStefano Zampini ierr = PetscMalloc1(nl*cdim,&coords);CHKERRQ(ierr); 18281c7a958bSStefano Zampini ierr = PetscMalloc2(nf,&funcs,nf,&ctxs);CHKERRQ(ierr); 18291c7a958bSStefano Zampini ierr = PetscMalloc1(nf,&ctxs[0]);CHKERRQ(ierr); 18301c7a958bSStefano Zampini for (d=0;d<nf;d++) funcs[d] = func_coords_private; 18311c7a958bSStefano Zampini for (d=1;d<nf;d++) ctxs[d] = ctxs[d-1] + 1; 18321c7a958bSStefano Zampini for (d=0;d<cdim;d++) { 18331c7a958bSStefano Zampini PetscInt i; 18341c7a958bSStefano Zampini const PetscScalar *v; 18351c7a958bSStefano Zampini 18361c7a958bSStefano Zampini for (i=0;i<nf;i++) ctxs[i][0] = d; 18371c7a958bSStefano Zampini ierr = DMProjectFunction(dm,0.0,funcs,(void**)ctxs,INSERT_VALUES,vcoords);CHKERRQ(ierr); 18381c7a958bSStefano Zampini ierr = VecGetArrayRead(vcoords,&v);CHKERRQ(ierr); 18391c7a958bSStefano Zampini for (i=0;i<nl;i++) coords[i*cdim+d] = PetscRealPart(v[i]); 18401c7a958bSStefano Zampini ierr = VecRestoreArrayRead(vcoords,&v);CHKERRQ(ierr); 18411c7a958bSStefano Zampini } 18421c7a958bSStefano Zampini ierr = VecDestroy(&vcoords);CHKERRQ(ierr); 18431c7a958bSStefano Zampini ierr = PCSetCoordinates(pc,cdim,nl,coords);CHKERRQ(ierr); 18441c7a958bSStefano Zampini ierr = PetscFree(coords);CHKERRQ(ierr); 18451c7a958bSStefano Zampini ierr = PetscFree(ctxs[0]);CHKERRQ(ierr); 18461c7a958bSStefano Zampini ierr = PetscFree2(funcs,ctxs);CHKERRQ(ierr); 18471c7a958bSStefano Zampini } 18481c7a958bSStefano Zampini } 18497a0e7b2cSstefano_zampini PetscFunctionReturn(0); 18507a0e7b2cSstefano_zampini } 18517a0e7b2cSstefano_zampini 18527a0e7b2cSstefano_zampini PetscErrorCode PCBDDCConsistencyCheckIS(PC pc, MPI_Op mop, IS *is) 18537a0e7b2cSstefano_zampini { 18547a0e7b2cSstefano_zampini Mat_IS *matis = (Mat_IS*)(pc->pmat->data); 18557a0e7b2cSstefano_zampini PetscErrorCode ierr; 18567a0e7b2cSstefano_zampini IS nis; 18577a0e7b2cSstefano_zampini const PetscInt *idxs; 18587a0e7b2cSstefano_zampini PetscInt i,nd,n = matis->A->rmap->n,*nidxs,nnd; 18597a0e7b2cSstefano_zampini PetscBool *ld; 18607a0e7b2cSstefano_zampini 18617a0e7b2cSstefano_zampini PetscFunctionBegin; 18627a0e7b2cSstefano_zampini if (mop != MPI_LAND && mop != MPI_LOR) SETERRQ(PetscObjectComm((PetscObject)(pc)),PETSC_ERR_SUP,"Supported are MPI_LAND and MPI_LOR"); 18637a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18647a0e7b2cSstefano_zampini /* init rootdata with true */ 18657a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_rootdata; 18667a0e7b2cSstefano_zampini for (i=0;i<pc->pmat->rmap->n;i++) ld[i] = PETSC_TRUE; 18677a0e7b2cSstefano_zampini } else { 1868580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,pc->pmat->rmap->n);CHKERRQ(ierr); 18697a0e7b2cSstefano_zampini } 1870580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,n);CHKERRQ(ierr); 18717a0e7b2cSstefano_zampini ierr = ISGetLocalSize(*is,&nd);CHKERRQ(ierr); 18727a0e7b2cSstefano_zampini ierr = ISGetIndices(*is,&idxs);CHKERRQ(ierr); 18737a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_leafdata; 18747a0e7b2cSstefano_zampini for (i=0;i<nd;i++) 18757a0e7b2cSstefano_zampini if (-1 < idxs[i] && idxs[i] < n) 18767a0e7b2cSstefano_zampini ld[idxs[i]] = PETSC_TRUE; 18777a0e7b2cSstefano_zampini ierr = ISRestoreIndices(*is,&idxs);CHKERRQ(ierr); 18787a0e7b2cSstefano_zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18797a0e7b2cSstefano_zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18807a0e7b2cSstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18817a0e7b2cSstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18827a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18837a0e7b2cSstefano_zampini ierr = PetscMalloc1(nd,&nidxs);CHKERRQ(ierr); 18847a0e7b2cSstefano_zampini } else { 18857a0e7b2cSstefano_zampini ierr = PetscMalloc1(n,&nidxs);CHKERRQ(ierr); 18867a0e7b2cSstefano_zampini } 18877a0e7b2cSstefano_zampini for (i=0,nnd=0;i<n;i++) 18887a0e7b2cSstefano_zampini if (ld[i]) 18897a0e7b2cSstefano_zampini nidxs[nnd++] = i; 18907a0e7b2cSstefano_zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(*is)),nnd,nidxs,PETSC_OWN_POINTER,&nis);CHKERRQ(ierr); 18917a0e7b2cSstefano_zampini ierr = ISDestroy(is);CHKERRQ(ierr); 18927a0e7b2cSstefano_zampini *is = nis; 18931f4df5f7SStefano Zampini PetscFunctionReturn(0); 18941f4df5f7SStefano Zampini } 18951f4df5f7SStefano Zampini 18963e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 18973e589ea0SStefano Zampini { 18983e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18993e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 19003e589ea0SStefano Zampini PetscErrorCode ierr; 19013e589ea0SStefano Zampini 19023e589ea0SStefano Zampini PetscFunctionBegin; 19033e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 19043e589ea0SStefano Zampini PetscFunctionReturn(0); 19053e589ea0SStefano Zampini } 19063e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19073e589ea0SStefano Zampini Vec swap; 19083e589ea0SStefano Zampini 19093e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19103e589ea0SStefano Zampini swap = pcbddc->work_change; 19113e589ea0SStefano Zampini pcbddc->work_change = r; 19123e589ea0SStefano Zampini r = swap; 19133e589ea0SStefano Zampini } 19143e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19153e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19163e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1917c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 19183e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 19193e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19203e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19213e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1922f913dca9SStefano Zampini pcbddc->work_change = r; 19233e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 19243e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 19253e589ea0SStefano Zampini } 19263e589ea0SStefano Zampini PetscFunctionReturn(0); 19273e589ea0SStefano Zampini } 19283e589ea0SStefano Zampini 1929a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1930a3df083aSStefano Zampini { 1931a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1932a3df083aSStefano Zampini PetscErrorCode ierr; 1933a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1934a3df083aSStefano Zampini 1935a3df083aSStefano Zampini PetscFunctionBegin; 1936a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1937a3df083aSStefano Zampini if (transpose) { 1938a3df083aSStefano Zampini apply_right = ctx->apply_left; 1939a3df083aSStefano Zampini apply_left = ctx->apply_right; 1940a3df083aSStefano Zampini } else { 1941a3df083aSStefano Zampini apply_right = ctx->apply_right; 1942a3df083aSStefano Zampini apply_left = ctx->apply_left; 1943a3df083aSStefano Zampini } 1944a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1945a3df083aSStefano Zampini if (apply_right) { 1946a3df083aSStefano Zampini const PetscScalar *ax; 1947a3df083aSStefano Zampini PetscInt nl,i; 1948a3df083aSStefano Zampini 1949a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1950a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1951580bdb30SBarry Smith ierr = PetscArraycpy(ctx->work,ax,nl);CHKERRQ(ierr); 1952a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1953a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1954a3df083aSStefano Zampini PetscScalar sum,val; 1955a3df083aSStefano Zampini const PetscInt *idxs; 1956a3df083aSStefano Zampini PetscInt nz,j; 1957a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1958a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1959a3df083aSStefano Zampini sum = 0.; 1960a3df083aSStefano Zampini if (ctx->apply_p0) { 1961a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1962a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1963a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1964a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1965a3df083aSStefano Zampini } 1966a3df083aSStefano Zampini } else { 1967a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1968a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1969a3df083aSStefano Zampini } 1970a3df083aSStefano Zampini } 1971a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1972a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1973a3df083aSStefano Zampini } 1974a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1975a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1976a3df083aSStefano Zampini } 1977a3df083aSStefano Zampini if (transpose) { 1978a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1979a3df083aSStefano Zampini } else { 1980a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1981a3df083aSStefano Zampini } 1982a3df083aSStefano Zampini if (reset_x) { 1983a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1984a3df083aSStefano Zampini } 1985a3df083aSStefano Zampini if (apply_left) { 1986a3df083aSStefano Zampini PetscScalar *ay; 1987a3df083aSStefano Zampini PetscInt i; 1988a3df083aSStefano Zampini 1989a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1990a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1991a3df083aSStefano Zampini PetscScalar sum,val; 1992a3df083aSStefano Zampini const PetscInt *idxs; 1993a3df083aSStefano Zampini PetscInt nz,j; 1994a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1995a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1996a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1997a3df083aSStefano Zampini if (ctx->apply_p0) { 1998a3df083aSStefano Zampini sum = 0.; 1999a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 2000a3df083aSStefano Zampini sum += ay[idxs[j]]; 2001a3df083aSStefano Zampini ay[idxs[j]] += val; 2002a3df083aSStefano Zampini } 2003a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 2004a3df083aSStefano Zampini } else { 2005a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 2006a3df083aSStefano Zampini ay[idxs[j]] += val; 2007a3df083aSStefano Zampini } 2008a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 2009a3df083aSStefano Zampini } 2010a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 2011a3df083aSStefano Zampini } 2012a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 2013a3df083aSStefano Zampini } 2014a3df083aSStefano Zampini PetscFunctionReturn(0); 2015a3df083aSStefano Zampini } 2016a3df083aSStefano Zampini 2017a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 2018a3df083aSStefano Zampini { 2019a3df083aSStefano Zampini PetscErrorCode ierr; 2020a3df083aSStefano Zampini 2021a3df083aSStefano Zampini PetscFunctionBegin; 2022a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 2023a3df083aSStefano Zampini PetscFunctionReturn(0); 2024a3df083aSStefano Zampini } 2025a3df083aSStefano Zampini 2026a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 2027a3df083aSStefano Zampini { 2028a3df083aSStefano Zampini PetscErrorCode ierr; 2029a3df083aSStefano Zampini 2030a3df083aSStefano Zampini PetscFunctionBegin; 2031a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 2032a3df083aSStefano Zampini PetscFunctionReturn(0); 2033a3df083aSStefano Zampini } 2034a3df083aSStefano Zampini 2035a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 2036a3df083aSStefano Zampini { 2037a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2038a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2039a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 2040a3df083aSStefano Zampini PetscErrorCode ierr; 2041a3df083aSStefano Zampini 2042a3df083aSStefano Zampini PetscFunctionBegin; 2043a3df083aSStefano Zampini if (!restore) { 20441dd7afcfSStefano Zampini Mat A_IB,A_BI; 2045a3df083aSStefano Zampini PetscScalar *work; 2046b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 2047a3df083aSStefano Zampini 20489a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 20499a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 2050a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 2051a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 2052a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2053a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 2054a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 2055a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 2056a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 2057a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 2058a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 2059a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 2060a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 2061a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 2062059032f7SStefano Zampini if (reuse) { 2063a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 20641dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 2065059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 2066059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 2067059032f7SStefano Zampini PetscInt i; 2068059032f7SStefano Zampini 2069059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 2070059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2071059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2072059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2073059032f7SStefano Zampini } 2074059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 20751dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 2076059032f7SStefano Zampini } 2077a3df083aSStefano Zampini ctx->A = pcis->A_IB; 2078a3df083aSStefano Zampini ctx->work = work; 2079a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 2080a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2081a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2082a3df083aSStefano Zampini pcis->A_IB = A_IB; 2083a3df083aSStefano Zampini 2084a3df083aSStefano Zampini /* A_BI as A_IB^T */ 2085a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 2086a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 2087a3df083aSStefano Zampini pcis->A_BI = A_BI; 2088a3df083aSStefano Zampini } else { 20891dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 20901dd7afcfSStefano Zampini PetscFunctionReturn(0); 20911dd7afcfSStefano Zampini } 2092a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 2093a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 2094a3df083aSStefano Zampini pcis->A_IB = ctx->A; 20951dd7afcfSStefano Zampini ctx->A = NULL; 20961dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 20971dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 20981dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 20991dd7afcfSStefano Zampini if (ctx->free) { 2100059032f7SStefano Zampini PetscInt i; 21011dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 2102059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2103059032f7SStefano Zampini } 2104059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2105059032f7SStefano Zampini } 2106a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 2107a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 2108a3df083aSStefano Zampini } 2109a3df083aSStefano Zampini PetscFunctionReturn(0); 2110a3df083aSStefano Zampini } 2111a3df083aSStefano Zampini 2112a3df083aSStefano Zampini /* used just in bddc debug mode */ 2113a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 2114a3df083aSStefano Zampini { 2115a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2116a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2117a3df083aSStefano Zampini Mat An; 2118a3df083aSStefano Zampini PetscErrorCode ierr; 2119a3df083aSStefano Zampini 2120a3df083aSStefano Zampini PetscFunctionBegin; 2121a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 2122a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 2123a3df083aSStefano Zampini if (is1) { 21247dae84e0SHong Zhang ierr = MatCreateSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 2125a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 2126a3df083aSStefano Zampini } else { 2127a3df083aSStefano Zampini *B = An; 2128a3df083aSStefano Zampini } 2129a3df083aSStefano Zampini PetscFunctionReturn(0); 2130a3df083aSStefano Zampini } 2131a3df083aSStefano Zampini 21321cf9b237SStefano Zampini /* TODO: add reuse flag */ 21331cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 21341cf9b237SStefano Zampini { 21351cf9b237SStefano Zampini Mat Bt; 21361cf9b237SStefano Zampini PetscScalar *a,*bdata; 21371cf9b237SStefano Zampini const PetscInt *ii,*ij; 21381cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 21391cf9b237SStefano Zampini PetscBool flg_row; 21401cf9b237SStefano Zampini PetscErrorCode ierr; 21411cf9b237SStefano Zampini 21421cf9b237SStefano Zampini PetscFunctionBegin; 21431cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 21441cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 21451cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 21461cf9b237SStefano Zampini nnz = n; 21471cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 21481cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 21491cf9b237SStefano Zampini } 21501cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 21511cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 21521cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 21531cf9b237SStefano Zampini nnz = 0; 21541cf9b237SStefano Zampini bii[0] = 0; 21551cf9b237SStefano Zampini for (i=0;i<n;i++) { 21561cf9b237SStefano Zampini PetscInt j; 21571cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 21581cf9b237SStefano Zampini PetscScalar entry = a[j]; 21593272d46bSStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || (n == m && ij[j] == i)) { 21601cf9b237SStefano Zampini bij[nnz] = ij[j]; 21611cf9b237SStefano Zampini bdata[nnz] = entry; 21621cf9b237SStefano Zampini nnz++; 21631cf9b237SStefano Zampini } 21641cf9b237SStefano Zampini } 21651cf9b237SStefano Zampini bii[i+1] = nnz; 21661cf9b237SStefano Zampini } 21671cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 21681cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 21691cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 21701cf9b237SStefano Zampini { 21711cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 21721cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 21731cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 21741cf9b237SStefano Zampini } 21753272d46bSStefano Zampini if (*B == A) { 21763272d46bSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 21773272d46bSStefano Zampini } 21781cf9b237SStefano Zampini *B = Bt; 21791cf9b237SStefano Zampini PetscFunctionReturn(0); 21801cf9b237SStefano Zampini } 21811cf9b237SStefano Zampini 21828361f951SStefano Zampini PetscErrorCode PCBDDCDetectDisconnectedComponents(PC pc, PetscBool filter, PetscInt *ncc, IS* cc[], IS* primalv) 21834f1b2e48SStefano Zampini { 2184c80a6c00SStefano Zampini Mat B = NULL; 2185c80a6c00SStefano Zampini DM dm; 21864f1b2e48SStefano Zampini IS is_dummy,*cc_n; 21874f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 21884f1b2e48SStefano Zampini PCBDDCGraph graph; 2189c80a6c00SStefano Zampini PetscInt *xadj_filtered = NULL,*adjncy_filtered = NULL; 21904f1b2e48SStefano Zampini PetscInt i,n; 21914f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 2192c80a6c00SStefano Zampini PetscBool isplex = PETSC_FALSE; 21934f1b2e48SStefano Zampini PetscErrorCode ierr; 21944f1b2e48SStefano Zampini 21954f1b2e48SStefano Zampini PetscFunctionBegin; 2196a2eca866SStefano Zampini if (ncc) *ncc = 0; 2197a2eca866SStefano Zampini if (cc) *cc = NULL; 2198a2eca866SStefano Zampini if (primalv) *primalv = NULL; 2199c80a6c00SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 2200c80a6c00SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 22014f819b78SStefano Zampini if (!dm) { 22024f819b78SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 2203c80a6c00SStefano Zampini } 2204c80a6c00SStefano Zampini if (dm) { 2205c80a6c00SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&isplex);CHKERRQ(ierr); 2206c80a6c00SStefano Zampini } 22078361f951SStefano Zampini if (filter) isplex = PETSC_FALSE; 22088361f951SStefano Zampini 2209c80a6c00SStefano Zampini if (isplex) { /* this code has been modified from plexpartition.c */ 2210c80a6c00SStefano Zampini PetscInt p, pStart, pEnd, a, adjSize, idx, size, nroots; 2211c80a6c00SStefano Zampini PetscInt *adj = NULL; 2212c80a6c00SStefano Zampini IS cellNumbering; 2213c80a6c00SStefano Zampini const PetscInt *cellNum; 2214c80a6c00SStefano Zampini PetscBool useCone, useClosure; 2215c80a6c00SStefano Zampini PetscSection section; 2216c80a6c00SStefano Zampini PetscSegBuffer adjBuffer; 2217c80a6c00SStefano Zampini PetscSF sfPoint; 2218c80a6c00SStefano Zampini PetscErrorCode ierr; 2219c80a6c00SStefano Zampini 2220c80a6c00SStefano Zampini PetscFunctionBegin; 2221c80a6c00SStefano Zampini ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 2222c80a6c00SStefano Zampini ierr = DMGetPointSF(dm, &sfPoint);CHKERRQ(ierr); 2223c80a6c00SStefano Zampini ierr = PetscSFGetGraph(sfPoint, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 2224c80a6c00SStefano Zampini /* Build adjacency graph via a section/segbuffer */ 2225c80a6c00SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), §ion);CHKERRQ(ierr); 2226c80a6c00SStefano Zampini ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 2227c80a6c00SStefano Zampini ierr = PetscSegBufferCreate(sizeof(PetscInt),1000,&adjBuffer);CHKERRQ(ierr); 2228c80a6c00SStefano Zampini /* Always use FVM adjacency to create partitioner graph */ 2229b0441da4SMatthew G. Knepley ierr = DMGetBasicAdjacency(dm, &useCone, &useClosure);CHKERRQ(ierr); 2230b0441da4SMatthew G. Knepley ierr = DMSetBasicAdjacency(dm, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr); 2231956e2312SStefano Zampini ierr = DMPlexGetCellNumbering(dm, &cellNumbering);CHKERRQ(ierr); 2232c80a6c00SStefano Zampini ierr = ISGetIndices(cellNumbering, &cellNum);CHKERRQ(ierr); 2233c80a6c00SStefano Zampini for (n = 0, p = pStart; p < pEnd; p++) { 2234c80a6c00SStefano Zampini /* Skip non-owned cells in parallel (ParMetis expects no overlap) */ 2235c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2236c80a6c00SStefano Zampini adjSize = PETSC_DETERMINE; 2237c80a6c00SStefano Zampini ierr = DMPlexGetAdjacency(dm, p, &adjSize, &adj);CHKERRQ(ierr); 2238c80a6c00SStefano Zampini for (a = 0; a < adjSize; ++a) { 2239c80a6c00SStefano Zampini const PetscInt point = adj[a]; 22405cef3d0dSStefano Zampini if (pStart <= point && point < pEnd) { 2241c80a6c00SStefano Zampini PetscInt *PETSC_RESTRICT pBuf; 2242c80a6c00SStefano Zampini ierr = PetscSectionAddDof(section, p, 1);CHKERRQ(ierr); 2243c80a6c00SStefano Zampini ierr = PetscSegBufferGetInts(adjBuffer, 1, &pBuf);CHKERRQ(ierr); 2244c80a6c00SStefano Zampini *pBuf = point; 2245c80a6c00SStefano Zampini } 2246c80a6c00SStefano Zampini } 2247c80a6c00SStefano Zampini n++; 2248c80a6c00SStefano Zampini } 2249b0441da4SMatthew G. Knepley ierr = DMSetBasicAdjacency(dm, useCone, useClosure);CHKERRQ(ierr); 2250c80a6c00SStefano Zampini /* Derive CSR graph from section/segbuffer */ 2251c80a6c00SStefano Zampini ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 2252c80a6c00SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 2253c80a6c00SStefano Zampini ierr = PetscMalloc1(n+1, &xadj);CHKERRQ(ierr); 2254c80a6c00SStefano Zampini for (idx = 0, p = pStart; p < pEnd; p++) { 2255c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2256c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(section, p, &(xadj[idx++]));CHKERRQ(ierr); 2257c80a6c00SStefano Zampini } 2258c80a6c00SStefano Zampini xadj[n] = size; 2259c80a6c00SStefano Zampini ierr = PetscSegBufferExtractAlloc(adjBuffer, &adjncy);CHKERRQ(ierr); 2260c80a6c00SStefano Zampini /* Clean up */ 2261c80a6c00SStefano Zampini ierr = PetscSegBufferDestroy(&adjBuffer);CHKERRQ(ierr); 2262c80a6c00SStefano Zampini ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 2263c80a6c00SStefano Zampini ierr = PetscFree(adj);CHKERRQ(ierr); 2264c80a6c00SStefano Zampini graph->xadj = xadj; 2265c80a6c00SStefano Zampini graph->adjncy = adjncy; 2266c80a6c00SStefano Zampini } else { 2267c80a6c00SStefano Zampini Mat A; 22688361f951SStefano Zampini PetscBool isseqaij, flg_row; 2269c80a6c00SStefano Zampini 2270c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 227163c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 2272a2eca866SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 227363c961adSStefano Zampini PetscFunctionReturn(0); 227463c961adSStefano Zampini } 22757ebab0bbSStefano Zampini ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 22764f1b2e48SStefano Zampini if (!isseqaij && filter) { 22771cf9b237SStefano Zampini PetscBool isseqdense; 22781cf9b237SStefano Zampini 22791cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 22801cf9b237SStefano Zampini if (!isseqdense) { 22814f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 22821cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 22831cf9b237SStefano Zampini PetscScalar *array; 22841cf9b237SStefano Zampini PetscReal chop=1.e-6; 22851cf9b237SStefano Zampini 22861cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 22871cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 22881cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 22891cf9b237SStefano Zampini for (i=0;i<n;i++) { 22901cf9b237SStefano Zampini PetscInt j; 22911cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 22921cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 22931cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 22941cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 22951cf9b237SStefano Zampini } 22961cf9b237SStefano Zampini } 22971cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 22989d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 22991cf9b237SStefano Zampini } 23004f1b2e48SStefano Zampini } else { 2301c80a6c00SStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 23024f1b2e48SStefano Zampini B = A; 23034f1b2e48SStefano Zampini } 23044f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 23054f1b2e48SStefano Zampini 23064f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 23074f1b2e48SStefano Zampini if (filter) { 23084f1b2e48SStefano Zampini PetscScalar *data; 23094f1b2e48SStefano Zampini PetscInt j,cum; 23104f1b2e48SStefano Zampini 23114f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 23124f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 23134f1b2e48SStefano Zampini cum = 0; 23144f1b2e48SStefano Zampini for (i=0;i<n;i++) { 23154f1b2e48SStefano Zampini PetscInt t; 23164f1b2e48SStefano Zampini 23174f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 23184f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 23194f1b2e48SStefano Zampini continue; 23204f1b2e48SStefano Zampini } 23214f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 23224f1b2e48SStefano Zampini } 23234f1b2e48SStefano Zampini t = xadj_filtered[i]; 23244f1b2e48SStefano Zampini xadj_filtered[i] = cum; 23254f1b2e48SStefano Zampini cum += t; 23264f1b2e48SStefano Zampini } 23274f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 23284f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 23294f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 23304f1b2e48SStefano Zampini } else { 23314f1b2e48SStefano Zampini graph->xadj = xadj; 23324f1b2e48SStefano Zampini graph->adjncy = adjncy; 23334f1b2e48SStefano Zampini } 2334c80a6c00SStefano Zampini } 2335c80a6c00SStefano Zampini /* compute local connected components using PCBDDCGraph */ 2336c80a6c00SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 2337c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 2338c80a6c00SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2339c80a6c00SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 2340c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 23414f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 23424f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 2343c80a6c00SStefano Zampini 23444f1b2e48SStefano Zampini /* partial clean up */ 23454f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 2346c80a6c00SStefano Zampini if (B) { 2347c80a6c00SStefano Zampini PetscBool flg_row; 23484f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 23494f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 23504f1b2e48SStefano Zampini } 2351c80a6c00SStefano Zampini if (isplex) { 2352c80a6c00SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 2353c80a6c00SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 2354c80a6c00SStefano Zampini } 23554f1b2e48SStefano Zampini 23564f1b2e48SStefano Zampini /* get back data */ 2357c80a6c00SStefano Zampini if (isplex) { 2358c80a6c00SStefano Zampini if (ncc) *ncc = graph->ncc; 2359c80a6c00SStefano Zampini if (cc || primalv) { 2360c80a6c00SStefano Zampini Mat A; 2361c80a6c00SStefano Zampini PetscBT btv,btvt; 2362c80a6c00SStefano Zampini PetscSection subSection; 2363c80a6c00SStefano Zampini PetscInt *ids,cum,cump,*cids,*pids; 2364c80a6c00SStefano Zampini 2365c80a6c00SStefano Zampini ierr = DMPlexGetSubdomainSection(dm,&subSection);CHKERRQ(ierr); 2366c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 2367c80a6c00SStefano Zampini ierr = PetscMalloc3(A->rmap->n,&ids,graph->ncc+1,&cids,A->rmap->n,&pids);CHKERRQ(ierr); 2368c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btv);CHKERRQ(ierr); 2369c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btvt);CHKERRQ(ierr); 2370c80a6c00SStefano Zampini 2371c80a6c00SStefano Zampini cids[0] = 0; 2372c80a6c00SStefano Zampini for (i = 0, cump = 0, cum = 0; i < graph->ncc; i++) { 2373c80a6c00SStefano Zampini PetscInt j; 2374c80a6c00SStefano Zampini 2375c80a6c00SStefano Zampini ierr = PetscBTMemzero(A->rmap->n,btvt);CHKERRQ(ierr); 2376c80a6c00SStefano Zampini for (j = graph->cptr[i]; j < graph->cptr[i+1]; j++) { 2377c80a6c00SStefano Zampini PetscInt k, size, *closure = NULL, cell = graph->queue[j]; 2378c80a6c00SStefano Zampini 2379c80a6c00SStefano Zampini ierr = DMPlexGetTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2380c80a6c00SStefano Zampini for (k = 0; k < 2*size; k += 2) { 238120c3699dSStefano Zampini PetscInt s, pp, p = closure[k], off, dof, cdof; 2382c80a6c00SStefano Zampini 2383c80a6c00SStefano Zampini ierr = PetscSectionGetConstraintDof(subSection,p,&cdof);CHKERRQ(ierr); 2384c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(subSection,p,&off);CHKERRQ(ierr); 2385c80a6c00SStefano Zampini ierr = PetscSectionGetDof(subSection,p,&dof);CHKERRQ(ierr); 2386c80a6c00SStefano Zampini for (s = 0; s < dof-cdof; s++) { 2387c80a6c00SStefano Zampini if (PetscBTLookupSet(btvt,off+s)) continue; 2388c80a6c00SStefano Zampini if (!PetscBTLookup(btv,off+s)) { 2389c80a6c00SStefano Zampini ids[cum++] = off+s; 2390c80a6c00SStefano Zampini } else { /* cross-vertex */ 2391c80a6c00SStefano Zampini pids[cump++] = off+s; 2392c80a6c00SStefano Zampini } 2393c80a6c00SStefano Zampini } 239420c3699dSStefano Zampini ierr = DMPlexGetTreeParent(dm,p,&pp,NULL);CHKERRQ(ierr); 239520c3699dSStefano Zampini if (pp != p) { 239620c3699dSStefano Zampini ierr = PetscSectionGetConstraintDof(subSection,pp,&cdof);CHKERRQ(ierr); 239720c3699dSStefano Zampini ierr = PetscSectionGetOffset(subSection,pp,&off);CHKERRQ(ierr); 239820c3699dSStefano Zampini ierr = PetscSectionGetDof(subSection,pp,&dof);CHKERRQ(ierr); 239920c3699dSStefano Zampini for (s = 0; s < dof-cdof; s++) { 240020c3699dSStefano Zampini if (PetscBTLookupSet(btvt,off+s)) continue; 240120c3699dSStefano Zampini if (!PetscBTLookup(btv,off+s)) { 240220c3699dSStefano Zampini ids[cum++] = off+s; 240320c3699dSStefano Zampini } else { /* cross-vertex */ 240420c3699dSStefano Zampini pids[cump++] = off+s; 240520c3699dSStefano Zampini } 240620c3699dSStefano Zampini } 240720c3699dSStefano Zampini } 2408c80a6c00SStefano Zampini } 2409c80a6c00SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2410c80a6c00SStefano Zampini } 2411c80a6c00SStefano Zampini cids[i+1] = cum; 2412c80a6c00SStefano Zampini /* mark dofs as already assigned */ 2413c80a6c00SStefano Zampini for (j = cids[i]; j < cids[i+1]; j++) { 2414c80a6c00SStefano Zampini ierr = PetscBTSet(btv,ids[j]);CHKERRQ(ierr); 2415c80a6c00SStefano Zampini } 2416c80a6c00SStefano Zampini } 2417c80a6c00SStefano Zampini if (cc) { 2418c80a6c00SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 2419c80a6c00SStefano Zampini for (i = 0; i < graph->ncc; i++) { 2420c80a6c00SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cids[i+1]-cids[i],ids+cids[i],PETSC_COPY_VALUES,&cc_n[i]);CHKERRQ(ierr); 2421c80a6c00SStefano Zampini } 2422c80a6c00SStefano Zampini *cc = cc_n; 2423c80a6c00SStefano Zampini } 2424c80a6c00SStefano Zampini if (primalv) { 2425c80a6c00SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),cump,pids,PETSC_COPY_VALUES,primalv);CHKERRQ(ierr); 2426c80a6c00SStefano Zampini } 2427c80a6c00SStefano Zampini ierr = PetscFree3(ids,cids,pids);CHKERRQ(ierr); 2428c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 2429c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btvt);CHKERRQ(ierr); 2430c80a6c00SStefano Zampini } 2431c80a6c00SStefano Zampini } else { 24321cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 24331cf9b237SStefano Zampini if (cc) { 24344f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 24354f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 24364f1b2e48SStefano 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); 24374f1b2e48SStefano Zampini } 24384f1b2e48SStefano Zampini *cc = cc_n; 24391cf9b237SStefano Zampini } 2440c80a6c00SStefano Zampini } 24414f1b2e48SStefano Zampini /* clean up graph */ 24424f1b2e48SStefano Zampini graph->xadj = 0; 24434f1b2e48SStefano Zampini graph->adjncy = 0; 24444f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 24454f1b2e48SStefano Zampini PetscFunctionReturn(0); 24464f1b2e48SStefano Zampini } 24474f1b2e48SStefano Zampini 24485408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 24495408967cSStefano Zampini { 24505408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 24515408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2452dee84bffSStefano Zampini IS dirIS = NULL; 24534f1b2e48SStefano Zampini PetscInt i; 24545408967cSStefano Zampini PetscErrorCode ierr; 24555408967cSStefano Zampini 24565408967cSStefano Zampini PetscFunctionBegin; 2457dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 24585408967cSStefano Zampini if (zerodiag) { 24595408967cSStefano Zampini Mat A; 24605408967cSStefano Zampini Vec vec3_N; 24615408967cSStefano Zampini PetscScalar *vals; 24625408967cSStefano Zampini const PetscInt *idxs; 2463d12d3064SStefano Zampini PetscInt nz,*count; 24645408967cSStefano Zampini 24655408967cSStefano Zampini /* p0 */ 24665408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 24675408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 24685408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 24695408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 24704f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 24715408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24725408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 24735408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 24745408967cSStefano Zampini /* v_I */ 24755408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 24765408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 24775408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24785408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 24795408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24805408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 24815408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24825408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24835408967cSStefano Zampini if (dirIS) { 24845408967cSStefano Zampini PetscInt n; 24855408967cSStefano Zampini 24865408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 24875408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 24885408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 24895408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24905408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 24915408967cSStefano Zampini } 24925408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 24935408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 24945408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 24955408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2496669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 24975408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 24985408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 24999a962809SStefano 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])); 25005408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 25015408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2502d12d3064SStefano Zampini 2503d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2504d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2505d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2506d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2507d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2508d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 25096080607fSStefano 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]); 2510d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2511d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 25125408967cSStefano Zampini } 2513dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 25145408967cSStefano Zampini 25155408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 25165408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 25174f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 25185408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 25194f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 25205408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2521f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2522f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 25236080607fSStefano 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); 2524f2a566d8SStefano Zampini } 25255408967cSStefano Zampini PetscFunctionReturn(0); 25265408967cSStefano Zampini } 25275408967cSStefano Zampini 25283b03f7bbSStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, PetscBool reuse, IS *zerodiaglocal) 2529339f8db1SStefano Zampini { 2530339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 25313b03f7bbSStefano Zampini IS pressures = NULL,zerodiag = NULL,*bzerodiag = NULL,zerodiag_save,*zerodiag_subs; 25323b03f7bbSStefano Zampini PetscInt nz,n,benign_n,bsp = 1; 25334edc6404Sstefano_zampini PetscInt *interior_dofs,n_interior_dofs,nneu; 25344edc6404Sstefano_zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag,checkb; 2535339f8db1SStefano Zampini PetscErrorCode ierr; 2536339f8db1SStefano Zampini 2537339f8db1SStefano Zampini PetscFunctionBegin; 25383b03f7bbSStefano Zampini if (reuse) goto project_b0; 25399f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 25409f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2541a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2542a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2543a3df083aSStefano Zampini } 2544a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 25453b03f7bbSStefano Zampini has_null_pressures = PETSC_TRUE; 25463b03f7bbSStefano Zampini have_null = PETSC_TRUE; 25473b03f7bbSStefano Zampini /* if a local information on dofs is present, gets pressure dofs from command line (uses the last field is not provided) 25483b03f7bbSStefano Zampini Without local information, it uses only the zerodiagonal dofs (ok if the pressure block is all zero and it is a scalar field) 25494f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 25504f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 25511ae86dd6SStefano Zampini since the local Schur complements are already SPD 25524f1b2e48SStefano Zampini */ 255340fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 25547fbe2174Sstefano_zampini IS iP = NULL; 25553b03f7bbSStefano Zampini PetscInt p,*pp; 25563b03f7bbSStefano Zampini PetscBool flg; 25574f1b2e48SStefano Zampini 25583b03f7bbSStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pp);CHKERRQ(ierr); 25593b03f7bbSStefano Zampini n = pcbddc->n_ISForDofsLocal; 256028b8efb1Sstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC benign options","PC");CHKERRQ(ierr); 25613b03f7bbSStefano Zampini ierr = PetscOptionsIntArray("-pc_bddc_pressure_field","Field id for pressures",NULL,pp,&n,&flg);CHKERRQ(ierr); 256228b8efb1Sstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 25633b03f7bbSStefano Zampini if (!flg) { 25643b03f7bbSStefano Zampini n = 1; 25653b03f7bbSStefano Zampini pp[0] = pcbddc->n_ISForDofsLocal-1; 25663b03f7bbSStefano Zampini } 25673b03f7bbSStefano Zampini 25683b03f7bbSStefano Zampini bsp = 0; 25693b03f7bbSStefano Zampini for (p=0;p<n;p++) { 25703b03f7bbSStefano Zampini PetscInt bs; 25713b03f7bbSStefano Zampini 25723b03f7bbSStefano 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]); 25733b03f7bbSStefano Zampini ierr = ISGetBlockSize(pcbddc->ISForDofsLocal[pp[p]],&bs);CHKERRQ(ierr); 25743b03f7bbSStefano Zampini bsp += bs; 25753b03f7bbSStefano Zampini } 25763b03f7bbSStefano Zampini ierr = PetscMalloc1(bsp,&bzerodiag);CHKERRQ(ierr); 25773b03f7bbSStefano Zampini bsp = 0; 25783b03f7bbSStefano Zampini for (p=0;p<n;p++) { 25793b03f7bbSStefano Zampini const PetscInt *idxs; 25803b03f7bbSStefano Zampini PetscInt b,bs,npl,*bidxs; 25813b03f7bbSStefano Zampini 25823b03f7bbSStefano Zampini ierr = ISGetBlockSize(pcbddc->ISForDofsLocal[pp[p]],&bs);CHKERRQ(ierr); 25833b03f7bbSStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[pp[p]],&npl);CHKERRQ(ierr); 25843b03f7bbSStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[pp[p]],&idxs);CHKERRQ(ierr); 25853b03f7bbSStefano Zampini ierr = PetscMalloc1(npl/bs,&bidxs);CHKERRQ(ierr); 25863b03f7bbSStefano Zampini for (b=0;b<bs;b++) { 25873b03f7bbSStefano Zampini PetscInt i; 25883b03f7bbSStefano Zampini 25893b03f7bbSStefano Zampini for (i=0;i<npl/bs;i++) bidxs[i] = idxs[bs*i+b]; 25903b03f7bbSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl/bs,bidxs,PETSC_COPY_VALUES,&bzerodiag[bsp]);CHKERRQ(ierr); 25913b03f7bbSStefano Zampini bsp++; 25923b03f7bbSStefano Zampini } 25933b03f7bbSStefano Zampini ierr = PetscFree(bidxs);CHKERRQ(ierr); 25943b03f7bbSStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[pp[p]],&idxs);CHKERRQ(ierr); 25953b03f7bbSStefano Zampini } 25963b03f7bbSStefano Zampini ierr = ISConcatenate(PETSC_COMM_SELF,bsp,bzerodiag,&pressures);CHKERRQ(ierr); 25973b03f7bbSStefano Zampini 25987fbe2174Sstefano_zampini /* remove zeroed out pressures if we are setting up a BDDC solver for a saddle-point FETI-DP */ 25997fbe2174Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP",(PetscObject*)&iP);CHKERRQ(ierr); 26007fbe2174Sstefano_zampini if (iP) { 26017fbe2174Sstefano_zampini IS newpressures; 26027fbe2174Sstefano_zampini 26037fbe2174Sstefano_zampini ierr = ISDifference(pressures,iP,&newpressures);CHKERRQ(ierr); 26047fbe2174Sstefano_zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 26057fbe2174Sstefano_zampini pressures = newpressures; 26067fbe2174Sstefano_zampini } 260740fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 260840fa8d13SStefano Zampini if (!sorted) { 260940fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 261040fa8d13SStefano Zampini } 26113b03f7bbSStefano Zampini ierr = PetscFree(pp);CHKERRQ(ierr); 261240fa8d13SStefano Zampini } 26133b03f7bbSStefano Zampini 261497d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 261597d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 261627b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 261797d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2618339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2619339f8db1SStefano Zampini if (!sorted) { 2620339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2621339f8db1SStefano Zampini } 26224edc6404Sstefano_zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 26234edc6404Sstefano_zampini zerodiag_save = zerodiag; 2624339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 26254f1b2e48SStefano Zampini if (!nz) { 26264f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 26274f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 262840fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 262940fa8d13SStefano Zampini } 26304f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 26313b03f7bbSStefano Zampini 26324f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 26334f1b2e48SStefano Zampini zerodiag_subs = NULL; 26343b03f7bbSStefano Zampini benign_n = 0; 26351f4df5f7SStefano Zampini n_interior_dofs = 0; 26361f4df5f7SStefano Zampini interior_dofs = NULL; 26374edc6404Sstefano_zampini nneu = 0; 26384edc6404Sstefano_zampini if (pcbddc->NeumannBoundariesLocal) { 26394edc6404Sstefano_zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nneu);CHKERRQ(ierr); 26404edc6404Sstefano_zampini } 26413369cb78Sstefano_zampini checkb = (PetscBool)(!pcbddc->NeumannBoundariesLocal || pcbddc->current_level); 26424edc6404Sstefano_zampini if (checkb) { /* need to compute interior nodes */ 26431f4df5f7SStefano Zampini PetscInt n,i,j; 26441f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 26451f4df5f7SStefano Zampini PetscInt *iwork; 26461f4df5f7SStefano Zampini 26471f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 26481f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 26491f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 26501f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 265190648384SStefano Zampini for (i=1;i<n_neigh;i++) 26521f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 26531f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 26541f4df5f7SStefano Zampini for (i=0;i<n;i++) 26551f4df5f7SStefano Zampini if (!iwork[i]) 26561f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 26571f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 26581f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 26591f4df5f7SStefano Zampini } 26604f1b2e48SStefano Zampini if (has_null_pressures) { 26614f1b2e48SStefano Zampini IS *subs; 26624edc6404Sstefano_zampini PetscInt nsubs,i,j,nl; 26631f4df5f7SStefano Zampini const PetscInt *idxs; 26641f4df5f7SStefano Zampini PetscScalar *array; 26651f4df5f7SStefano Zampini Vec *work; 26661f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 26674f1b2e48SStefano Zampini 26684f1b2e48SStefano Zampini subs = pcbddc->local_subs; 26694f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 26701f4df5f7SStefano 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) */ 26714edc6404Sstefano_zampini if (checkb) { 26721f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 26731f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 26741f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 26751f4df5f7SStefano Zampini /* work[0] = 1_p */ 26761f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 26771f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 26781f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 26791f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 26801f4df5f7SStefano Zampini /* work[0] = 1_v */ 26811f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 26821f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 26831f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 26841f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 26851f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 26861f4df5f7SStefano Zampini } 26873b03f7bbSStefano Zampini 26883b03f7bbSStefano Zampini if (nsubs > 1 || bsp > 1) { 26893b03f7bbSStefano Zampini IS *is; 26903b03f7bbSStefano Zampini PetscInt b,totb; 26913b03f7bbSStefano Zampini 26923b03f7bbSStefano Zampini totb = bsp; 26933b03f7bbSStefano Zampini is = bsp > 1 ? bzerodiag : &zerodiag; 26943b03f7bbSStefano Zampini nsubs = PetscMax(nsubs,1); 26953b03f7bbSStefano Zampini ierr = PetscCalloc1(nsubs*totb,&zerodiag_subs);CHKERRQ(ierr); 26963b03f7bbSStefano Zampini for (b=0;b<totb;b++) { 26974f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 26984f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 26994f1b2e48SStefano Zampini IS t_zerodiag_subs; 27004f1b2e48SStefano Zampini PetscInt nl; 27014f1b2e48SStefano Zampini 27023b03f7bbSStefano Zampini if (subs) { 27034f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 27043b03f7bbSStefano Zampini } else { 27053b03f7bbSStefano Zampini IS tis; 27063b03f7bbSStefano Zampini 27073b03f7bbSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&nl,NULL);CHKERRQ(ierr); 27083b03f7bbSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nl,0,1,&tis);CHKERRQ(ierr); 27093b03f7bbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(tis,&l2g);CHKERRQ(ierr); 27103b03f7bbSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 27113b03f7bbSStefano Zampini } 27123b03f7bbSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,is[b],&t_zerodiag_subs);CHKERRQ(ierr); 27134f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 27144f1b2e48SStefano Zampini if (nl) { 27154f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 27164f1b2e48SStefano Zampini 27174edc6404Sstefano_zampini if (checkb) { 27181f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 27191f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 27201f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 27211f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 27221f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 27231f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 27241f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 27251f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 27261f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 27271f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 27281f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 27291f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 27301f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 27311f4df5f7SStefano Zampini valid = PETSC_FALSE; 27321f4df5f7SStefano Zampini break; 27331f4df5f7SStefano Zampini } 27341f4df5f7SStefano Zampini } 27351f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 27361f4df5f7SStefano Zampini } 27376632bad2Sstefano_zampini if (valid && nneu) { 27386632bad2Sstefano_zampini const PetscInt *idxs; 27391f4df5f7SStefano Zampini PetscInt nzb; 27401f4df5f7SStefano Zampini 27416632bad2Sstefano_zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 27426632bad2Sstefano_zampini ierr = ISGlobalToLocalMappingApply(l2g,IS_GTOLM_DROP,nneu,idxs,&nzb,NULL);CHKERRQ(ierr); 27436632bad2Sstefano_zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 27441f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 27451f4df5f7SStefano Zampini } 27461f4df5f7SStefano Zampini if (valid && pressures) { 27473b03f7bbSStefano Zampini IS t_pressure_subs,tmp; 27483b03f7bbSStefano Zampini PetscInt i1,i2; 27493b03f7bbSStefano Zampini 27504f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 27513b03f7bbSStefano Zampini ierr = ISEmbed(t_zerodiag_subs,t_pressure_subs,PETSC_TRUE,&tmp);CHKERRQ(ierr); 27523b03f7bbSStefano Zampini ierr = ISGetLocalSize(tmp,&i1);CHKERRQ(ierr); 27533b03f7bbSStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&i2);CHKERRQ(ierr); 27543b03f7bbSStefano Zampini if (i2 != i1) valid = PETSC_FALSE; 27554f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 27563b03f7bbSStefano Zampini ierr = ISDestroy(&tmp);CHKERRQ(ierr); 27574f1b2e48SStefano Zampini } 27584f1b2e48SStefano Zampini if (valid) { 27593b03f7bbSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[benign_n]);CHKERRQ(ierr); 27603b03f7bbSStefano Zampini benign_n++; 27613b03f7bbSStefano Zampini } else recompute_zerodiag = PETSC_TRUE; 27624f1b2e48SStefano Zampini } 27634f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 27644f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 27654f1b2e48SStefano Zampini } 27663b03f7bbSStefano Zampini } 27674f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 27684f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 27691f4df5f7SStefano Zampini 27706632bad2Sstefano_zampini if (nneu) valid = PETSC_FALSE; 27711f4df5f7SStefano Zampini if (valid && pressures) { 27724f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 27734f1b2e48SStefano Zampini } 27744edc6404Sstefano_zampini if (valid && checkb) { 27751f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 27761f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 27771f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 27781f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 27791f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 27801f4df5f7SStefano Zampini valid = PETSC_FALSE; 27811f4df5f7SStefano Zampini break; 27821f4df5f7SStefano Zampini } 27831f4df5f7SStefano Zampini } 27841f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 27851f4df5f7SStefano Zampini } 27864f1b2e48SStefano Zampini if (valid) { 27873b03f7bbSStefano Zampini benign_n = 1; 27883b03f7bbSStefano Zampini ierr = PetscMalloc1(benign_n,&zerodiag_subs);CHKERRQ(ierr); 27894f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 27904f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 27914f1b2e48SStefano Zampini } 27924f1b2e48SStefano Zampini } 27934edc6404Sstefano_zampini if (checkb) { 27941f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 27954f1b2e48SStefano Zampini } 27961f4df5f7SStefano Zampini } 27971f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 27984f1b2e48SStefano Zampini 27993b03f7bbSStefano Zampini if (!benign_n) { 2800b9b0e38cSStefano Zampini PetscInt n; 2801b9b0e38cSStefano Zampini 28024f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 28034f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2804b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 280576a58201SStefano Zampini if (n) have_null = PETSC_FALSE; 2806b9b0e38cSStefano Zampini } 28074f1b2e48SStefano Zampini 28084f1b2e48SStefano Zampini /* final check for null pressures */ 28094f1b2e48SStefano Zampini if (zerodiag && pressures) { 28103b03f7bbSStefano Zampini ierr = ISEqual(pressures,zerodiag,&have_null);CHKERRQ(ierr); 28114f1b2e48SStefano Zampini } 28124f1b2e48SStefano Zampini 28134f1b2e48SStefano Zampini if (recompute_zerodiag) { 28144f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 28153b03f7bbSStefano Zampini if (benign_n == 1) { 28164f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 28174f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 28184f1b2e48SStefano Zampini } else { 28194f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 28204f1b2e48SStefano Zampini 28214f1b2e48SStefano Zampini nzn = 0; 28223b03f7bbSStefano Zampini for (i=0;i<benign_n;i++) { 28234f1b2e48SStefano Zampini PetscInt ns; 28244f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 28254f1b2e48SStefano Zampini nzn += ns; 28264f1b2e48SStefano Zampini } 28274f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 28284f1b2e48SStefano Zampini nzn = 0; 28293b03f7bbSStefano Zampini for (i=0;i<benign_n;i++) { 28304f1b2e48SStefano Zampini PetscInt ns,*idxs; 28314f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 28324f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2833580bdb30SBarry Smith ierr = PetscArraycpy(new_idxs+nzn,idxs,ns);CHKERRQ(ierr); 28344f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 28354f1b2e48SStefano Zampini nzn += ns; 28364f1b2e48SStefano Zampini } 28374f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 28384f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 28394f1b2e48SStefano Zampini } 28404f1b2e48SStefano Zampini have_null = PETSC_FALSE; 28414f1b2e48SStefano Zampini } 28424f1b2e48SStefano Zampini 28433b03f7bbSStefano Zampini /* determines if the coarse solver will be singular or not */ 28443b03f7bbSStefano Zampini ierr = MPIU_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 28453b03f7bbSStefano Zampini 2846669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2847a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2848a198735bSStefano Zampini Mat A,loc_divudotp; 2849a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2850a198735bSStefano Zampini IS row,col,isused = NULL; 2851a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2852a198735bSStefano Zampini 28531f4df5f7SStefano Zampini if (pressures) { 28541f4df5f7SStefano Zampini isused = pressures; 28551f4df5f7SStefano Zampini } else { 28564edc6404Sstefano_zampini isused = zerodiag_save; 28571f4df5f7SStefano Zampini } 2858a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2859669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 28601ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 28611ae86dd6SStefano 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"); 2862a198735bSStefano Zampini n_isused = 0; 2863a198735bSStefano Zampini if (isused) { 2864a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2865a198735bSStefano Zampini } 2866a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2867a198735bSStefano Zampini st = st-n_isused; 28681ae86dd6SStefano Zampini if (n) { 2869a198735bSStefano Zampini const PetscInt *gidxs; 2870a198735bSStefano Zampini 28717dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2872a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2873a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2874a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2875a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2876a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 28771ae86dd6SStefano Zampini } else { 2878a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2879a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2880a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2881a198735bSStefano Zampini } 2882a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2883a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2884a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2885a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2886a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2887a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2888a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2889a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2890a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2891a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2892a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2893a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2894a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2895a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 28961ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28971ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28981ae86dd6SStefano Zampini } 28994edc6404Sstefano_zampini ierr = ISDestroy(&zerodiag_save);CHKERRQ(ierr); 29003b03f7bbSStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 29013b03f7bbSStefano Zampini if (bzerodiag) { 29023b03f7bbSStefano Zampini PetscInt i; 2903b3afcdbeSStefano Zampini 29043b03f7bbSStefano Zampini for (i=0;i<bsp;i++) { 29053b03f7bbSStefano Zampini ierr = ISDestroy(&bzerodiag[i]);CHKERRQ(ierr); 29063b03f7bbSStefano Zampini } 29073b03f7bbSStefano Zampini ierr = PetscFree(bzerodiag);CHKERRQ(ierr); 29083b03f7bbSStefano Zampini } 29093b03f7bbSStefano Zampini pcbddc->benign_n = benign_n; 29103b03f7bbSStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 29113b03f7bbSStefano Zampini 29123b03f7bbSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 29133b03f7bbSStefano Zampini have_null = (PetscBool)(!!pcbddc->benign_n); 29143b03f7bbSStefano Zampini ierr = MPIU_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 29153b03f7bbSStefano Zampini 29163b03f7bbSStefano Zampini project_b0: 2917aa0d93e9SStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2918b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 29193b03f7bbSStefano Zampini if (pcbddc->benign_n) { 29204f1b2e48SStefano Zampini PetscInt i,s,*nnz; 29214f1b2e48SStefano Zampini 2922339f8db1SStefano Zampini /* local change of basis for pressures */ 2923339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 292497d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2925339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2926339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2927339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 2928aa0d93e9SStefano Zampini for (i=0;i<n;i++) nnz[i] = 1; /* defaults to identity */ 29294f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2930aa0d93e9SStefano Zampini const PetscInt *idxs; 29314f1b2e48SStefano Zampini PetscInt nzs,j; 29324f1b2e48SStefano Zampini 29333b03f7bbSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nzs);CHKERRQ(ierr); 29343b03f7bbSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 29354f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 29364f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 29373b03f7bbSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 29384f1b2e48SStefano Zampini } 2939339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2940e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->benign_change,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 2941339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2942aa0d93e9SStefano Zampini /* set identity by default */ 2943aa0d93e9SStefano Zampini for (i=0;i<n;i++) { 2944aa0d93e9SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,i,i,1.,INSERT_VALUES);CHKERRQ(ierr); 2945339f8db1SStefano Zampini } 29469f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 29474f1b2e48SStefano 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); 2948339f8db1SStefano Zampini /* set change on pressures */ 29494f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 29504f1b2e48SStefano Zampini PetscScalar *array; 2951aa0d93e9SStefano Zampini const PetscInt *idxs; 29524f1b2e48SStefano Zampini PetscInt nzs; 29534f1b2e48SStefano Zampini 29543b03f7bbSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[s],&nzs);CHKERRQ(ierr); 29553b03f7bbSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[s],&idxs);CHKERRQ(ierr); 29564f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2957339f8db1SStefano Zampini PetscScalar vals[2]; 2958339f8db1SStefano Zampini PetscInt cols[2]; 2959339f8db1SStefano Zampini 2960339f8db1SStefano Zampini cols[0] = idxs[i]; 29614f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2962339f8db1SStefano Zampini vals[0] = 1.; 2963b0f5fe93SStefano Zampini vals[1] = 1.; 29644f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2965339f8db1SStefano Zampini } 29664f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 29674f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 29684f1b2e48SStefano Zampini array[nzs-1] = 1.; 29694f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 29704f1b2e48SStefano Zampini /* store local idxs for p0 */ 29714f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 29723b03f7bbSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2973339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 29744f1b2e48SStefano Zampini } 2975339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2976339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 29773b03f7bbSStefano Zampini 2978a3df083aSStefano Zampini /* project if needed */ 2979a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 29801dd7afcfSStefano Zampini Mat M; 29811dd7afcfSStefano Zampini 29821dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2983339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 29841dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 29851dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2986a3df083aSStefano Zampini } 29874f1b2e48SStefano Zampini /* store global idxs for p0 */ 29884f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2989339f8db1SStefano Zampini } 2990339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2991339f8db1SStefano Zampini PetscFunctionReturn(0); 2992339f8db1SStefano Zampini } 2993339f8db1SStefano Zampini 2994015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2995efc2fbd9SStefano Zampini { 2996efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2997de9d7bd0SStefano Zampini PetscScalar *array; 2998efc2fbd9SStefano Zampini PetscErrorCode ierr; 2999efc2fbd9SStefano Zampini 3000efc2fbd9SStefano Zampini PetscFunctionBegin; 3001efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 3002efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 30034f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 3004efc2fbd9SStefano Zampini } 3005de9d7bd0SStefano Zampini if (get) { 3006efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 30074f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 30084f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 3009efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 3010de9d7bd0SStefano Zampini } else { 3011de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 3012de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 3013de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 3014de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 3015efc2fbd9SStefano Zampini } 3016efc2fbd9SStefano Zampini PetscFunctionReturn(0); 3017efc2fbd9SStefano Zampini } 3018efc2fbd9SStefano Zampini 3019c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 3020c263805aSStefano Zampini { 3021c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3022c263805aSStefano Zampini PetscErrorCode ierr; 3023c263805aSStefano Zampini 3024c263805aSStefano Zampini PetscFunctionBegin; 3025c263805aSStefano Zampini /* TODO: add error checking 3026c263805aSStefano Zampini - avoid nested pop (or push) calls. 3027c263805aSStefano Zampini - cannot push before pop. 30281c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 3029c263805aSStefano Zampini */ 30304f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 3031efc2fbd9SStefano Zampini PetscFunctionReturn(0); 3032efc2fbd9SStefano Zampini } 3033c263805aSStefano Zampini if (pop) { 3034a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 30354f1b2e48SStefano Zampini IS is_p0; 30364f1b2e48SStefano Zampini MatReuse reuse; 3037c263805aSStefano Zampini 3038c263805aSStefano Zampini /* extract B_0 */ 30394f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 30404f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 30414f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 30424f1b2e48SStefano Zampini } 30434f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 30447dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 3045c263805aSStefano Zampini /* remove rows and cols from local problem */ 3046c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 304797d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 30484f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 30494f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 3050a3df083aSStefano Zampini } else { 3051a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 3052a3df083aSStefano Zampini PetscScalar *vals; 3053a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 3054a3df083aSStefano Zampini 3055a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 3056a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 3057a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 30580b5adadeSStefano Zampini PetscInt *nnz; 3059a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 3060a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 3061a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 3062331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 3063331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3064331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 3065331e053bSStefano Zampini nnz[i] = n - nnz[i]; 3066331e053bSStefano Zampini } 3067331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 3068e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->benign_B0,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3069331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3070331e053bSStefano Zampini } 3071a3df083aSStefano Zampini 3072a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3073a3df083aSStefano Zampini PetscScalar *array; 3074a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 3075a3df083aSStefano Zampini 3076a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 3077a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3078a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 3079a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 3080a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 3081a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 3082a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 3083a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 3084a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 3085a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 3086a3df083aSStefano Zampini cum = 0; 3087a3df083aSStefano Zampini for (j=0;j<n;j++) { 308822db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 3089a3df083aSStefano Zampini vals[cum] = array[j]; 3090a3df083aSStefano Zampini idxs_ins[cum] = j; 3091a3df083aSStefano Zampini cum++; 3092a3df083aSStefano Zampini } 3093a3df083aSStefano Zampini } 3094a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 3095a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 3096a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 3097a3df083aSStefano Zampini } 3098a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3099a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3100a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 3101a3df083aSStefano Zampini } 3102c263805aSStefano Zampini } else { /* push */ 3103a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 31044f1b2e48SStefano Zampini PetscInt i; 31054f1b2e48SStefano Zampini 31064f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 31074f1b2e48SStefano Zampini PetscScalar *B0_vals; 31084f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 31094f1b2e48SStefano Zampini 31104f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 31114f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 31127b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 31134f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 31144f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 31154f1b2e48SStefano Zampini } 3116c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3117c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 31186080607fSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!"); 3119c263805aSStefano Zampini } 3120c263805aSStefano Zampini PetscFunctionReturn(0); 3121c263805aSStefano Zampini } 3122c263805aSStefano Zampini 312308122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 3124b1b3d7a2SStefano Zampini { 3125b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 312608122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 312708122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 312808122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 312908122e43SStefano Zampini PetscScalar *work,lwork; 313008122e43SStefano Zampini PetscScalar *St,*S,*eigv; 313108122e43SStefano Zampini PetscScalar *Sarray,*Starray; 3132bd2a564bSStefano Zampini PetscReal *eigs,thresh,lthresh,uthresh; 31331b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 3134f6f667cfSStefano Zampini PetscBool allocated_S_St; 313508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 313608122e43SStefano Zampini PetscReal *rwork; 313708122e43SStefano Zampini #endif 3138b1b3d7a2SStefano Zampini PetscErrorCode ierr; 3139b1b3d7a2SStefano Zampini 3140b1b3d7a2SStefano Zampini PetscFunctionBegin; 3141b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 3142af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 3143bd2a564bSStefano 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); 314443371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_AdaptiveSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 314506a4e24aSStefano Zampini 3146fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3147fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3148fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3149fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 31501575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3151fd14bc51SStefano Zampini } 3152fd14bc51SStefano Zampini 3153e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 31546080607fSStefano 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); 3155e496cd5dSStefano Zampini } 3156e496cd5dSStefano Zampini 315708122e43SStefano Zampini /* max size of subsets */ 315808122e43SStefano Zampini mss = 0; 315908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 316008122e43SStefano Zampini PetscInt subset_size; 3161862806e4SStefano Zampini 316208122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 316308122e43SStefano Zampini mss = PetscMax(mss,subset_size); 316408122e43SStefano Zampini } 316508122e43SStefano Zampini 316608122e43SStefano Zampini /* min/max and threshold */ 316708122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 3168f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 316908122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 3170f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 3171bd2a564bSStefano Zampini if (nmin || !sub_schurs->is_posdef) { /* XXX */ 3172f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 3173f6f667cfSStefano Zampini } 317408122e43SStefano Zampini 317508122e43SStefano Zampini /* allocate lapack workspace */ 317608122e43SStefano Zampini cum = cum2 = 0; 317708122e43SStefano Zampini maxneigs = 0; 317808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 317908122e43SStefano Zampini PetscInt n,subset_size; 3180f6f667cfSStefano Zampini 318108122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 318208122e43SStefano Zampini n = PetscMin(subset_size,nmax); 31839162d606SStefano Zampini cum += subset_size; 31849162d606SStefano Zampini cum2 += subset_size*n; 318508122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 318608122e43SStefano Zampini } 31877ebab0bbSStefano Zampini lwork = 0; 318808122e43SStefano Zampini if (mss) { 3189bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 31907ebab0bbSStefano Zampini PetscScalar sdummy = 0.; 319108122e43SStefano Zampini PetscBLASInt B_itype = 1; 31927ebab0bbSStefano Zampini PetscBLASInt B_N = mss, idummy = 0; 31937ebab0bbSStefano Zampini PetscReal rdummy = 0.,zero = 0.0; 31944c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 319508122e43SStefano Zampini 319608122e43SStefano Zampini B_lwork = -1; 31977ebab0bbSStefano Zampini /* some implementations may complain about NULL pointers, even if we are querying */ 31987ebab0bbSStefano Zampini S = &sdummy; 31997ebab0bbSStefano Zampini St = &sdummy; 32007ebab0bbSStefano Zampini eigs = &rdummy; 32017ebab0bbSStefano Zampini eigv = &sdummy; 32027ebab0bbSStefano Zampini B_iwork = &idummy; 32037ebab0bbSStefano Zampini B_ifail = &idummy; 3204d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 32057ebab0bbSStefano Zampini rwork = &rdummy; 3206d1710679SStefano Zampini #endif 32078bec7fa6SStefano Zampini thresh = 1.0; 320808122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 320908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 321008122e43SStefano 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)); 321108122e43SStefano Zampini #else 321208122e43SStefano 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)); 321308122e43SStefano Zampini #endif 321408122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 321508122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3216bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 321708122e43SStefano Zampini } 321808122e43SStefano Zampini 321908122e43SStefano Zampini nv = 0; 3220d62866d3SStefano 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) */ 3221d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 322208122e43SStefano Zampini } 32234c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 3224f6f667cfSStefano Zampini if (allocated_S_St) { 3225f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 3226f6f667cfSStefano Zampini } 3227f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 322808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 322908122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 323008122e43SStefano Zampini #endif 32319162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 32329162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 32339162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 323408122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 32359162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 3236580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->adaptive_constraints_n,nv+sub_schurs->n_subs);CHKERRQ(ierr); 323708122e43SStefano Zampini 323808122e43SStefano Zampini maxneigs = 0; 323972b8c272SStefano Zampini cum = cumarray = 0; 32409162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 32419162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 3242d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 324308122e43SStefano Zampini const PetscInt *idxs; 324408122e43SStefano Zampini 3245d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 324608122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 324708122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 324808122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 324908122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 32509162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 32519162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 325208122e43SStefano Zampini } 3253d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 325408122e43SStefano Zampini } 325508122e43SStefano Zampini 325608122e43SStefano Zampini if (mss) { /* multilevel */ 325708122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 325808122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 325908122e43SStefano Zampini } 326008122e43SStefano Zampini 3261bd2a564bSStefano Zampini lthresh = pcbddc->adaptive_threshold[0]; 3262bd2a564bSStefano Zampini uthresh = pcbddc->adaptive_threshold[1]; 326308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 326408122e43SStefano Zampini const PetscInt *idxs; 32659d54b7f4SStefano Zampini PetscReal upper,lower; 3266862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 326708122e43SStefano Zampini PetscBLASInt B_N; 3268aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 3269bd2a564bSStefano Zampini PetscBool scal = PETSC_FALSE; 327008122e43SStefano Zampini 32719d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 32729d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 3273bd2a564bSStefano Zampini lower = uthresh; 32749d54b7f4SStefano Zampini } else { 3275bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented without deluxe scaling"); 3276bd2a564bSStefano Zampini upper = 1./uthresh; 32779d54b7f4SStefano Zampini lower = 0.; 32789d54b7f4SStefano Zampini } 3279862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 3280ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 3281f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 3282bd2a564bSStefano Zampini /* this is experimental: we assume the dofs have been properly grouped to have 3283bd2a564bSStefano Zampini the diagonal blocks Schur complements either positive or negative definite (true for Stokes) */ 3284bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) { 3285bd2a564bSStefano Zampini Mat T; 3286bd2a564bSStefano Zampini 3287bd2a564bSStefano Zampini for (j=0;j<subset_size;j++) { 3288bd2a564bSStefano Zampini if (PetscRealPart(*(Sarray+cumarray+j*(subset_size+1))) < 0.0) { 3289bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Sarray+cumarray,&T);CHKERRQ(ierr); 3290bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3291bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3292bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Starray+cumarray,&T);CHKERRQ(ierr); 3293bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3294bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3295bd2a564bSStefano Zampini if (sub_schurs->change_primal_sub) { 3296bd2a564bSStefano Zampini PetscInt nz,k; 3297bd2a564bSStefano Zampini const PetscInt *idxs; 3298bd2a564bSStefano Zampini 3299bd2a564bSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nz);CHKERRQ(ierr); 3300bd2a564bSStefano Zampini ierr = ISGetIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3301bd2a564bSStefano Zampini for (k=0;k<nz;k++) { 3302bd2a564bSStefano Zampini *( Sarray + cumarray + idxs[k]*(subset_size+1)) *= -1.0; 3303bd2a564bSStefano Zampini *(Starray + cumarray + idxs[k]*(subset_size+1)) = 0.0; 3304bd2a564bSStefano Zampini } 3305bd2a564bSStefano Zampini ierr = ISRestoreIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3306bd2a564bSStefano Zampini } 3307bd2a564bSStefano Zampini scal = PETSC_TRUE; 3308bd2a564bSStefano Zampini break; 3309bd2a564bSStefano Zampini } 3310bd2a564bSStefano Zampini } 3311bd2a564bSStefano Zampini } 3312bd2a564bSStefano Zampini 3313f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 3314bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 3315aff50787SStefano Zampini PetscInt j,k; 3316580bdb30SBarry Smith if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscArraycmp() later */ 3317580bdb30SBarry Smith ierr = PetscArrayzero(S,subset_size*subset_size);CHKERRQ(ierr); 3318580bdb30SBarry Smith ierr = PetscArrayzero(St,subset_size*subset_size);CHKERRQ(ierr); 331908122e43SStefano Zampini } 332008122e43SStefano Zampini for (j=0;j<subset_size;j++) { 3321aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 3322aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 3323aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 3324aff50787SStefano Zampini } 332508122e43SStefano Zampini } 332608122e43SStefano Zampini } else { 3327580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3328580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 332908122e43SStefano Zampini } 33308bec7fa6SStefano Zampini } else { 3331f6f667cfSStefano Zampini S = Sarray + cumarray; 3332f6f667cfSStefano Zampini St = Starray + cumarray; 33338bec7fa6SStefano Zampini } 3334aff50787SStefano Zampini /* see if we can save some work */ 3335b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 3336580bdb30SBarry Smith ierr = PetscArraycmp(S,St,subset_size*subset_size,&same_data);CHKERRQ(ierr); 3337aff50787SStefano Zampini } 3338aff50787SStefano Zampini 3339b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 3340aff50787SStefano Zampini B_neigs = 0; 3341aff50787SStefano Zampini } else { 3342bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 334308122e43SStefano Zampini PetscBLASInt B_itype = 1; 3344f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 33454c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 33469552c7c7SStefano Zampini PetscInt nmin_s; 3347bd2a564bSStefano Zampini PetscBool compute_range; 3348bd2a564bSStefano Zampini 33499036ceccSStefano Zampini B_neigs = 0; 3350bd2a564bSStefano Zampini compute_range = (PetscBool)!same_data; 3351bd2a564bSStefano Zampini if (nmin >= subset_size) compute_range = PETSC_FALSE; 335208122e43SStefano Zampini 3353fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 33549036ceccSStefano Zampini PetscInt nc = 0; 3355d16cbb6bSStefano Zampini 33569036ceccSStefano Zampini if (sub_schurs->change_primal_sub) { 33579036ceccSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nc);CHKERRQ(ierr); 33589036ceccSStefano Zampini } 33596080607fSStefano 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); 3360b7ab4a40SStefano Zampini } 3361b7ab4a40SStefano Zampini 336208122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3363b7ab4a40SStefano Zampini if (compute_range) { 3364d16cbb6bSStefano Zampini 3365d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 3366bd2a564bSStefano Zampini if (sub_schurs->is_posdef) { 336708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 33689d54b7f4SStefano 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)); 336908122e43SStefano Zampini #else 33709d54b7f4SStefano 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)); 337108122e43SStefano Zampini #endif 337243371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3373bd2a564bSStefano Zampini } else { /* no theory so far, but it works nicely */ 33749036ceccSStefano Zampini PetscInt recipe = 0,recipe_m = 1; 3375bd2a564bSStefano Zampini PetscReal bb[2]; 3376bd2a564bSStefano Zampini 3377bd2a564bSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe",&recipe,NULL);CHKERRQ(ierr); 3378bd2a564bSStefano Zampini switch (recipe) { 3379bd2a564bSStefano Zampini case 0: 3380bd2a564bSStefano Zampini if (scal) { bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; } 3381bd2a564bSStefano Zampini else { bb[0] = uthresh; bb[1] = PETSC_MAX_REAL; } 3382bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3383bd2a564bSStefano 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)); 3384bd2a564bSStefano Zampini #else 3385bd2a564bSStefano 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)); 3386bd2a564bSStefano Zampini #endif 338743371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3388bd2a564bSStefano Zampini break; 3389bd2a564bSStefano Zampini case 1: 3390bd2a564bSStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh*lthresh; 3391bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3392bd2a564bSStefano 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)); 3393bd2a564bSStefano Zampini #else 3394bd2a564bSStefano 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)); 3395bd2a564bSStefano Zampini #endif 339643371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3397bd2a564bSStefano Zampini if (!scal) { 33989036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 3399bd2a564bSStefano Zampini 3400aed7e7d0SStefano Zampini bb[0] = PetscMax(lthresh*lthresh,uthresh); bb[1] = PETSC_MAX_REAL; 3401580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3402580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3403bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3404bd2a564bSStefano 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)); 3405bd2a564bSStefano Zampini #else 3406bd2a564bSStefano 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)); 3407bd2a564bSStefano Zampini #endif 340843371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3409bd2a564bSStefano Zampini B_neigs += B_neigs2; 3410bd2a564bSStefano Zampini } 3411bd2a564bSStefano Zampini break; 34129036ceccSStefano Zampini case 2: 34139036ceccSStefano Zampini if (scal) { 34149036ceccSStefano Zampini bb[0] = PETSC_MIN_REAL; 34159036ceccSStefano Zampini bb[1] = 0; 34169036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34179036ceccSStefano 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)); 34189036ceccSStefano Zampini #else 34199036ceccSStefano 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)); 34209036ceccSStefano Zampini #endif 342143371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34229036ceccSStefano Zampini } else { 34239036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 34249036ceccSStefano Zampini PetscBool import = PETSC_FALSE; 34259036ceccSStefano Zampini 34269036ceccSStefano Zampini lthresh = PetscMax(lthresh,0.0); 34279036ceccSStefano Zampini if (lthresh > 0.0) { 34289036ceccSStefano Zampini bb[0] = PETSC_MIN_REAL; 34299036ceccSStefano Zampini bb[1] = lthresh*lthresh; 34309036ceccSStefano Zampini 34319036ceccSStefano Zampini import = PETSC_TRUE; 34329036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34339036ceccSStefano 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)); 34349036ceccSStefano Zampini #else 34359036ceccSStefano 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)); 34369036ceccSStefano Zampini #endif 343743371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34389036ceccSStefano Zampini } 34399036ceccSStefano Zampini bb[0] = PetscMax(lthresh*lthresh,uthresh); 34409036ceccSStefano Zampini bb[1] = PETSC_MAX_REAL; 34419036ceccSStefano Zampini if (import) { 3442580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3443580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 34449036ceccSStefano Zampini } 34459036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34469036ceccSStefano 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)); 34479036ceccSStefano Zampini #else 34489036ceccSStefano 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)); 34499036ceccSStefano Zampini #endif 345043371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34519036ceccSStefano Zampini B_neigs += B_neigs2; 34529036ceccSStefano Zampini } 34539036ceccSStefano Zampini break; 34549036ceccSStefano Zampini case 3: 34559036ceccSStefano Zampini if (scal) { 34569036ceccSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe3_min_scal",&recipe_m,NULL);CHKERRQ(ierr); 34579036ceccSStefano Zampini } else { 34589036ceccSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe3_min",&recipe_m,NULL);CHKERRQ(ierr); 34599036ceccSStefano Zampini } 34609036ceccSStefano Zampini if (!scal) { 34619036ceccSStefano Zampini bb[0] = uthresh; 34629036ceccSStefano Zampini bb[1] = PETSC_MAX_REAL; 34639036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34649036ceccSStefano 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)); 34659036ceccSStefano Zampini #else 34669036ceccSStefano 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)); 34679036ceccSStefano Zampini #endif 346843371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34699036ceccSStefano Zampini } 34709036ceccSStefano Zampini if (recipe_m > 0 && B_N - B_neigs > 0) { 34719036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 34729036ceccSStefano Zampini 34739036ceccSStefano Zampini B_IL = 1; 34749036ceccSStefano Zampini ierr = PetscBLASIntCast(PetscMin(recipe_m,B_N - B_neigs),&B_IU);CHKERRQ(ierr); 3475580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3476580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 34779036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34789036ceccSStefano 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)); 34799036ceccSStefano Zampini #else 34809036ceccSStefano 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)); 34819036ceccSStefano Zampini #endif 348243371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34839036ceccSStefano Zampini B_neigs += B_neigs2; 34849036ceccSStefano Zampini } 34859036ceccSStefano Zampini break; 348648cebe81SStefano Zampini case 4: 348748cebe81SStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; 348848cebe81SStefano Zampini #if defined(PETSC_USE_COMPLEX) 348948cebe81SStefano 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)); 349048cebe81SStefano Zampini #else 349148cebe81SStefano 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)); 349248cebe81SStefano Zampini #endif 349343371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 349448cebe81SStefano Zampini { 349548cebe81SStefano Zampini PetscBLASInt B_neigs2 = 0; 349648cebe81SStefano Zampini 349748cebe81SStefano Zampini bb[0] = PetscMax(lthresh+PETSC_SMALL,uthresh); bb[1] = PETSC_MAX_REAL; 3498580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3499580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 350048cebe81SStefano Zampini #if defined(PETSC_USE_COMPLEX) 350148cebe81SStefano 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)); 350248cebe81SStefano Zampini #else 350348cebe81SStefano 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)); 350448cebe81SStefano Zampini #endif 350543371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 350648cebe81SStefano Zampini B_neigs += B_neigs2; 350748cebe81SStefano Zampini } 350848cebe81SStefano Zampini break; 350980db8efeSStefano Zampini case 5: /* same as before: first compute all eigenvalues, then filter */ 351080db8efeSStefano Zampini #if defined(PETSC_USE_COMPLEX) 351180db8efeSStefano 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)); 351280db8efeSStefano Zampini #else 351380db8efeSStefano 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)); 351480db8efeSStefano Zampini #endif 351543371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 351680db8efeSStefano Zampini { 351780db8efeSStefano Zampini PetscInt e,k,ne; 351880db8efeSStefano Zampini for (e=0,ne=0;e<B_neigs;e++) { 351980db8efeSStefano Zampini if (eigs[e] < lthresh || eigs[e] > uthresh) { 352080db8efeSStefano Zampini for (k=0;k<B_N;k++) S[ne*B_N+k] = eigv[e*B_N+k]; 352180db8efeSStefano Zampini eigs[ne] = eigs[e]; 352280db8efeSStefano Zampini ne++; 352380db8efeSStefano Zampini } 352480db8efeSStefano Zampini } 3525580bdb30SBarry Smith ierr = PetscArraycpy(eigv,S,B_N*ne);CHKERRQ(ierr); 352680db8efeSStefano Zampini B_neigs = ne; 352780db8efeSStefano Zampini } 352880db8efeSStefano Zampini break; 3529bd2a564bSStefano Zampini default: 3530bd2a564bSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Unknown recipe %D",recipe); 3531bd2a564bSStefano Zampini break; 3532bd2a564bSStefano Zampini } 3533bd2a564bSStefano Zampini } 3534bd2a564bSStefano Zampini } else if (!same_data) { /* this is just to see all the eigenvalues */ 3535d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 3536d16cbb6bSStefano Zampini B_IL = 1; 3537d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 35389d54b7f4SStefano 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)); 3539d16cbb6bSStefano Zampini #else 35409d54b7f4SStefano 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)); 3541d16cbb6bSStefano Zampini #endif 354243371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3543b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 3544b7ab4a40SStefano Zampini PetscInt k; 3545b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 3546b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 3547b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 3548b7ab4a40SStefano Zampini nmin = nmax; 3549580bdb30SBarry Smith ierr = PetscArrayzero(eigv,subset_size*nmax);CHKERRQ(ierr); 3550b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 3551b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 3552b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 3553b7ab4a40SStefano Zampini } 3554d16cbb6bSStefano Zampini } 355508122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 355608122e43SStefano Zampini if (B_ierr) { 35576c4ed002SBarry 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); 35586c4ed002SBarry 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); 35596c4ed002SBarry 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); 356008122e43SStefano Zampini } 356108122e43SStefano Zampini 356208122e43SStefano Zampini if (B_neigs > nmax) { 3563fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 35646080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %D.\n",B_neigs,nmax);CHKERRQ(ierr); 3565fd14bc51SStefano Zampini } 3566bd2a564bSStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = scal ? 0 : B_neigs-nmax; 356708122e43SStefano Zampini B_neigs = nmax; 356808122e43SStefano Zampini } 356908122e43SStefano Zampini 35709552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 35719552c7c7SStefano Zampini if (B_neigs < nmin_s) { 35729036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 357308122e43SStefano Zampini 35749d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3575bd2a564bSStefano Zampini if (scal) { 3576bd2a564bSStefano Zampini B_IU = nmin_s; 3577bd2a564bSStefano Zampini B_IL = B_neigs + 1; 3578bd2a564bSStefano Zampini } else { 3579f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 35809d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 3581bd2a564bSStefano Zampini } 35829d54b7f4SStefano Zampini } else { 35839d54b7f4SStefano Zampini B_IL = B_neigs + 1; 35849d54b7f4SStefano Zampini B_IU = nmin_s; 35859d54b7f4SStefano Zampini } 3586fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 35876080607fSStefano 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); 3588fd14bc51SStefano Zampini } 3589bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 35901ae86dd6SStefano Zampini PetscInt j,k; 359108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 35921ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 35931ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 35941ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 359508122e43SStefano Zampini } 359608122e43SStefano Zampini } 359708122e43SStefano Zampini } else { 3598580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3599580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 360008122e43SStefano Zampini } 360108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 360208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 36039d54b7f4SStefano 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)); 360408122e43SStefano Zampini #else 36059d54b7f4SStefano 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)); 360608122e43SStefano Zampini #endif 360743371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 360808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 360908122e43SStefano Zampini B_neigs += B_neigs2; 361008122e43SStefano Zampini } 361108122e43SStefano Zampini if (B_ierr) { 36126c4ed002SBarry 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); 36136c4ed002SBarry 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); 36146c4ed002SBarry 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); 361508122e43SStefano Zampini } 3616fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3617ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 361808122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 361908122e43SStefano Zampini if (eigs[j] == 0.0) { 3620ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 362108122e43SStefano Zampini } else { 36229d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3623ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 36249d54b7f4SStefano Zampini } else { 36259d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 36269d54b7f4SStefano Zampini } 3627fd14bc51SStefano Zampini } 362808122e43SStefano Zampini } 362908122e43SStefano Zampini } 3630bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 3631aff50787SStefano Zampini } 36326c3e6151SStefano Zampini /* change the basis back to the original one */ 36336c3e6151SStefano Zampini if (sub_schurs->change) { 363472b8c272SStefano Zampini Mat change,phi,phit; 36356c3e6151SStefano Zampini 363603dfb2d7SStefano Zampini if (pcbddc->dbg_flag > 2) { 36376c3e6151SStefano Zampini PetscInt ii; 36386c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 36396c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 36406c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 3641684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3642684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 3643684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 3644684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3645684229deSStefano Zampini #else 36466c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 3647684229deSStefano Zampini #endif 36486c3e6151SStefano Zampini } 36496c3e6151SStefano Zampini } 36506c3e6151SStefano Zampini } 365172b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 36526c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 365372b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 36546c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 36556c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 36566c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 36576c3e6151SStefano Zampini } 36588bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 36598bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 36609162d606SStefano Zampini if (B_neigs) { 3661580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum],eigv+eigs_start*subset_size,B_neigs*subset_size);CHKERRQ(ierr); 3662fd14bc51SStefano Zampini 3663fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 36649552c7c7SStefano Zampini PetscInt ii; 36659552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 3666ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 36679552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 3668ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3669ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3670ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3671ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3672ac47001eSStefano Zampini #else 3673ac47001eSStefano 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); 3674ac47001eSStefano Zampini #endif 36759552c7c7SStefano Zampini } 36769552c7c7SStefano Zampini } 3677fd14bc51SStefano Zampini } 3678580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size);CHKERRQ(ierr); 36799162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 36809162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 36819162d606SStefano Zampini cum++; 368208122e43SStefano Zampini } 368308122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 368408122e43SStefano Zampini /* shift for next computation */ 368508122e43SStefano Zampini cumarray += subset_size*subset_size; 368608122e43SStefano Zampini } 3687fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3688fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3689fd14bc51SStefano Zampini } 369008122e43SStefano Zampini 369108122e43SStefano Zampini if (mss) { 369208122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 369308122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3694f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3695f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3696f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 369708122e43SStefano Zampini } 3698f6f667cfSStefano Zampini if (allocated_S_St) { 3699f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3700f6f667cfSStefano Zampini } 3701f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 370208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 370308122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 370408122e43SStefano Zampini #endif 370508122e43SStefano Zampini if (pcbddc->dbg_flag) { 37061b968477SStefano Zampini PetscInt maxneigs_r; 3707b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 37086080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %D\n",maxneigs_r);CHKERRQ(ierr); 370908122e43SStefano Zampini } 371043371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_AdaptiveSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 371108122e43SStefano Zampini PetscFunctionReturn(0); 371208122e43SStefano Zampini } 3713b1b3d7a2SStefano Zampini 3714c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3715c8587f34SStefano Zampini { 37168629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3717c8587f34SStefano Zampini PetscErrorCode ierr; 3718c8587f34SStefano Zampini 3719c8587f34SStefano Zampini PetscFunctionBegin; 3720f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 37215e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3722c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3723c8587f34SStefano Zampini 3724684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 37250fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3726684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3727c8587f34SStefano Zampini 37288629588bSStefano Zampini /* 37298629588bSStefano Zampini Setup local correction and local part of coarse basis. 37308629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 37318629588bSStefano Zampini */ 373247f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 37338629588bSStefano Zampini 37348629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 37358629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 37368629588bSStefano Zampini 37378629588bSStefano Zampini /* free */ 37388629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3739c8587f34SStefano Zampini PetscFunctionReturn(0); 3740c8587f34SStefano Zampini } 3741c8587f34SStefano Zampini 3742674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3743674ae819SStefano Zampini { 3744674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3745674ae819SStefano Zampini PetscErrorCode ierr; 3746674ae819SStefano Zampini 3747674ae819SStefano Zampini PetscFunctionBegin; 3748674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 374930368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3750674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3751785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3752674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3753f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3754f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3755785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 375663602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 375763602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3758674ae819SStefano Zampini PetscFunctionReturn(0); 3759674ae819SStefano Zampini } 3760674ae819SStefano Zampini 3761674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3762674ae819SStefano Zampini { 3763674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 37644f1b2e48SStefano Zampini PetscInt i; 3765674ae819SStefano Zampini PetscErrorCode ierr; 3766674ae819SStefano Zampini 3767674ae819SStefano Zampini PetscFunctionBegin; 37681e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 37691e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3770a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3771b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3772674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 377316909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 37741dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3775674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3776669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3777fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 37789326c5c6Sstefano_zampini ierr = PCBDDCGraphDestroy(&pcbddc->mat_graph);CHKERRQ(ierr); 37794f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 37804f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 37814f1b2e48SStefano Zampini } 3782e68a0315Sstefano_zampini pcbddc->n_local_subs = 0; 37834f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3784e68a0315Sstefano_zampini ierr = PCBDDCSubSchursDestroy(&pcbddc->sub_schurs);CHKERRQ(ierr); 3785c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 37868af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 37871c7a958bSStefano Zampini pcbddc->corner_selected = PETSC_FALSE; 3788674ae819SStefano Zampini PetscFunctionReturn(0); 3789674ae819SStefano Zampini } 3790674ae819SStefano Zampini 3791674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3792674ae819SStefano Zampini { 3793674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3794674ae819SStefano Zampini PetscErrorCode ierr; 3795674ae819SStefano Zampini 3796674ae819SStefano Zampini PetscFunctionBegin; 3797674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 379858da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3799ca92afb2SStefano Zampini PetscScalar *array; 380006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 380106656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 380258da7f69SStefano Zampini } 3803674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3804674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 380515aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 380615aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3807674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3808674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3809674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 381006656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3811674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3812674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 38138ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3814674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3815674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3816674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 38179326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_D);CHKERRQ(ierr); 38189326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 38199326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3820f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3821727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 38220e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3823f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 382470cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 382581d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 38260369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 38271dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 38284f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 38298b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3830ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3831ca92afb2SStefano Zampini PetscInt i; 3832ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3833ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3834ca92afb2SStefano Zampini } 3835ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3836ca92afb2SStefano Zampini } 38374f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3838674ae819SStefano Zampini PetscFunctionReturn(0); 3839674ae819SStefano Zampini } 3840674ae819SStefano Zampini 3841f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 38426bfb1811SStefano Zampini { 38436bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 38446bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 38456bfb1811SStefano Zampini VecType impVecType; 38464f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 38476bfb1811SStefano Zampini PetscErrorCode ierr; 38486bfb1811SStefano Zampini 38496bfb1811SStefano Zampini PetscFunctionBegin; 38504f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3851b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 38526bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3853e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3854e7b262bdSStefano Zampini /* R nodes */ 3855e7b262bdSStefano Zampini old_size = -1; 3856e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3857e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3858e7b262bdSStefano Zampini } 3859e7b262bdSStefano Zampini if (n_R != old_size) { 3860e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3861e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 38626bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 38636bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 38646bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 38656bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3866e7b262bdSStefano Zampini } 3867e7b262bdSStefano Zampini /* local primal dofs */ 3868e7b262bdSStefano Zampini old_size = -1; 3869e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3870e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3871e7b262bdSStefano Zampini } 3872e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3873e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 387483b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3875e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 38766bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3877e7b262bdSStefano Zampini } 3878e7b262bdSStefano Zampini /* local explicit constraints */ 3879e7b262bdSStefano Zampini old_size = -1; 3880e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3881e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3882e7b262bdSStefano Zampini } 3883e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3884e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 388583b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 388683b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 388783b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 388883b7ccabSStefano Zampini } 38896bfb1811SStefano Zampini PetscFunctionReturn(0); 38906bfb1811SStefano Zampini } 38916bfb1811SStefano Zampini 389247f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 389388ebb749SStefano Zampini { 389425084f0cSStefano Zampini PetscErrorCode ierr; 389525084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 389688ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 389788ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3898d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 389925084f0cSStefano Zampini /* submatrices of local problem */ 390080677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 390106656605SStefano Zampini /* submatrices of local coarse problem */ 390206656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 390325084f0cSStefano Zampini /* working matrices */ 390406656605SStefano Zampini Mat C_CR; 390525084f0cSStefano Zampini /* additional working stuff */ 390606656605SStefano Zampini PC pc_R; 3907c58f9fdbSStefano Zampini Mat F,Brhs = NULL; 39085cbda25cSStefano Zampini Vec dummy_vec; 39097ebab0bbSStefano Zampini PetscBool isLU,isCHOL,need_benign_correction,sparserhs; 391025084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 391106656605SStefano Zampini PetscScalar *work; 391206656605SStefano Zampini PetscInt *idx_V_B; 3913ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 391406656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 391506656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 391688ebb749SStefano Zampini 391788ebb749SStefano Zampini PetscFunctionBegin; 39189a962809SStefano 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"); 391943371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CorrectionSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 3920ffd830a3SStefano Zampini 3921ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3922b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 39234f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3924b371cd4fSStefano Zampini n_B = pcis->n_B; 3925b371cd4fSStefano Zampini n_D = pcis->n - n_B; 392688ebb749SStefano Zampini n_R = pcis->n - n_vertices; 392788ebb749SStefano Zampini 392888ebb749SStefano Zampini /* vertices in boundary numbering */ 3929785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 39300e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 39316080607fSStefano Zampini if (i != n_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D",n_vertices,i); 393288ebb749SStefano Zampini 393306656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3934019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 393506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 393606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 393706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 393806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 393906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 394006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 394106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 394206656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 394306656605SStefano Zampini 394406656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 394506656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 39462958b453SStefano Zampini ierr = PCSetUp(pc_R);CHKERRQ(ierr); 394706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);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; 39517ebab0bbSStefano Zampini if (isLU || 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; 39607ebab0bbSStefano Zampini if (type == MAT_FACTOR_LU) isLU = PETSC_TRUE; 3961ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 396222db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 39637ebab0bbSStefano Zampini } else F = NULL; 396406656605SStefano Zampini 3965c58f9fdbSStefano Zampini /* determine if we can use a sparse right-hand side */ 3966c58f9fdbSStefano Zampini sparserhs = PETSC_FALSE; 3967c58f9fdbSStefano Zampini if (F) { 3968ea799195SBarry Smith MatSolverType solver; 3969c58f9fdbSStefano Zampini 39703ca39a21SBarry Smith ierr = MatFactorGetSolverType(F,&solver);CHKERRQ(ierr); 3971c58f9fdbSStefano Zampini ierr = PetscStrcmp(solver,MATSOLVERMUMPS,&sparserhs);CHKERRQ(ierr); 3972c58f9fdbSStefano Zampini } 3973c58f9fdbSStefano Zampini 3974ffd830a3SStefano Zampini /* allocate workspace */ 3975ffd830a3SStefano Zampini n = 0; 3976ffd830a3SStefano Zampini if (n_constraints) { 3977ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3978ffd830a3SStefano Zampini } 3979ffd830a3SStefano Zampini if (n_vertices) { 3980ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3981ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3982ffd830a3SStefano Zampini } 39832a3a6641Sstefano_zampini if (!pcbddc->symmetric_primal) { 39842a3a6641Sstefano_zampini n = PetscMax(2*lda_rhs*pcbddc->local_primal_size,n); 39852a3a6641Sstefano_zampini } 3986ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3987ffd830a3SStefano Zampini 39885cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 39895cbda25cSStefano Zampini dummy_vec = NULL; 39905cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 3991c72cccf8SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&dummy_vec);CHKERRQ(ierr); 3992c72cccf8SStefano Zampini ierr = VecSetSizes(dummy_vec,lda_rhs,PETSC_DECIDE);CHKERRQ(ierr); 3993c72cccf8SStefano Zampini ierr = VecSetType(dummy_vec,((PetscObject)pcis->vec1_N)->type_name);CHKERRQ(ierr); 39945cbda25cSStefano Zampini } 39955cbda25cSStefano Zampini 39967ebab0bbSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 39977ebab0bbSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 39987ebab0bbSStefano Zampini 399988ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 400088ebb749SStefano Zampini if (n_constraints) { 4001837cedc9SStefano Zampini Mat M3,C_B; 400206656605SStefano Zampini IS is_aux; 400380677318SStefano Zampini PetscScalar *array,*array2; 400406656605SStefano Zampini 400525084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 400625084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 40077dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 40087dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 400988ebb749SStefano Zampini 401080677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 401180677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 4012c58f9fdbSStefano Zampini if (!sparserhs) { 4013580bdb30SBarry Smith ierr = PetscArrayzero(work,lda_rhs*n_constraints);CHKERRQ(ierr); 401488ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 401506656605SStefano Zampini const PetscScalar *row_cmat_values; 401606656605SStefano Zampini const PetscInt *row_cmat_indices; 401706656605SStefano Zampini PetscInt size_of_constraint,j; 401888ebb749SStefano Zampini 401906656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 402006656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 4021ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 402206656605SStefano Zampini } 402306656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 402406656605SStefano Zampini } 4025c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&Brhs);CHKERRQ(ierr); 4026c58f9fdbSStefano Zampini } else { 4027c58f9fdbSStefano Zampini Mat tC_CR; 4028c58f9fdbSStefano Zampini 4029c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 4030c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 4031c58f9fdbSStefano Zampini PetscScalar *aa; 4032c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 4033c58f9fdbSStefano Zampini PetscBool done; 4034c58f9fdbSStefano Zampini 4035c58f9fdbSStefano Zampini ierr = MatGetRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 403613903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 4037c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(C_CR,&aa);CHKERRQ(ierr); 4038c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_constraints,lda_rhs,ii,jj,aa,&tC_CR);CHKERRQ(ierr); 4039c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 404013903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 4041c58f9fdbSStefano Zampini } else { 4042c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)C_CR);CHKERRQ(ierr); 4043c58f9fdbSStefano Zampini tC_CR = C_CR; 4044c58f9fdbSStefano Zampini } 4045c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tC_CR,&Brhs);CHKERRQ(ierr); 4046c58f9fdbSStefano Zampini ierr = MatDestroy(&tC_CR);CHKERRQ(ierr); 4047c58f9fdbSStefano Zampini } 4048ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 404906656605SStefano Zampini if (F) { 4050a3df083aSStefano Zampini if (need_benign_correction) { 4051df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4052a3df083aSStefano Zampini 405372b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 4054580bdb30SBarry Smith ierr = PetscArrayzero(reuse_solver->benign_save_vals,pcbddc->benign_n);CHKERRQ(ierr); 4055a3df083aSStefano Zampini } 4056c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,local_auxmat2_R);CHKERRQ(ierr); 4057a3df083aSStefano Zampini if (need_benign_correction) { 4058a3df083aSStefano Zampini PetscScalar *marr; 4059df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4060a3df083aSStefano Zampini 4061a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 40625cbda25cSStefano Zampini if (lda_rhs != n_R) { 40635cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 40645cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 40655cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 40665cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 40675cbda25cSStefano Zampini } 40685cbda25cSStefano Zampini } else { 4069a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 4070a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 40715cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4072a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4073a3df083aSStefano Zampini } 40745cbda25cSStefano Zampini } 4075a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 4076a3df083aSStefano Zampini } 407706656605SStefano Zampini } else { 407880677318SStefano Zampini PetscScalar *marr; 407980677318SStefano Zampini 408080677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 408106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 4082ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4083ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 408406656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4085c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 408606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 408706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 408806656605SStefano Zampini } 408980677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 409006656605SStefano Zampini } 4091c58f9fdbSStefano Zampini if (sparserhs) { 4092c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 4093c58f9fdbSStefano Zampini } 4094c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 409580677318SStefano Zampini if (!pcbddc->switch_static) { 409680677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 409780677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 409880677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 409980677318SStefano Zampini for (i=0;i<n_constraints;i++) { 4100ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 410180677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 410280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 410380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 410480677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 410580677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 410680677318SStefano Zampini } 410780677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 410880677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 410972b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 411080677318SStefano Zampini } else { 4111ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4112ffd830a3SStefano Zampini IS dummy; 4113ffd830a3SStefano Zampini 4114ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 41157dae84e0SHong Zhang ierr = MatCreateSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 4116ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 4117ffd830a3SStefano Zampini } else { 411880677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 411980677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 4120ffd830a3SStefano Zampini } 412125084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 412280677318SStefano Zampini } 412380677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 412480677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 412580677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 412680677318SStefano Zampini if (isCHOL) { 412780677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 412880677318SStefano Zampini } else { 412925084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 413080677318SStefano Zampini } 4131837cedc9SStefano Zampini ierr = MatSeqDenseInvertFactors_Private(M3);CHKERRQ(ierr); 413280677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 4133837cedc9SStefano Zampini ierr = MatMatMult(M3,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 413472b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 4135837cedc9SStefano Zampini ierr = MatCopy(M3,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 4136837cedc9SStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 4137f4ddd8eeSStefano Zampini } 4138fc227af8SStefano Zampini 4139fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 414088ebb749SStefano Zampini if (n_vertices) { 41417ebab0bbSStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 41427ebab0bbSStefano Zampini PetscBool oldpin; 41437ebab0bbSStefano Zampini #endif 41447ebab0bbSStefano Zampini PetscBool isaij; 414506656605SStefano Zampini IS is_aux; 41463a50541eSStefano Zampini 4147b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 41486816873aSStefano Zampini IS tis; 41496816873aSStefano Zampini 41506816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 41516816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 41526816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 41536816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 41546816873aSStefano Zampini } else { 41553a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 41566816873aSStefano Zampini } 41577ebab0bbSStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 4158*b470e4b4SRichard Tran Mills oldpin = pcbddc->local_mat->boundtocpu; 41597ebab0bbSStefano Zampini #endif 4160*b470e4b4SRichard Tran Mills ierr = MatBindToCPU(pcbddc->local_mat,PETSC_TRUE);CHKERRQ(ierr); 41617dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 41627dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 41637ebab0bbSStefano Zampini ierr = PetscObjectBaseTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isaij);CHKERRQ(ierr); 41647ebab0bbSStefano Zampini if (!isaij) { /* TODO REMOVE: MatMatMult(A_VR,A_RRmA_RV) below may raise an error */ 4165c58f9fdbSStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 41667ebab0bbSStefano Zampini } 41677dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 41687ebab0bbSStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 4169*b470e4b4SRichard Tran Mills ierr = MatBindToCPU(pcbddc->local_mat,oldpin);CHKERRQ(ierr); 41707ebab0bbSStefano Zampini #endif 417125084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 417288ebb749SStefano Zampini } 417388ebb749SStefano Zampini 417488ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 4175f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 417606656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 417706656605SStefano Zampini if (pcbddc->coarse_phi_D) { 417806656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 417906656605SStefano Zampini } 4180f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 418106656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 418206656605SStefano Zampini PetscScalar *marray; 418306656605SStefano Zampini 418406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 418506656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 4186f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 4187f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 4188f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 4189f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 4190f4ddd8eeSStefano Zampini } 4191f4ddd8eeSStefano Zampini } 419206656605SStefano Zampini 4193f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 4194a6e023c1Sstefano_zampini PetscScalar *marr; 419588ebb749SStefano Zampini 4196a6e023c1Sstefano_zampini /* memory size */ 419706656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 4198a6e023c1Sstefano_zampini if (pcbddc->switch_static || pcbddc->dbg_flag) n += n_D*pcbddc->local_primal_size; 4199a6e023c1Sstefano_zampini if (!pcbddc->symmetric_primal) n *= 2; 4200a6e023c1Sstefano_zampini ierr = PetscCalloc1(n,&marr);CHKERRQ(ierr); 4201a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 4202a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 42038eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4204a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 4205a6e023c1Sstefano_zampini marr += n_D*pcbddc->local_primal_size; 420688ebb749SStefano Zampini } 42073301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4208a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 4209a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 42108eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4211a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 421288ebb749SStefano Zampini } 421388ebb749SStefano Zampini } else { 4214c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 4215c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 42161b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4217c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 4218c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 4219c0553b1fSStefano Zampini } 422088ebb749SStefano Zampini } 422106656605SStefano Zampini } 4222019a44ceSStefano Zampini 422306656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 42244f1b2e48SStefano Zampini p0_lidx_I = NULL; 42254f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 4226d12edf2fSStefano Zampini const PetscInt *idxs; 4227d12edf2fSStefano Zampini 4228d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 42294f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 42304f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 42314f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 42324f1b2e48SStefano Zampini } 4233d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 4234d12edf2fSStefano Zampini } 4235d16cbb6bSStefano Zampini 423606656605SStefano Zampini /* vertices */ 423706656605SStefano Zampini if (n_vertices) { 4238c58f9fdbSStefano Zampini PetscBool restoreavr = PETSC_FALSE; 423916f15bc4SStefano Zampini 4240af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 424104708bb6SStefano Zampini 424216f15bc4SStefano Zampini if (n_R) { 424314393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 424406656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 42451683a169SBarry Smith const PetscScalar *x; 42461683a169SBarry Smith PetscScalar *y; 424706656605SStefano Zampini 424821eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 424914393ed6SStefano Zampini if (need_benign_correction) { 425014393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 425114393ed6SStefano Zampini IS is_p0; 425214393ed6SStefano Zampini PetscInt *idxs_p0,n; 425314393ed6SStefano Zampini 425414393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 425514393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 425614393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 42576080607fSStefano 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); 425814393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 425914393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 42607dae84e0SHong Zhang ierr = MatCreateSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 426114393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 426214393ed6SStefano Zampini } 426314393ed6SStefano Zampini 4264c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4265c58f9fdbSStefano Zampini if (!sparserhs || need_benign_correction) { 4266ffd830a3SStefano Zampini if (lda_rhs == n_R) { 4267af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 4268ffd830a3SStefano Zampini } else { 4269ca92afb2SStefano Zampini PetscScalar *av,*array; 4270ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 4271ca92afb2SStefano Zampini PetscInt n; 4272ca92afb2SStefano Zampini PetscBool flg_row; 4273ffd830a3SStefano Zampini 4274ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 4275580bdb30SBarry Smith ierr = PetscArrayzero(array,lda_rhs*n_vertices);CHKERRQ(ierr); 42769d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 4277ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4278ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 4279ca92afb2SStefano Zampini for (i=0;i<n;i++) { 4280ca92afb2SStefano Zampini PetscInt j; 4281ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 4282ffd830a3SStefano Zampini } 4283ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4284ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4285ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 4286ffd830a3SStefano Zampini } 4287a3df083aSStefano Zampini if (need_benign_correction) { 4288df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4289a3df083aSStefano Zampini PetscScalar *marr; 4290a3df083aSStefano Zampini 4291a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 429214393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 429314393ed6SStefano Zampini 429414393ed6SStefano Zampini | 0 0 0 | (V) 429514393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 429614393ed6SStefano Zampini | 0 0 -1 | (p0) 429714393ed6SStefano Zampini 429814393ed6SStefano Zampini */ 4299df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 430014393ed6SStefano Zampini const PetscScalar *vals; 430114393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 430214393ed6SStefano Zampini PetscInt n,j,nz; 430314393ed6SStefano Zampini 4304df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4305df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 430614393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 430714393ed6SStefano Zampini for (j=0;j<n;j++) { 430814393ed6SStefano Zampini PetscScalar val = vals[j]; 430914393ed6SStefano Zampini PetscInt k,col = idxs[j]; 431014393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 431114393ed6SStefano Zampini } 431214393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4313df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 431414393ed6SStefano Zampini } 431572b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 431672b8c272SStefano Zampini } 4317c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RV);CHKERRQ(ierr); 4318c58f9fdbSStefano Zampini Brhs = A_RV; 4319c58f9fdbSStefano Zampini } else { 4320c58f9fdbSStefano Zampini Mat tA_RVT,A_RVT; 4321c58f9fdbSStefano Zampini 4322c58f9fdbSStefano Zampini if (!pcbddc->symmetric_primal) { 4323fb6280fbSStefano Zampini /* A_RV already scaled by -1 */ 4324c58f9fdbSStefano Zampini ierr = MatTranspose(A_RV,MAT_INITIAL_MATRIX,&A_RVT);CHKERRQ(ierr); 4325c58f9fdbSStefano Zampini } else { 4326c58f9fdbSStefano Zampini restoreavr = PETSC_TRUE; 4327c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4328c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_VR);CHKERRQ(ierr); 4329c58f9fdbSStefano Zampini A_RVT = A_VR; 4330c58f9fdbSStefano Zampini } 4331c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 4332c58f9fdbSStefano Zampini PetscScalar *aa; 4333c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 4334c58f9fdbSStefano Zampini PetscBool done; 4335c58f9fdbSStefano Zampini 4336c58f9fdbSStefano Zampini ierr = MatGetRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 433713903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 4338c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(A_RVT,&aa);CHKERRQ(ierr); 4339c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_vertices,lda_rhs,ii,jj,aa,&tA_RVT);CHKERRQ(ierr); 4340c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 434113903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 4342c58f9fdbSStefano Zampini } else { 4343c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RVT);CHKERRQ(ierr); 4344c58f9fdbSStefano Zampini tA_RVT = A_RVT; 4345c58f9fdbSStefano Zampini } 4346c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tA_RVT,&Brhs);CHKERRQ(ierr); 4347c58f9fdbSStefano Zampini ierr = MatDestroy(&tA_RVT);CHKERRQ(ierr); 4348c58f9fdbSStefano Zampini ierr = MatDestroy(&A_RVT);CHKERRQ(ierr); 4349c58f9fdbSStefano Zampini } 435072b8c272SStefano Zampini if (F) { 435114393ed6SStefano Zampini /* need to correct the rhs */ 435272b8c272SStefano Zampini if (need_benign_correction) { 435372b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 435472b8c272SStefano Zampini PetscScalar *marr; 435572b8c272SStefano Zampini 4356c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&marr);CHKERRQ(ierr); 43575cbda25cSStefano Zampini if (lda_rhs != n_R) { 43585cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 43595cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 43605cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 43615cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 43625cbda25cSStefano Zampini } 43635cbda25cSStefano Zampini } else { 4364a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4365a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 43665cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 4367a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4368a3df083aSStefano Zampini } 43695cbda25cSStefano Zampini } 4370c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&marr);CHKERRQ(ierr); 4371a3df083aSStefano Zampini } 4372c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,A_RRmA_RV);CHKERRQ(ierr); 4373c58f9fdbSStefano Zampini if (restoreavr) { 4374c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4375c58f9fdbSStefano Zampini } 437614393ed6SStefano Zampini /* need to correct the solution */ 4377a3df083aSStefano Zampini if (need_benign_correction) { 4378df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4379a3df083aSStefano Zampini PetscScalar *marr; 4380a3df083aSStefano Zampini 4381a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 43825cbda25cSStefano Zampini if (lda_rhs != n_R) { 43835cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 43845cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 43855cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 43865cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 43875cbda25cSStefano Zampini } 43885cbda25cSStefano Zampini } else { 4389a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4390a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 43915cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4392a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4393a3df083aSStefano Zampini } 43945cbda25cSStefano Zampini } 4395a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 4396a3df083aSStefano Zampini } 439706656605SStefano Zampini } else { 4398c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&y);CHKERRQ(ierr); 439906656605SStefano Zampini for (i=0;i<n_vertices;i++) { 4400ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 4401ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 440206656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4403c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 440406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 440506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 440606656605SStefano Zampini } 4407c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&y);CHKERRQ(ierr); 440806656605SStefano Zampini } 440980677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4410c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 4411ffd830a3SStefano Zampini /* S_VV and S_CV */ 441206656605SStefano Zampini if (n_constraints) { 441306656605SStefano Zampini Mat B; 441480677318SStefano Zampini 4415580bdb30SBarry Smith ierr = PetscArrayzero(work+lda_rhs*n_vertices,n_B*n_vertices);CHKERRQ(ierr); 441680677318SStefano Zampini for (i=0;i<n_vertices;i++) { 4417ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4418ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 441980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 442080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 442180677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 442280677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 442380677318SStefano Zampini } 4424ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 442580677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 442680677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 4427ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 442880677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 442906656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 4430ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 4431ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 443206656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 443306656605SStefano Zampini } 4434ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4435ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 4436ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4437ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 4438ffd830a3SStefano Zampini } 443906656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 444014393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 444114393ed6SStefano Zampini if (need_benign_correction) { 4442df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 444314393ed6SStefano Zampini PetscScalar *marr,*sums; 444414393ed6SStefano Zampini 444514393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 4446f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 4447df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 444814393ed6SStefano Zampini const PetscScalar *vals; 444914393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 445014393ed6SStefano Zampini PetscInt n,j,nz; 445114393ed6SStefano Zampini 4452df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4453df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 445414393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 445514393ed6SStefano Zampini PetscInt k; 445614393ed6SStefano Zampini sums[j] = 0.; 445714393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 445814393ed6SStefano Zampini } 445914393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 446014393ed6SStefano Zampini for (j=0;j<n;j++) { 446114393ed6SStefano Zampini PetscScalar val = vals[j]; 446214393ed6SStefano Zampini PetscInt k; 446314393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 446414393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 446514393ed6SStefano Zampini } 446614393ed6SStefano Zampini } 446714393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4468df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 446914393ed6SStefano Zampini } 447014393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 4471f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 447214393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 447314393ed6SStefano Zampini } 447480677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 447506656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 44761683a169SBarry Smith ierr = MatDenseGetArrayRead(A_VV,&x);CHKERRQ(ierr); 447706656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 447806656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 44791683a169SBarry Smith ierr = MatDenseRestoreArrayRead(A_VV,&x);CHKERRQ(ierr); 448006656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 448106656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4482d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 4483019a44ceSStefano Zampini } else { 4484d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4485d16cbb6bSStefano Zampini } 448621eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 4487d16cbb6bSStefano Zampini 448806656605SStefano Zampini /* coarse basis functions */ 448906656605SStefano Zampini for (i=0;i<n_vertices;i++) { 449016f15bc4SStefano Zampini PetscScalar *y; 449116f15bc4SStefano Zampini 4492ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 449306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 449406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 449506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 449606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 449706656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 449806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 449906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 450006656605SStefano Zampini 450106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 45024f1b2e48SStefano Zampini PetscInt j; 45034f1b2e48SStefano Zampini 450406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 450506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 450606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 450706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 450806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 45094f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 451006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 451106656605SStefano Zampini } 451206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 451306656605SStefano Zampini } 451404708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 451504708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 451606656605SStefano Zampini } 45175cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 451806656605SStefano Zampini 451906656605SStefano Zampini if (n_constraints) { 452006656605SStefano Zampini Mat B; 452106656605SStefano Zampini 4522ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 452306656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 452480677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 452506656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 452606656605SStefano Zampini if (n_vertices) { 452703dfb2d7SStefano Zampini if (isCHOL || need_benign_correction) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 452880677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 452980677318SStefano Zampini } else { 453080677318SStefano Zampini Mat S_VCt; 453180677318SStefano Zampini 4532ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4533ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 453472b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 4535ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 4536ffd830a3SStefano Zampini } 453780677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 453880677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 453980677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 454080677318SStefano Zampini } 454106656605SStefano Zampini } 454206656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 454306656605SStefano Zampini /* coarse basis functions */ 454406656605SStefano Zampini for (i=0;i<n_constraints;i++) { 454506656605SStefano Zampini PetscScalar *y; 454606656605SStefano Zampini 4547ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 454806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 454906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 455006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 455106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 455206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 455306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 455406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 45554f1b2e48SStefano Zampini PetscInt j; 45564f1b2e48SStefano Zampini 455706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 455806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 455906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 456006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 456106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 45624f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 456306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 456406656605SStefano Zampini } 456506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 456606656605SStefano Zampini } 456706656605SStefano Zampini } 456880677318SStefano Zampini if (n_constraints) { 456980677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 457080677318SStefano Zampini } 45714f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 457272b8c272SStefano Zampini 457372b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 457472b8c272SStefano Zampini if (pcbddc->benign_n) { 457572b8c272SStefano Zampini Mat B0_B,B0_BPHI; 457672b8c272SStefano Zampini IS is_dummy; 45771683a169SBarry Smith const PetscScalar *data; 457872b8c272SStefano Zampini PetscInt j; 457972b8c272SStefano Zampini 458072b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 45817dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 458272b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 458372b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 458486c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 45851683a169SBarry Smith ierr = MatDenseGetArrayRead(B0_BPHI,&data);CHKERRQ(ierr); 458672b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 458772b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 458872b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 458972b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 459072b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 459172b8c272SStefano Zampini } 459272b8c272SStefano Zampini } 45931683a169SBarry Smith ierr = MatDenseRestoreArrayRead(B0_BPHI,&data);CHKERRQ(ierr); 459472b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 459572b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 459672b8c272SStefano Zampini } 4597019a44ceSStefano Zampini 459806656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 45993301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4600ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 4601ffd830a3SStefano Zampini PetscScalar *marray; 460206656605SStefano Zampini 460306656605SStefano Zampini if (n_constraints) { 4604ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 460506656605SStefano Zampini 4606abc8f43dSstefano_zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 460706656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 4608ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 460916f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 461006656605SStefano Zampini if (n_vertices) { 4611ffd830a3SStefano Zampini Mat S_VCT; 461206656605SStefano Zampini 461306656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 4614ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 461516f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 461606656605SStefano Zampini } 4617ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 46185b782168SStefano Zampini } else { 46195b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 462006656605SStefano Zampini } 462116f15bc4SStefano Zampini if (n_vertices && n_R) { 4622ffd830a3SStefano Zampini PetscScalar *av,*marray; 4623ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 4624ffd830a3SStefano Zampini PetscInt n; 4625ffd830a3SStefano Zampini PetscBool flg_row; 462606656605SStefano Zampini 4627ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 4628af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4629ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4630ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 4631ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4632ffd830a3SStefano Zampini for (i=0;i<n;i++) { 4633ffd830a3SStefano Zampini PetscInt j; 4634ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 4635ffd830a3SStefano Zampini } 4636ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4637ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4638ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 463906656605SStefano Zampini } 464006656605SStefano Zampini 4641ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 4642abc8f43dSstefano_zampini if (n_vertices) { 4643ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4644ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 4645ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 4646ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 464706656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4648c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 464906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 465006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 465106656605SStefano Zampini } 4652ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4653abc8f43dSstefano_zampini } 46545b782168SStefano Zampini if (B_C) { 4655ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 4656ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 4657ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 4658ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 4659ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4660c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 4661ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4662ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 466306656605SStefano Zampini } 4664ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 46655b782168SStefano Zampini } 466606656605SStefano Zampini /* coarse basis functions */ 466706656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 466806656605SStefano Zampini PetscScalar *y; 466906656605SStefano Zampini 4670ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 467106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 467206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 467306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 467406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 467506656605SStefano Zampini if (i<n_vertices) { 467606656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 467706656605SStefano Zampini } 467806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 467906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 468006656605SStefano Zampini 468106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 468206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 468306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 468406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 468506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 468606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 468706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 468806656605SStefano Zampini } 468906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 469006656605SStefano Zampini } 4691ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 4692ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 469306656605SStefano Zampini } 4694a6e023c1Sstefano_zampini 4695d62866d3SStefano Zampini /* free memory */ 469688ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 469706656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 469806656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 469906656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 470006656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 4701d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4702d62866d3SStefano Zampini if (n_vertices) { 4703d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 4704d62866d3SStefano Zampini } 4705d62866d3SStefano Zampini if (n_constraints) { 4706d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 4707d62866d3SStefano Zampini } 47088ead10e4SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CorrectionSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 47098ead10e4SStefano Zampini 471088ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 471188ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 471288ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 4713d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 471488ebb749SStefano Zampini Mat coarse_sub_mat; 471525084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 471688ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 471788ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 471888ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 47198bec7fa6SStefano Zampini Mat C_B,CPHI; 47208bec7fa6SStefano Zampini IS is_dummy; 47218bec7fa6SStefano Zampini Vec mones; 472288ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 472388ebb749SStefano Zampini PetscReal real_value; 472488ebb749SStefano Zampini 4725a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 4726a3df083aSStefano Zampini Mat A; 4727a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 47287dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 47297dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 47307dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 47317dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4732a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 4733a3df083aSStefano Zampini } else { 473488ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 473588ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 473688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 473788ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4738a3df083aSStefano Zampini } 473988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 474088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 4741ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 474288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 474388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 474488ebb749SStefano Zampini } 474588ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 474688ebb749SStefano Zampini 474725084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47483301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 474925084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4750ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 475188ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 475288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 475388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 475488ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 475588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 475688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 475788ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 475888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 475988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 476088ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 476188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 476288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 476388ebb749SStefano Zampini } else { 476488ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 476588ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 476688ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 476788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 476888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 476988ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 477088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 477188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 477288ebb749SStefano Zampini } 477388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 477488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 477588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4776511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 47774f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4778fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 47791683a169SBarry Smith const PetscScalar *data2; 47801683a169SBarry Smith PetscScalar *data; 47814f1b2e48SStefano Zampini PetscInt j; 4782d12edf2fSStefano Zampini 47834f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 47847dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4785d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 478686c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4787d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 47881683a169SBarry Smith ierr = MatDenseGetArrayRead(B0_BPHI,&data2);CHKERRQ(ierr); 47894f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 47904f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4791d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 47924f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 47934f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 47944f1b2e48SStefano Zampini } 4795d12edf2fSStefano Zampini } 4796d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 47971683a169SBarry Smith ierr = MatDenseRestoreArrayRead(B0_BPHI,&data2);CHKERRQ(ierr); 4798d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4799d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4800d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4801d12edf2fSStefano Zampini } 4802d12edf2fSStefano Zampini #if 0 4803d12edf2fSStefano Zampini { 4804d12edf2fSStefano Zampini PetscViewer viewer; 4805d12edf2fSStefano Zampini char filename[256]; 4806ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4807d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4808a7414863SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4809ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4810ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4811ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4812d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 4813a7414863SStefano Zampini if (pcbddc->coarse_phi_B) { 4814ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4815ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 481672b8c272SStefano Zampini } 4817ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4818ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4819ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4820ffd830a3SStefano Zampini } 4821ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4822ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4823ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4824ffd830a3SStefano Zampini } 482572b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4826ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4827ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4828ffd830a3SStefano Zampini } 4829fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->local_mat,"A");CHKERRQ(ierr); 4830fb6280fbSStefano Zampini ierr = MatView(pcbddc->local_mat,viewer);CHKERRQ(ierr); 4831fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->ConstraintMatrix,"C");CHKERRQ(ierr); 4832fb6280fbSStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,viewer);CHKERRQ(ierr); 4833fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_I_local,"I");CHKERRQ(ierr); 4834fb6280fbSStefano Zampini ierr = ISView(pcis->is_I_local,viewer);CHKERRQ(ierr); 4835fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_B_local,"B");CHKERRQ(ierr); 4836fb6280fbSStefano Zampini ierr = ISView(pcis->is_B_local,viewer);CHKERRQ(ierr); 4837fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->is_R_local,"R");CHKERRQ(ierr); 4838fb6280fbSStefano Zampini ierr = ISView(pcbddc->is_R_local,viewer);CHKERRQ(ierr); 4839d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4840d12edf2fSStefano Zampini } 4841d12edf2fSStefano Zampini #endif 484281d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 48438bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 48441575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 484506656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 48468bec7fa6SStefano Zampini 48478bec7fa6SStefano Zampini /* check constraints */ 4848a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 48497dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 48504f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 48518bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4852a00504b5SStefano Zampini } else { 4853a00504b5SStefano Zampini PetscScalar *data; 4854a00504b5SStefano Zampini Mat tmat; 4855a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4856a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4857a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4858a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4859a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4860a00504b5SStefano Zampini } 48618bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 48628bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 48638bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 48648bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4865bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4866ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4867bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4868bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4869bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4870bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4871bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 487288ebb749SStefano Zampini } 48738bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 48748bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 48758bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 48768bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 487725084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 487888ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 487988ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 488088ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 488188ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 488288ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 488388ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 488488ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 488588ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 488688ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 488788ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4888ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 488988ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 489088ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 489188ebb749SStefano Zampini } 489288ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 489388ebb749SStefano Zampini } 48947ebab0bbSStefano Zampini /* FINAL CUDA support (we cannot currently mix viennacl and cuda vectors */ 48957ebab0bbSStefano Zampini { 48967ebab0bbSStefano Zampini PetscBool gpu; 48977ebab0bbSStefano Zampini 48987ebab0bbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->vec1_N,VECSEQCUDA,&gpu);CHKERRQ(ierr); 48997ebab0bbSStefano Zampini if (gpu) { 49007ebab0bbSStefano Zampini if (pcbddc->local_auxmat1) { 49017ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->local_auxmat1,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->local_auxmat1);CHKERRQ(ierr); 49027ebab0bbSStefano Zampini } 49037ebab0bbSStefano Zampini if (pcbddc->local_auxmat2) { 49047ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->local_auxmat2,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 49057ebab0bbSStefano Zampini } 49067ebab0bbSStefano Zampini if (pcbddc->coarse_phi_B) { 49077ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 49087ebab0bbSStefano Zampini } 49097ebab0bbSStefano Zampini if (pcbddc->coarse_phi_D) { 49107ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 49117ebab0bbSStefano Zampini } 49127ebab0bbSStefano Zampini if (pcbddc->coarse_psi_B) { 49137ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 49147ebab0bbSStefano Zampini } 49157ebab0bbSStefano Zampini if (pcbddc->coarse_psi_D) { 49167ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 49177ebab0bbSStefano Zampini } 49187ebab0bbSStefano Zampini } 49197ebab0bbSStefano Zampini } 49208629588bSStefano Zampini /* get back data */ 49218629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 492288ebb749SStefano Zampini PetscFunctionReturn(0); 492388ebb749SStefano Zampini } 492488ebb749SStefano Zampini 49257dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4926aa0d41d4SStefano Zampini { 4927d65f70fdSStefano Zampini Mat *work_mat; 4928d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4929d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4930c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4931aa0d41d4SStefano Zampini PetscErrorCode ierr; 4932aa0d41d4SStefano Zampini 4933aa0d41d4SStefano Zampini PetscFunctionBegin; 4934d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4935d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4936d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4937d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4938aa0d41d4SStefano Zampini 4939d65f70fdSStefano Zampini if (!rsorted) { 4940906d46d4SStefano Zampini const PetscInt *idxs; 4941906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4942aa0d41d4SStefano Zampini 4943d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4944d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4945d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4946d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4947aa0d41d4SStefano Zampini } 4948d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4949d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4950d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4951d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4952aa0d41d4SStefano Zampini } 4953d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4954d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4955d65f70fdSStefano Zampini } else { 4956d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4957d65f70fdSStefano Zampini isrow_s = isrow; 4958aa0d41d4SStefano Zampini } 4959906d46d4SStefano Zampini 4960d65f70fdSStefano Zampini if (!csorted) { 4961d65f70fdSStefano Zampini if (isrow == iscol) { 4962d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4963d65f70fdSStefano Zampini iscol_s = isrow_s; 4964d65f70fdSStefano Zampini } else { 4965d65f70fdSStefano Zampini const PetscInt *idxs; 4966d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4967906d46d4SStefano Zampini 4968d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4969d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4970d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4971d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4972d65f70fdSStefano Zampini } 4973d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4974d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4975d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4976d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4977d65f70fdSStefano Zampini } 4978d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4979d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4980d65f70fdSStefano Zampini } 4981d65f70fdSStefano Zampini } else { 4982d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4983d65f70fdSStefano Zampini iscol_s = iscol; 4984d65f70fdSStefano Zampini } 4985d65f70fdSStefano Zampini 49867dae84e0SHong Zhang ierr = MatCreateSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4987d65f70fdSStefano Zampini 4988d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4989906d46d4SStefano Zampini Mat new_mat; 4990d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4991906d46d4SStefano Zampini 4992d65f70fdSStefano Zampini if (!rsorted) { 4993d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4994d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4995d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4996d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4997906d46d4SStefano Zampini } 4998d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4999d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 5000d65f70fdSStefano Zampini } else { 5001d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 5002906d46d4SStefano Zampini } 5003d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 5004d65f70fdSStefano Zampini 5005d65f70fdSStefano Zampini if (!csorted) { 5006d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 5007d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 5008d65f70fdSStefano Zampini is_perm_c = is_perm_r; 5009d65f70fdSStefano Zampini } else { 5010d65f70fdSStefano Zampini PetscInt *idxs_c,i; 5011f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 5012d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 5013d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 5014d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 5015d65f70fdSStefano Zampini } 5016d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 5017d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 5018d65f70fdSStefano Zampini } 5019d65f70fdSStefano Zampini } else { 5020d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 5021d65f70fdSStefano Zampini } 5022d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 5023d65f70fdSStefano Zampini 5024d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 5025d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 5026d65f70fdSStefano Zampini work_mat[0] = new_mat; 5027d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 5028d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 5029d65f70fdSStefano Zampini } 5030d65f70fdSStefano Zampini 5031d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 5032d65f70fdSStefano Zampini *B = work_mat[0]; 5033d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 5034d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 5035d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 5036d65f70fdSStefano Zampini PetscFunctionReturn(0); 5037d65f70fdSStefano Zampini } 5038d65f70fdSStefano Zampini 50395e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 5040aa0d41d4SStefano Zampini { 5041aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 50425e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5043022d8d2bSstefano_zampini Mat new_mat,lA; 50445e8657edSStefano Zampini IS is_local,is_global; 5045d65f70fdSStefano Zampini PetscInt local_size; 5046d65f70fdSStefano Zampini PetscBool isseqaij; 5047aa0d41d4SStefano Zampini PetscErrorCode ierr; 5048aa0d41d4SStefano Zampini 5049aa0d41d4SStefano Zampini PetscFunctionBegin; 5050aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 50515e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 50525e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 5053b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 5054aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 50557dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 5056aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 5057906d46d4SStefano Zampini 5058906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 5059906d46d4SStefano Zampini Vec x,x_change; 5060906d46d4SStefano Zampini PetscReal error; 5061906d46d4SStefano Zampini 50625e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 5063906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 50645e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 5065e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5066e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5067d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 506888428137SStefano Zampini if (!pcbddc->change_interior) { 506988428137SStefano Zampini const PetscScalar *x,*y,*v; 507088428137SStefano Zampini PetscReal lerror = 0.; 507188428137SStefano Zampini PetscInt i; 507288428137SStefano Zampini 507388428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 507488428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 507588428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 507688428137SStefano Zampini for (i=0;i<local_size;i++) 507788428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 507888428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 507988428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 508088428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 508188428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 508288428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5083637e8532SStefano Zampini if (error > PETSC_SMALL) { 5084637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 50856080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on I: %1.6e",error); 5086637e8532SStefano Zampini } else { 50876080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on I: %1.6e",error); 5088637e8532SStefano Zampini } 5089637e8532SStefano Zampini } 509088428137SStefano Zampini } 5091e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5092e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5093906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 5094906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 5095637e8532SStefano Zampini if (error > PETSC_SMALL) { 5096637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 50976080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e",error); 5098637e8532SStefano Zampini } else { 50996080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on N: %1.6e",error); 5100637e8532SStefano Zampini } 5101637e8532SStefano Zampini } 5102906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 5103906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 5104906d46d4SStefano Zampini } 5105906d46d4SStefano Zampini 5106022d8d2bSstefano_zampini /* lA is present if we are setting up an inner BDDC for a saddle point FETI-DP */ 5107022d8d2bSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 5108022d8d2bSstefano_zampini 510922d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 51107ebab0bbSStefano Zampini ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 511122d5777bSStefano Zampini if (isseqaij) { 5112a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 5113a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 5114022d8d2bSstefano_zampini if (lA) { 5115022d8d2bSstefano_zampini Mat work; 5116022d8d2bSstefano_zampini ierr = MatPtAP(lA,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 5117022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 5118022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 5119022d8d2bSstefano_zampini } 5120aa0d41d4SStefano Zampini } else { 5121a00504b5SStefano Zampini Mat work_mat; 51221cf9b237SStefano Zampini 5123a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 5124aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 5125a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 51261d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 5127022d8d2bSstefano_zampini if (lA) { 5128022d8d2bSstefano_zampini Mat work; 5129022d8d2bSstefano_zampini ierr = MatConvert(lA,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 5130022d8d2bSstefano_zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 5131022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 5132022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 5133022d8d2bSstefano_zampini } 5134aa0d41d4SStefano Zampini } 51353301b35fSStefano Zampini if (matis->A->symmetric_set) { 51363301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 5137e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 51383301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 5139e496cd5dSStefano Zampini #endif 51403301b35fSStefano Zampini } 5141d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 5142aa0d41d4SStefano Zampini PetscFunctionReturn(0); 5143aa0d41d4SStefano Zampini } 5144aa0d41d4SStefano Zampini 51458ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 5146a64d13efSStefano Zampini { 5147a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5148a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5149d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 515053892102SStefano Zampini PetscInt *idx_R_local=NULL; 51513a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 51523a50541eSStefano Zampini PetscInt vbs,bs; 51536816873aSStefano Zampini PetscBT bitmask=NULL; 5154a64d13efSStefano Zampini PetscErrorCode ierr; 5155a64d13efSStefano Zampini 5156a64d13efSStefano Zampini PetscFunctionBegin; 5157b23d619eSStefano Zampini /* 5158b23d619eSStefano Zampini No need to setup local scatters if 5159b23d619eSStefano Zampini - primal space is unchanged 5160b23d619eSStefano Zampini AND 5161b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 5162b23d619eSStefano Zampini AND 5163b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 5164b23d619eSStefano Zampini */ 5165b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 5166f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 5167f4ddd8eeSStefano Zampini } 5168f4ddd8eeSStefano Zampini /* destroy old objects */ 5169f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 5170f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 5171f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 5172a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 5173b371cd4fSStefano Zampini n_B = pcis->n_B; 5174b371cd4fSStefano Zampini n_D = pcis->n - n_B; 5175b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 51763a50541eSStefano Zampini 5177a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 51786816873aSStefano Zampini 517953892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 5180b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 5181854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 5182a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 5183a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 51840e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 5185a64d13efSStefano Zampini } 5186a64d13efSStefano Zampini 5187a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 51884641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 51896816873aSStefano Zampini idx_R_local[n_R++] = i; 5190a64d13efSStefano Zampini } 5191a64d13efSStefano Zampini } 5192df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 5193df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 51946816873aSStefano Zampini 5195df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5196df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 51976816873aSStefano Zampini } 51983a50541eSStefano Zampini 51993a50541eSStefano Zampini /* Block code */ 52003a50541eSStefano Zampini vbs = 1; 52013a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 52023a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 52033a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 52043a50541eSStefano Zampini PetscInt *vary; 5205b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 5206785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 5207580bdb30SBarry Smith ierr = PetscArrayzero(vary,pcis->n/bs);CHKERRQ(ierr); 5208d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 5209d3df7717SStefano 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 */ 52100e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 5211d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 52123a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 52133a50541eSStefano Zampini is_blocked = PETSC_FALSE; 52143a50541eSStefano Zampini break; 52153a50541eSStefano Zampini } 52163a50541eSStefano Zampini } 5217d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 5218d3df7717SStefano Zampini } else { 5219d3df7717SStefano Zampini /* Verify directly the R set */ 5220d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 5221d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 5222d3df7717SStefano Zampini for (j=1; j<bs; j++) { 5223d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 5224d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 5225d3df7717SStefano Zampini break; 5226d3df7717SStefano Zampini } 5227d3df7717SStefano Zampini } 5228d3df7717SStefano Zampini } 5229d3df7717SStefano Zampini } 52303a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 52313a50541eSStefano Zampini vbs = bs; 52323a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 52333a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 52343a50541eSStefano Zampini } 52353a50541eSStefano Zampini } 52363a50541eSStefano Zampini } 52373a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 5238b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5239df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 524053892102SStefano Zampini 5241df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5242df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 524353892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 5244df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 524553892102SStefano Zampini } else { 52463a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 524753892102SStefano Zampini } 5248a64d13efSStefano Zampini 5249a64d13efSStefano Zampini /* print some info if requested */ 5250a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 5251a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5252a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 52531575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5254a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 52556080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %D, dirichlet_size = %D, boundary_size = %D\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 52566080607fSStefano 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); 5257a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5258a64d13efSStefano Zampini } 5259a64d13efSStefano Zampini 5260a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 5261b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 52626816873aSStefano Zampini IS is_aux1,is_aux2; 52636816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 52646816873aSStefano Zampini 52653a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5266854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 5267854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 5268a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 52694641a718SStefano Zampini for (i=0; i<n_D; i++) { 52704641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 52714641a718SStefano Zampini } 5272a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5273a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 52744641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 52754641a718SStefano Zampini aux_array1[j++] = i; 5276a64d13efSStefano Zampini } 5277a64d13efSStefano Zampini } 5278a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 5279a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5280a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 52814641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 52824641a718SStefano Zampini aux_array2[j++] = i; 5283a64d13efSStefano Zampini } 5284a64d13efSStefano Zampini } 5285a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5286a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 52879448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 5288a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 5289a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 5290a64d13efSStefano Zampini 52918eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 5292785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 5293a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 52944641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 52954641a718SStefano Zampini aux_array1[j++] = i; 5296a64d13efSStefano Zampini } 5297a64d13efSStefano Zampini } 5298a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 52999448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 5300a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 5301a64d13efSStefano Zampini } 53024641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 53033a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5304d62866d3SStefano Zampini } else { 5305df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 53066816873aSStefano Zampini IS tis; 53076816873aSStefano Zampini PetscInt schur_size; 53086816873aSStefano Zampini 5309df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 53106816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 53119448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 53126816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 53136816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 53146816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 53159448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 53166816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 5317d62866d3SStefano Zampini } 5318d62866d3SStefano Zampini } 5319a64d13efSStefano Zampini PetscFunctionReturn(0); 5320a64d13efSStefano Zampini } 5321a64d13efSStefano Zampini 53226d9e27e4SStefano Zampini static PetscErrorCode MatNullSpacePropagateAny_Private(Mat A, IS is, Mat B) 532392cccca0SStefano Zampini { 532492cccca0SStefano Zampini MatNullSpace NullSpace; 532592cccca0SStefano Zampini Mat dmat; 532692cccca0SStefano Zampini const Vec *nullvecs; 532792cccca0SStefano Zampini Vec v,v2,*nullvecs2; 53286d9e27e4SStefano Zampini VecScatter sct = NULL; 5329eb06acf8SStefano Zampini PetscContainer c; 5330eb06acf8SStefano Zampini PetscScalar *ddata; 5331295df10fSStefano Zampini PetscInt k,nnsp_size,bsiz,bsiz2,n,N,bs; 533292cccca0SStefano Zampini PetscBool nnsp_has_cnst; 533392cccca0SStefano Zampini PetscErrorCode ierr; 533492cccca0SStefano Zampini 533592cccca0SStefano Zampini PetscFunctionBegin; 53366d9e27e4SStefano Zampini if (!is && !B) { /* MATIS */ 53376d9e27e4SStefano Zampini Mat_IS* matis = (Mat_IS*)A->data; 53386d9e27e4SStefano Zampini 53396d9e27e4SStefano Zampini if (!B) { 53406d9e27e4SStefano Zampini ierr = MatISGetLocalMat(A,&B);CHKERRQ(ierr); 53416d9e27e4SStefano Zampini } 53426d9e27e4SStefano Zampini sct = matis->cctx; 53436d9e27e4SStefano Zampini ierr = PetscObjectReference((PetscObject)sct);CHKERRQ(ierr); 53446d9e27e4SStefano Zampini } else { 534592cccca0SStefano Zampini ierr = MatGetNullSpace(B,&NullSpace);CHKERRQ(ierr); 534692cccca0SStefano Zampini if (!NullSpace) { 534792cccca0SStefano Zampini ierr = MatGetNearNullSpace(B,&NullSpace);CHKERRQ(ierr); 534892cccca0SStefano Zampini } 534992cccca0SStefano Zampini if (NullSpace) PetscFunctionReturn(0); 53506d9e27e4SStefano Zampini } 535192cccca0SStefano Zampini ierr = MatGetNullSpace(A,&NullSpace);CHKERRQ(ierr); 535292cccca0SStefano Zampini if (!NullSpace) { 535392cccca0SStefano Zampini ierr = MatGetNearNullSpace(A,&NullSpace);CHKERRQ(ierr); 535492cccca0SStefano Zampini } 535592cccca0SStefano Zampini if (!NullSpace) PetscFunctionReturn(0); 53566d9e27e4SStefano Zampini 535792cccca0SStefano Zampini ierr = MatCreateVecs(A,&v,NULL);CHKERRQ(ierr); 535892cccca0SStefano Zampini ierr = MatCreateVecs(B,&v2,NULL);CHKERRQ(ierr); 53596d9e27e4SStefano Zampini if (!sct) { 53609448b7f1SJunchao Zhang ierr = VecScatterCreate(v,is,v2,NULL,&sct);CHKERRQ(ierr); 53616d9e27e4SStefano Zampini } 536292cccca0SStefano Zampini ierr = MatNullSpaceGetVecs(NullSpace,&nnsp_has_cnst,&nnsp_size,(const Vec**)&nullvecs);CHKERRQ(ierr); 5363295df10fSStefano Zampini bsiz = bsiz2 = nnsp_size+!!nnsp_has_cnst; 536492cccca0SStefano Zampini ierr = PetscMalloc1(bsiz,&nullvecs2);CHKERRQ(ierr); 536592cccca0SStefano Zampini ierr = VecGetBlockSize(v2,&bs);CHKERRQ(ierr); 536692cccca0SStefano Zampini ierr = VecGetSize(v2,&N);CHKERRQ(ierr); 536792cccca0SStefano Zampini ierr = VecGetLocalSize(v2,&n);CHKERRQ(ierr); 5368eb06acf8SStefano Zampini ierr = PetscMalloc1(n*bsiz,&ddata);CHKERRQ(ierr); 536992cccca0SStefano Zampini for (k=0;k<nnsp_size;k++) { 5370eb06acf8SStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)B),bs,n,N,ddata + n*k,&nullvecs2[k]);CHKERRQ(ierr); 537192cccca0SStefano Zampini ierr = VecScatterBegin(sct,nullvecs[k],nullvecs2[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 537292cccca0SStefano Zampini ierr = VecScatterEnd(sct,nullvecs[k],nullvecs2[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 537392cccca0SStefano Zampini } 537492cccca0SStefano Zampini if (nnsp_has_cnst) { 5375eb06acf8SStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)B),bs,n,N,ddata + n*nnsp_size,&nullvecs2[nnsp_size]);CHKERRQ(ierr); 537692cccca0SStefano Zampini ierr = VecSet(nullvecs2[nnsp_size],1.0);CHKERRQ(ierr); 537792cccca0SStefano Zampini } 5378295df10fSStefano Zampini ierr = PCBDDCOrthonormalizeVecs(&bsiz2,nullvecs2);CHKERRQ(ierr); 5379295df10fSStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)B),PETSC_FALSE,bsiz2,nullvecs2,&NullSpace);CHKERRQ(ierr); 5380295df10fSStefano Zampini 5381eb06acf8SStefano Zampini ierr = MatCreateDense(PetscObjectComm((PetscObject)B),n,PETSC_DECIDE,N,bsiz2,ddata,&dmat);CHKERRQ(ierr); 5382eb06acf8SStefano Zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)B),&c);CHKERRQ(ierr); 5383eb06acf8SStefano Zampini ierr = PetscContainerSetPointer(c,ddata);CHKERRQ(ierr); 5384eb06acf8SStefano Zampini ierr = PetscContainerSetUserDestroy(c,PetscContainerUserDestroyDefault);CHKERRQ(ierr); 5385eb06acf8SStefano Zampini ierr = PetscObjectCompose((PetscObject)dmat,"_PBDDC_Null_dmat_arr",(PetscObject)c);CHKERRQ(ierr); 5386eb06acf8SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 538792cccca0SStefano Zampini ierr = PetscObjectCompose((PetscObject)NullSpace,"_PBDDC_Null_dmat",(PetscObject)dmat);CHKERRQ(ierr); 538892cccca0SStefano Zampini ierr = MatDestroy(&dmat);CHKERRQ(ierr); 5389eb06acf8SStefano Zampini 539092cccca0SStefano Zampini for (k=0;k<bsiz;k++) { 539192cccca0SStefano Zampini ierr = VecDestroy(&nullvecs2[k]);CHKERRQ(ierr); 539292cccca0SStefano Zampini } 539392cccca0SStefano Zampini ierr = PetscFree(nullvecs2);CHKERRQ(ierr); 539492cccca0SStefano Zampini ierr = MatSetNearNullSpace(B,NullSpace);CHKERRQ(ierr); 539592cccca0SStefano Zampini ierr = MatNullSpaceDestroy(&NullSpace);CHKERRQ(ierr); 539692cccca0SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 539792cccca0SStefano Zampini ierr = VecDestroy(&v2);CHKERRQ(ierr); 539892cccca0SStefano Zampini ierr = VecScatterDestroy(&sct);CHKERRQ(ierr); 539992cccca0SStefano Zampini PetscFunctionReturn(0); 540092cccca0SStefano Zampini } 5401304d26faSStefano Zampini 5402684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 5403304d26faSStefano Zampini { 5404304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5405304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 5406304d26faSStefano Zampini PC pc_temp; 5407304d26faSStefano Zampini Mat A_RR; 540892cccca0SStefano Zampini MatNullSpace nnsp; 5409f4ddd8eeSStefano Zampini MatReuse reuse; 5410304d26faSStefano Zampini PetscScalar m_one = -1.0; 5411304d26faSStefano Zampini PetscReal value; 541204708bb6SStefano Zampini PetscInt n_D,n_R; 541392cccca0SStefano Zampini PetscBool issbaij,opts; 5414304d26faSStefano Zampini PetscErrorCode ierr; 541592cccca0SStefano Zampini void (*f)(void) = 0; 5416312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 5417e604994aSStefano Zampini size_t len; 5418304d26faSStefano Zampini 5419304d26faSStefano Zampini PetscFunctionBegin; 542043371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalSolvers[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 54216d9e27e4SStefano Zampini /* approximate solver, propagate NearNullSpace if needed */ 54226d9e27e4SStefano Zampini if (!pc->setupcalled && (pcbddc->NullSpace_corr[0] || pcbddc->NullSpace_corr[2])) { 54236d9e27e4SStefano Zampini MatNullSpace gnnsp1,gnnsp2; 54246d9e27e4SStefano Zampini PetscBool lhas,ghas; 54256d9e27e4SStefano Zampini 54266d9e27e4SStefano Zampini ierr = MatGetNearNullSpace(pcbddc->local_mat,&nnsp);CHKERRQ(ierr); 54276d9e27e4SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&gnnsp1);CHKERRQ(ierr); 54286d9e27e4SStefano Zampini ierr = MatGetNullSpace(pc->pmat,&gnnsp2);CHKERRQ(ierr); 54296d9e27e4SStefano Zampini lhas = nnsp ? PETSC_TRUE : PETSC_FALSE; 54306d9e27e4SStefano Zampini ierr = MPIU_Allreduce(&lhas,&ghas,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 54316d9e27e4SStefano Zampini if (!ghas && (gnnsp1 || gnnsp2)) { 54326d9e27e4SStefano Zampini ierr = MatNullSpacePropagateAny_Private(pc->pmat,NULL,NULL);CHKERRQ(ierr); 54336d9e27e4SStefano Zampini } 54346d9e27e4SStefano Zampini } 54356d9e27e4SStefano Zampini 5436e604994aSStefano Zampini /* compute prefixes */ 5437e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 5438e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 5439e604994aSStefano Zampini if (!pcbddc->current_level) { 5440a126751eSBarry Smith ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,sizeof(dir_prefix));CHKERRQ(ierr); 5441a126751eSBarry Smith ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,sizeof(neu_prefix));CHKERRQ(ierr); 5442a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,"pc_bddc_dirichlet_",sizeof(dir_prefix));CHKERRQ(ierr); 5443a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,"pc_bddc_neumann_",sizeof(neu_prefix));CHKERRQ(ierr); 5444e604994aSStefano Zampini } else { 544535529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 5446e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5447e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 5448312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5449312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 5450a126751eSBarry Smith /* Nonstandard use of PetscStrncpy() to only copy a portion of the input string */ 545134d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 545234d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5453a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,"pc_bddc_dirichlet_",sizeof(dir_prefix));CHKERRQ(ierr); 5454a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,"pc_bddc_neumann_",sizeof(neu_prefix));CHKERRQ(ierr); 5455a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,str_level,sizeof(dir_prefix));CHKERRQ(ierr); 5456a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,str_level,sizeof(neu_prefix));CHKERRQ(ierr); 5457e604994aSStefano Zampini } 5458e604994aSStefano Zampini 5459304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 5460684f6988SStefano Zampini if (dirichlet) { 5461d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5462450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 54636080607fSStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 5464450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 5465a3df083aSStefano Zampini Mat A_IIn; 5466a3df083aSStefano Zampini 5467a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 5468a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 5469a3df083aSStefano Zampini pcis->A_II = A_IIn; 5470a3df083aSStefano Zampini } 5471450f8f5eSStefano Zampini } 54723301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 5473d1e098c7SStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric);CHKERRQ(ierr); 5474964fefecSStefano Zampini } 5475ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 5476964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 547792cccca0SStefano Zampini opts = PETSC_FALSE; 5478304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 547992cccca0SStefano Zampini opts = PETSC_TRUE; 5480304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 5481304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 5482304d26faSStefano Zampini /* default */ 5483304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 5484e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 54852f37b69bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->pA_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 5486304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 54879577ea80SStefano Zampini if (issbaij) { 54889577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 54899577ea80SStefano Zampini } else { 5490304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 54919577ea80SStefano Zampini } 5492399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->ksp_D,pc->erroriffailure);CHKERRQ(ierr); 549392cccca0SStefano Zampini } 549492cccca0SStefano Zampini ierr = MatSetOptionsPrefix(pcis->pA_II,((PetscObject)pcbddc->ksp_D)->prefix);CHKERRQ(ierr); 54952f37b69bSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->pA_II);CHKERRQ(ierr); 5496304d26faSStefano Zampini /* Allow user's customization */ 549792cccca0SStefano Zampini if (opts) { 5498304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 549992cccca0SStefano Zampini } 55006d9e27e4SStefano Zampini ierr = MatGetNearNullSpace(pcis->pA_II,&nnsp);CHKERRQ(ierr); 55016d9e27e4SStefano Zampini if (pcbddc->NullSpace_corr[0] && !nnsp) { /* approximate solver, propagate NearNullSpace */ 55026d9e27e4SStefano Zampini ierr = MatNullSpacePropagateAny_Private(pcbddc->local_mat,pcis->is_I_local,pcis->pA_II);CHKERRQ(ierr); 550392cccca0SStefano Zampini } 550492cccca0SStefano Zampini ierr = MatGetNearNullSpace(pcis->pA_II,&nnsp);CHKERRQ(ierr); 550592cccca0SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5506cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 550792cccca0SStefano Zampini if (f && pcbddc->mat_graph->cloc && !nnsp) { 5508cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5509cd18cfedSStefano Zampini const PetscInt *idxs; 5510cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5511cd18cfedSStefano Zampini 5512cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcis->is_I_local,&nl);CHKERRQ(ierr); 5513cd18cfedSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5514cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5515cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5516cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5517cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5518cd18cfedSStefano Zampini } 5519cd18cfedSStefano Zampini } 5520cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5521cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5522cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5523cd18cfedSStefano Zampini } 5524b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5525df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5526d62866d3SStefano Zampini 5527df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 5528d5574798SStefano Zampini } 552992cccca0SStefano Zampini 5530304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5531304d26faSStefano Zampini if (!n_D) { 5532304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5533304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5534304d26faSStefano Zampini } 553593120301SStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 5536304d26faSStefano Zampini /* set ksp_D into pcis data */ 5537304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 553892cccca0SStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 5539304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 5540684f6988SStefano Zampini } 5541304d26faSStefano Zampini 5542304d26faSStefano Zampini /* NEUMANN PROBLEM */ 5543684f6988SStefano Zampini A_RR = 0; 5544684f6988SStefano Zampini if (neumann) { 5545d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 554604708bb6SStefano Zampini PetscInt ibs,mbs; 55470aa714b2SStefano Zampini PetscBool issbaij, reuse_neumann_solver; 554804708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 55490aa714b2SStefano Zampini 55500aa714b2SStefano Zampini reuse_neumann_solver = PETSC_FALSE; 55510aa714b2SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 55520aa714b2SStefano Zampini IS iP; 55530aa714b2SStefano Zampini 55540aa714b2SStefano Zampini reuse_neumann_solver = PETSC_TRUE; 55550aa714b2SStefano Zampini ierr = PetscObjectQuery((PetscObject)sub_schurs->A,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 55560aa714b2SStefano Zampini if (iP) reuse_neumann_solver = PETSC_FALSE; 55570aa714b2SStefano Zampini } 5558f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 55598ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 5560f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 5561f4ddd8eeSStefano Zampini PetscInt nn_R; 556281d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 5563f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5564f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 5565f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 5566f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 5567f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5568f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5569f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 5570727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 5571f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5572f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5573f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 5574f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 5575f4ddd8eeSStefano Zampini } 5576f4ddd8eeSStefano Zampini } 5577f4ddd8eeSStefano Zampini /* last check */ 5578d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 5579f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5580f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5581f4ddd8eeSStefano Zampini } 5582f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 5583f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5584f4ddd8eeSStefano Zampini } 5585365a3a41SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection 5586365a3a41SStefano Zampini TODO: Get Rid of these conversions */ 5587af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 5588af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 558904708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 559004708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 559104708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 559204708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 559304708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 5594af732b37SStefano Zampini } else { 5595511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 55966816873aSStefano Zampini } 559704708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 559804708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 559904708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 5600365a3a41SStefano Zampini ierr = MatConvert(matis->A,mbs > 1 ? MATSEQBAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 560104708bb6SStefano Zampini } else { 5602365a3a41SStefano Zampini ierr = MatConvert(pcbddc->local_mat,mbs > 1 ? MATSEQBAIJ : MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 560304708bb6SStefano Zampini } 560404708bb6SStefano Zampini } 5605a00504b5SStefano Zampini /* extract A_RR */ 56060aa714b2SStefano Zampini if (reuse_neumann_solver) { 5607a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5608a00504b5SStefano Zampini 5609a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 561016e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5611a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 561216e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 561316e386b8SStefano Zampini } else { 56147dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 5615a00504b5SStefano Zampini } 5616a00504b5SStefano Zampini } else { 5617a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5618a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 5619a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5620a00504b5SStefano Zampini } 5621a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 56227dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 562316e386b8SStefano Zampini } 56243301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 5625d1e098c7SStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric);CHKERRQ(ierr); 56266816873aSStefano Zampini } 562792cccca0SStefano Zampini opts = PETSC_FALSE; 5628f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 562992cccca0SStefano Zampini opts = PETSC_TRUE; 5630304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 5631304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 5632304d26faSStefano Zampini /* default */ 5633304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 5634e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 5635304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 56369577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 56379577ea80SStefano Zampini if (issbaij) { 56389577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 56399577ea80SStefano Zampini } else { 5640304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 56419577ea80SStefano Zampini } 5642399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->ksp_R,pc->erroriffailure);CHKERRQ(ierr); 564392cccca0SStefano Zampini } 56442f37b69bSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 564592cccca0SStefano Zampini ierr = MatSetOptionsPrefix(A_RR,((PetscObject)pcbddc->ksp_R)->prefix);CHKERRQ(ierr); 564692cccca0SStefano Zampini if (opts) { /* Allow user's customization once */ 5647304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 564892cccca0SStefano Zampini } 56496d9e27e4SStefano Zampini ierr = MatGetNearNullSpace(A_RR,&nnsp);CHKERRQ(ierr); 56506d9e27e4SStefano Zampini if (pcbddc->NullSpace_corr[2] && !nnsp) { /* approximate solver, propagate NearNullSpace */ 56516d9e27e4SStefano Zampini ierr = MatNullSpacePropagateAny_Private(pcbddc->local_mat,pcbddc->is_R_local,A_RR);CHKERRQ(ierr); 565292cccca0SStefano Zampini } 565392cccca0SStefano Zampini ierr = MatGetNearNullSpace(A_RR,&nnsp);CHKERRQ(ierr); 565492cccca0SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5655cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 565692cccca0SStefano Zampini if (f && pcbddc->mat_graph->cloc && !nnsp) { 5657cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5658cd18cfedSStefano Zampini const PetscInt *idxs; 5659cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5660cd18cfedSStefano Zampini 5661cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcbddc->is_R_local,&nl);CHKERRQ(ierr); 5662cd18cfedSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5663cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5664cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5665cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5666cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5667cd18cfedSStefano Zampini } 5668cd18cfedSStefano Zampini } 5669cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5670cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5671cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5672cd18cfedSStefano Zampini } 567392cccca0SStefano Zampini 5674304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5675304d26faSStefano Zampini if (!n_R) { 5676304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5677304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5678304d26faSStefano Zampini } 5679df4d28bfSStefano Zampini /* Reuse solver if it is present */ 56800aa714b2SStefano Zampini if (reuse_neumann_solver) { 5681df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5682d62866d3SStefano Zampini 5683df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 5684d62866d3SStefano Zampini } 568593120301SStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 5686684f6988SStefano Zampini } 5687304d26faSStefano Zampini 5688684f6988SStefano Zampini if (pcbddc->dbg_flag) { 5689684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 56901575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5691684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5692684f6988SStefano Zampini } 56938ead10e4SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalSolvers[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 5694c7017625SStefano Zampini 5695c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 5696c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 5697c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 5698c7017625SStefano Zampini } 5699c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 5700c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 5701c7017625SStefano Zampini } 5702c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 5703c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 5704c7017625SStefano Zampini } 5705c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 5706c7017625SStefano Zampini if (pcbddc->dbg_flag) { 5707684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 57080fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 57090fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 57100fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 5711c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 57120fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 57130fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 5714e604994aSStefano 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); 5715304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5716304d26faSStefano Zampini } 5717684f6988SStefano Zampini if (neumann) { /* Neumann */ 57180fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 57190fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 57200fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 5721c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 57220fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 57230fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 5724e604994aSStefano 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); 5725304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5726304d26faSStefano Zampini } 5727684f6988SStefano Zampini } 57285cbda25cSStefano Zampini /* free Neumann problem's matrix */ 57295cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5730304d26faSStefano Zampini PetscFunctionReturn(0); 5731304d26faSStefano Zampini } 5732304d26faSStefano Zampini 573380677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 5734674ae819SStefano Zampini { 5735674ae819SStefano Zampini PetscErrorCode ierr; 5736674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5737be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5738b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 5739674ae819SStefano Zampini 5740674ae819SStefano Zampini PetscFunctionBegin; 5741b334f244SStefano Zampini if (!reuse_solver) { 574280677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 574320c7b377SStefano Zampini } 574480677318SStefano Zampini if (!pcbddc->switch_static) { 574580677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 574680677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 574780677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 574820c7b377SStefano Zampini } 5749b334f244SStefano Zampini if (!reuse_solver) { 575080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 575180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 575220c7b377SStefano Zampini } else { 5753df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5754be83ff47SStefano Zampini 5755df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5756df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 575720c7b377SStefano Zampini } 5758be83ff47SStefano Zampini } else { 575980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 576080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 576180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 576280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 576380677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 576480677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 576580677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 576680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 576780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5768674ae819SStefano Zampini } 5769674ae819SStefano Zampini } 5770b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 577180677318SStefano Zampini if (applytranspose) { 577280677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 577380677318SStefano Zampini } else { 577480677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 577580677318SStefano Zampini } 5776c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec1_R);CHKERRQ(ierr); 5777be83ff47SStefano Zampini } else { 5778df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5779be83ff47SStefano Zampini 5780be83ff47SStefano Zampini if (applytranspose) { 5781df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5782be83ff47SStefano Zampini } else { 5783df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5784be83ff47SStefano Zampini } 5785be83ff47SStefano Zampini } 578680677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 578780677318SStefano Zampini if (!pcbddc->switch_static) { 5788b334f244SStefano Zampini if (!reuse_solver) { 578980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 579080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5791be83ff47SStefano Zampini } else { 5792df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5793be83ff47SStefano Zampini 5794df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5795df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5796be83ff47SStefano Zampini } 579780677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 579880677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 579980677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 580080677318SStefano Zampini } 580180677318SStefano Zampini } else { 580280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 580380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 580480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 580580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 580680677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 580780677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 580880677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 580980677318SStefano Zampini } 581080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 581180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 581280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 581380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5814674ae819SStefano Zampini } 5815674ae819SStefano Zampini PetscFunctionReturn(0); 5816674ae819SStefano Zampini } 5817674ae819SStefano Zampini 5818dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 5819dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 5820674ae819SStefano Zampini { 5821674ae819SStefano Zampini PetscErrorCode ierr; 5822674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5823674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 5824674ae819SStefano Zampini const PetscScalar zero = 0.0; 5825674ae819SStefano Zampini 5826674ae819SStefano Zampini PetscFunctionBegin; 5827dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 58284fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5829dc359a40SStefano Zampini if (applytranspose) { 5830674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 58318eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 5832dc359a40SStefano Zampini } else { 5833674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 5834674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 583515aaf578SStefano Zampini } 58364fee134fSStefano Zampini } else { 58374fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 58384fee134fSStefano Zampini } 5839efc2fbd9SStefano Zampini 5840efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 58414f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5842efc2fbd9SStefano Zampini PetscScalar *array; 58434f1b2e48SStefano Zampini PetscInt j; 5844efc2fbd9SStefano Zampini 5845efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 58464f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 5847efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5848efc2fbd9SStefano Zampini } 5849efc2fbd9SStefano Zampini 585012edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 585112edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 585212edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 585312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 585412edc857SStefano Zampini 58559f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 585612edc857SStefano Zampini if (pcbddc->coarse_ksp) { 585751694757SStefano Zampini Mat coarse_mat; 5858964fefecSStefano Zampini Vec rhs,sol; 585951694757SStefano Zampini MatNullSpace nullsp; 586027b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 5861964fefecSStefano Zampini 586227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 586327b6a85dSStefano Zampini PC coarse_pc; 586427b6a85dSStefano Zampini 586527b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 586627b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 586727b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 586827b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 586927b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 587027b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 58713bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 587227b6a85dSStefano Zampini } 587327b6a85dSStefano Zampini } 5874964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 5875964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 587651694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 587712edc857SStefano Zampini if (applytranspose) { 58789a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 5879964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 5880c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->coarse_ksp,pc,sol);CHKERRQ(ierr); 58819bfcb8eaSStefano Zampini ierr = MatGetTransposeNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 58829bfcb8eaSStefano Zampini if (nullsp) { 58839bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 58849bfcb8eaSStefano Zampini } 58852701bc32SStefano Zampini } else { 58869bfcb8eaSStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 58871f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 58882701bc32SStefano Zampini PC coarse_pc; 58892701bc32SStefano Zampini 58909bfcb8eaSStefano Zampini if (nullsp) { 58919bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 58929bfcb8eaSStefano Zampini } 58932701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 58942701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 58953e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 58962701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 589712edc857SStefano Zampini } else { 5898964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 5899c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->coarse_ksp,pc,sol);CHKERRQ(ierr); 59009bfcb8eaSStefano Zampini if (nullsp) { 59019bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 59029bfcb8eaSStefano Zampini } 590312edc857SStefano Zampini } 59042701bc32SStefano Zampini } 59051d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 590627b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 590727b6a85dSStefano Zampini PC coarse_pc; 590827b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 590927b6a85dSStefano Zampini 591027b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 591127b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 591227b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 59133bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 591427b6a85dSStefano Zampini } 591512edc857SStefano Zampini } 5916674ae819SStefano Zampini 5917674ae819SStefano Zampini /* Local solution on R nodes */ 59184fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 591980677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 59209f00e9b4SStefano Zampini } 59219f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 59229f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 592312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5924674ae819SStefano Zampini 59254fee134fSStefano Zampini /* Sum contributions from the two levels */ 59264fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5927dc359a40SStefano Zampini if (applytranspose) { 5928dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5929dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5930dc359a40SStefano Zampini } else { 5931674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 59328eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5933dc359a40SStefano Zampini } 5934efc2fbd9SStefano Zampini /* store p0 */ 59354f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5936efc2fbd9SStefano Zampini PetscScalar *array; 59374f1b2e48SStefano Zampini PetscInt j; 5938efc2fbd9SStefano Zampini 5939efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 59404f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 5941efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5942efc2fbd9SStefano Zampini } 59434fee134fSStefano Zampini } else { /* expand the coarse solution */ 59444fee134fSStefano Zampini if (applytranspose) { 59454fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 59464fee134fSStefano Zampini } else { 59474fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 59484fee134fSStefano Zampini } 59494fee134fSStefano Zampini } 5950674ae819SStefano Zampini PetscFunctionReturn(0); 5951674ae819SStefano Zampini } 5952674ae819SStefano Zampini 595312edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 5954674ae819SStefano Zampini { 5955674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 595612edc857SStefano Zampini Vec from,to; 59577ebab0bbSStefano Zampini const PetscScalar *array; 59587ebab0bbSStefano Zampini PetscErrorCode ierr; 5959674ae819SStefano Zampini 5960674ae819SStefano Zampini PetscFunctionBegin; 596112edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 596212edc857SStefano Zampini from = pcbddc->coarse_vec; 596312edc857SStefano Zampini to = pcbddc->vec1_P; 596412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 596512edc857SStefano Zampini Vec tvec; 596658da7f69SStefano Zampini 596758da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 596858da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 596912edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 59707ebab0bbSStefano Zampini ierr = VecGetArrayRead(tvec,&array);CHKERRQ(ierr); 597158da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 59727ebab0bbSStefano Zampini ierr = VecRestoreArrayRead(tvec,&array);CHKERRQ(ierr); 597312edc857SStefano Zampini } 597412edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 597512edc857SStefano Zampini from = pcbddc->vec1_P; 597612edc857SStefano Zampini to = pcbddc->coarse_vec; 597712edc857SStefano Zampini } 597812edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 5979674ae819SStefano Zampini PetscFunctionReturn(0); 5980674ae819SStefano Zampini } 5981674ae819SStefano Zampini 598212edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 5983674ae819SStefano Zampini { 5984674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 598512edc857SStefano Zampini Vec from,to; 59867ebab0bbSStefano Zampini const PetscScalar *array; 59877ebab0bbSStefano Zampini PetscErrorCode ierr; 5988674ae819SStefano Zampini 5989674ae819SStefano Zampini PetscFunctionBegin; 599012edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 599112edc857SStefano Zampini from = pcbddc->coarse_vec; 599212edc857SStefano Zampini to = pcbddc->vec1_P; 599312edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 599412edc857SStefano Zampini from = pcbddc->vec1_P; 599512edc857SStefano Zampini to = pcbddc->coarse_vec; 599612edc857SStefano Zampini } 599712edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 599812edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 599912edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 600012edc857SStefano Zampini Vec tvec; 600158da7f69SStefano Zampini 600212edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 60037ebab0bbSStefano Zampini ierr = VecGetArrayRead(to,&array);CHKERRQ(ierr); 600458da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 60057ebab0bbSStefano Zampini ierr = VecRestoreArrayRead(to,&array);CHKERRQ(ierr); 600658da7f69SStefano Zampini } 600758da7f69SStefano Zampini } else { 600858da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 600958da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 601012edc857SStefano Zampini } 601112edc857SStefano Zampini } 6012674ae819SStefano Zampini PetscFunctionReturn(0); 6013674ae819SStefano Zampini } 6014674ae819SStefano Zampini 6015674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 6016674ae819SStefano Zampini { 6017674ae819SStefano Zampini PetscErrorCode ierr; 6018674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 6019674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6020674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 6021984c4197SStefano Zampini /* one and zero */ 6022984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 6023984c4197SStefano Zampini /* space to store constraints and their local indices */ 60249162d606SStefano Zampini PetscScalar *constraints_data; 60259162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 60269162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 60279162d606SStefano Zampini PetscInt *constraints_n; 6028984c4197SStefano Zampini /* iterators */ 6029b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 6030984c4197SStefano Zampini /* BLAS integers */ 6031e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 6032e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 6033c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 6034727cdba6SStefano Zampini /* reuse */ 60350e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 60360e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 6037984c4197SStefano Zampini /* change of basis */ 6038b3d85658SStefano Zampini PetscBool qr_needed; 60399162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 6040984c4197SStefano Zampini /* auxiliary stuff */ 604164efe560SStefano Zampini PetscInt *nnz,*is_indices; 60428a0068c3SStefano Zampini PetscInt ncc; 6043984c4197SStefano Zampini /* some quantities */ 604445a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 6045a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 604657715f18SStefano Zampini PetscReal tol; /* tolerance for retaining eigenmodes */ 6047984c4197SStefano Zampini 6048674ae819SStefano Zampini PetscFunctionBegin; 604957715f18SStefano Zampini tol = PetscSqrtReal(PETSC_SMALL); 60508e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 60518e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 60528e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 605316909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 6054088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 6055088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 60560e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 60570e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 6058580bdb30SBarry Smith ierr = PetscArraycpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc);CHKERRQ(ierr); 6059580bdb30SBarry Smith ierr = PetscArraycpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc);CHKERRQ(ierr); 60600e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 6061088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 6062cf5a6209SStefano Zampini 6063cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 60649162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 6065cf5a6209SStefano Zampini MatNullSpace nearnullsp; 6066cf5a6209SStefano Zampini const Vec *nearnullvecs; 6067cf5a6209SStefano Zampini Vec *localnearnullsp; 6068cf5a6209SStefano Zampini PetscScalar *array; 6069cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 6070cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 6071674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 6072b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 6073674ae819SStefano Zampini PetscScalar *work; 6074674ae819SStefano Zampini PetscReal *singular_vals; 6075674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6076674ae819SStefano Zampini PetscReal *rwork; 6077674ae819SStefano Zampini #endif 607855080a34SStefano Zampini PetscScalar *temp_basis = NULL,*correlation_mat = NULL; 6079964fefecSStefano Zampini PetscBLASInt dummy_int=1; 6080964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 608155080a34SStefano Zampini PetscBool use_pod = PETSC_FALSE; 6082674ae819SStefano Zampini 608355080a34SStefano Zampini /* MKL SVD with same input gives different results on different processes! */ 608455080a34SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) || defined(PETSC_HAVE_MKL) 608555080a34SStefano Zampini use_pod = PETSC_TRUE; 608655080a34SStefano Zampini #endif 6087674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 6088d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 6089e4d548c7SStefano Zampini /* print some info */ 60905c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 6091e4d548c7SStefano Zampini PetscInt nv; 6092e4d548c7SStefano Zampini 6093c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6094e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 6095e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6096e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 60976080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%D)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 60986080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%D)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 60996080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%D)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 6100e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6101e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6102e4d548c7SStefano Zampini } 6103e4d548c7SStefano Zampini 6104d06fc5fdSStefano Zampini /* free unneeded index sets */ 6105d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 6106d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 6107674ae819SStefano Zampini } 6108d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 6109d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 6110d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 6111d06fc5fdSStefano Zampini } 6112d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 6113d06fc5fdSStefano Zampini n_ISForEdges = 0; 6114d06fc5fdSStefano Zampini } 6115d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 6116d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 6117d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 6118d06fc5fdSStefano Zampini } 6119d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 6120d06fc5fdSStefano Zampini n_ISForFaces = 0; 6121d06fc5fdSStefano Zampini } 612270022509SStefano Zampini 6123674ae819SStefano Zampini /* check if near null space is attached to global mat */ 61246d9e27e4SStefano Zampini if (pcbddc->use_nnsp) { 6125674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 61266d9e27e4SStefano Zampini } else nearnullsp = NULL; 61276d9e27e4SStefano Zampini 6128674ae819SStefano Zampini if (nearnullsp) { 6129674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 6130f4ddd8eeSStefano Zampini /* remove any stored info */ 6131f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 6132f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 6133f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 6134f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 6135f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 6136473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 6137f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 6138f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 6139f4ddd8eeSStefano Zampini } 6140984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 6141984c4197SStefano Zampini nnsp_size = 0; 6142674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 6143674ae819SStefano Zampini } 6144984c4197SStefano Zampini /* get max number of constraints on a single cc */ 6145984c4197SStefano Zampini max_constraints = nnsp_size; 6146984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 6147984c4197SStefano Zampini 6148674ae819SStefano Zampini /* 6149674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 61509162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 61519162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 61529162d606SStefano Zampini There can be multiple constraints per connected component 6153674ae819SStefano Zampini */ 6154674ae819SStefano Zampini n_vertices = 0; 6155674ae819SStefano Zampini if (ISForVertices) { 6156674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 6157674ae819SStefano Zampini } 61589162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 61599162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 61609162d606SStefano Zampini 61619162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 61629162d606SStefano Zampini total_counts *= max_constraints; 6163674ae819SStefano Zampini total_counts += n_vertices; 61644641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 61659162d606SStefano Zampini 6166674ae819SStefano Zampini total_counts = 0; 6167674ae819SStefano Zampini max_size_of_constraint = 0; 6168674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 61699162d606SStefano Zampini IS used_is; 6170674ae819SStefano Zampini if (i<n_ISForEdges) { 61719162d606SStefano Zampini used_is = ISForEdges[i]; 6172674ae819SStefano Zampini } else { 61739162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 6174674ae819SStefano Zampini } 61759162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 6176674ae819SStefano Zampini total_counts += j; 6177674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 6178674ae819SStefano Zampini } 61799162d606SStefano 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); 61809162d606SStefano Zampini 6181984c4197SStefano Zampini /* get local part of global near null space vectors */ 6182785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 6183984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 6184984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 6185e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6186e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6187984c4197SStefano Zampini } 6188674ae819SStefano Zampini 6189242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 6190242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 6191a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 6192242a89d7SStefano Zampini 6193984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 6194a773dcb8SStefano Zampini if (!skip_lapack) { 6195674ae819SStefano Zampini PetscScalar temp_work; 6196911cabfeSStefano Zampini 619755080a34SStefano Zampini if (use_pod) { 6198984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 6199785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 6200785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 6201785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 6202674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6203785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 6204674ae819SStefano Zampini #endif 6205674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 6206c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 6207c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 6208674ae819SStefano Zampini lwork = -1; 6209674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6210674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 6211c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 6212674ae819SStefano Zampini #else 6213c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 6214674ae819SStefano Zampini #endif 6215674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6216984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 621755080a34SStefano Zampini } else { 621855080a34SStefano Zampini #if !defined(PETSC_MISSING_LAPACK_GESVD) 6219674ae819SStefano Zampini /* SVD */ 6220674ae819SStefano Zampini PetscInt max_n,min_n; 6221674ae819SStefano Zampini max_n = max_size_of_constraint; 6222984c4197SStefano Zampini min_n = max_constraints; 6223984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 6224674ae819SStefano Zampini min_n = max_size_of_constraint; 6225984c4197SStefano Zampini max_n = max_constraints; 6226674ae819SStefano Zampini } 6227785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 6228674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6229785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 6230674ae819SStefano Zampini #endif 6231674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 6232674ae819SStefano Zampini lwork = -1; 6233e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 6234e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 6235b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 6236674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6237674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 62389162d606SStefano 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)); 6239674ae819SStefano Zampini #else 62409162d606SStefano 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)); 6241674ae819SStefano Zampini #endif 6242674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6243984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 624455080a34SStefano Zampini #else 624555080a34SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"This should not happen"); 6246984c4197SStefano Zampini #endif /* on missing GESVD */ 624755080a34SStefano Zampini } 6248674ae819SStefano Zampini /* Allocate optimal workspace */ 6249674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 6250854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 6251674ae819SStefano Zampini } 6252674ae819SStefano Zampini /* Now we can loop on constraining sets */ 6253674ae819SStefano Zampini total_counts = 0; 62549162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 62559162d606SStefano Zampini constraints_data_ptr[0] = 0; 6256674ae819SStefano Zampini /* vertices */ 62579162d606SStefano Zampini if (n_vertices) { 6258674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6259580bdb30SBarry Smith ierr = PetscArraycpy(constraints_idxs,is_indices,n_vertices);CHKERRQ(ierr); 6260674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 62619162d606SStefano Zampini constraints_n[total_counts] = 1; 62629162d606SStefano Zampini constraints_data[total_counts] = 1.0; 62639162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 62649162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 6265674ae819SStefano Zampini total_counts++; 6266674ae819SStefano Zampini } 6267674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6268674ae819SStefano Zampini n_vertices = total_counts; 6269674ae819SStefano Zampini } 6270984c4197SStefano Zampini 6271674ae819SStefano Zampini /* edges and faces */ 62729162d606SStefano Zampini total_counts_cc = total_counts; 6273911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 62749162d606SStefano Zampini IS used_is; 62759162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 62769162d606SStefano Zampini 6277911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 62789162d606SStefano Zampini used_is = ISForEdges[ncc]; 6279984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 6280674ae819SStefano Zampini } else { 62819162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 6282984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 6283674ae819SStefano Zampini } 6284674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 62859162d606SStefano Zampini 62869162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 62879162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6288984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 6289984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 6290674ae819SStefano Zampini if (nnsp_has_cnst) { 62915b08dc53SStefano Zampini PetscScalar quad_value; 62929162d606SStefano Zampini 6293580bdb30SBarry Smith ierr = PetscArraycpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint);CHKERRQ(ierr); 62949162d606SStefano Zampini idxs_copied = PETSC_TRUE; 62959162d606SStefano Zampini 6296a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 6297674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 6298a773dcb8SStefano Zampini } else { 6299a773dcb8SStefano Zampini quad_value = 1.0; 6300a773dcb8SStefano Zampini } 6301674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 63029162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 6303674ae819SStefano Zampini } 63049162d606SStefano Zampini temp_constraints++; 6305674ae819SStefano Zampini total_counts++; 6306674ae819SStefano Zampini } 6307674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 6308984c4197SStefano Zampini PetscReal real_value; 63099162d606SStefano Zampini PetscScalar *ptr_to_data; 63109162d606SStefano Zampini 6311984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 63129162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 6313674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 63149162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 6315674ae819SStefano Zampini } 6316984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 6317984c4197SStefano Zampini /* check if array is null on the connected component */ 6318e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 63199162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 632057715f18SStefano Zampini if (real_value > tol*size_of_constraint) { /* keep indices and values */ 6321674ae819SStefano Zampini temp_constraints++; 6322674ae819SStefano Zampini total_counts++; 63239162d606SStefano Zampini if (!idxs_copied) { 6324580bdb30SBarry Smith ierr = PetscArraycpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint);CHKERRQ(ierr); 63259162d606SStefano Zampini idxs_copied = PETSC_TRUE; 6326674ae819SStefano Zampini } 6327674ae819SStefano Zampini } 63289162d606SStefano Zampini } 63299162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 633045a1bb75SStefano Zampini valid_constraints = temp_constraints; 6331eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 6332a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 63339162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 63349162d606SStefano Zampini 63359162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 6336a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 63379162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 6338a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 63399162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 6340a773dcb8SStefano Zampini } else { /* perform SVD */ 63419162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 6342674ae819SStefano Zampini 634355080a34SStefano Zampini if (use_pod) { 6344984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 6345984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 6346984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 6347984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 6348984c4197SStefano Zampini from that computed using LAPACKgesvd 6349984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 6350984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 6351580bdb30SBarry Smith ierr = PetscArrayzero(correlation_mat,temp_constraints*temp_constraints);CHKERRQ(ierr); 6352674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 6353e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6354984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6355674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 6356674ae819SStefano Zampini for (k=0;k<j+1;k++) { 63579162d606SStefano 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)); 6358674ae819SStefano Zampini } 6359674ae819SStefano Zampini } 6360e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 6361e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6362e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 6363674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 6364c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 6365674ae819SStefano Zampini #else 6366c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 6367674ae819SStefano Zampini #endif 6368674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6369984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 6370984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 6371674ae819SStefano Zampini j = 0; 637287b3baaaSStefano Zampini while (j < temp_constraints && singular_vals[j]/singular_vals[temp_constraints-1] < tol) j++; 6373674ae819SStefano Zampini total_counts = total_counts-j; 637445a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 6375e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 6376c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 6377c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6378c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 6379c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6380c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 6381c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6382674ae819SStefano Zampini if (j<temp_constraints) { 6383984c4197SStefano Zampini PetscInt ii; 6384984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 6385674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 63869162d606SStefano 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)); 6387674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6388984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 6389674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 63909162d606SStefano 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]; 6391674ae819SStefano Zampini } 6392674ae819SStefano Zampini } 6393674ae819SStefano Zampini } 639455080a34SStefano Zampini } else { 639555080a34SStefano Zampini #if !defined(PETSC_MISSING_LAPACK_GESVD) 6396e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 6397e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6398b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6399674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6400674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 64019162d606SStefano 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)); 6402674ae819SStefano Zampini #else 64039162d606SStefano 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)); 6404674ae819SStefano Zampini #endif 6405984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 6406674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6407984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 6408e310c8b4SStefano Zampini k = temp_constraints; 6409e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 6410674ae819SStefano Zampini j = 0; 641187b3baaaSStefano Zampini while (j < k && singular_vals[k-j-1]/singular_vals[0] < tol) j++; 641245a1bb75SStefano Zampini valid_constraints = k-j; 6413911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 641455080a34SStefano Zampini #else 641555080a34SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"This should not happen"); 6416984c4197SStefano Zampini #endif /* on missing GESVD */ 6417674ae819SStefano Zampini } 6418a773dcb8SStefano Zampini } 641955080a34SStefano Zampini } 64209162d606SStefano Zampini /* update pointers information */ 64219162d606SStefano Zampini if (valid_constraints) { 64229162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 64239162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 64249162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 64259162d606SStefano Zampini /* set change_of_basis flag */ 642645a1bb75SStefano Zampini if (boolforchange) { 6427b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 64289162d606SStefano Zampini } 6429b3d85658SStefano Zampini total_counts_cc++; 643045a1bb75SStefano Zampini } 643145a1bb75SStefano Zampini } 6432984c4197SStefano Zampini /* free workspace */ 64338f1c130eSStefano Zampini if (!skip_lapack) { 6434984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 6435984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6436984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 6437984c4197SStefano Zampini #endif 6438984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 6439984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 6440984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 6441984c4197SStefano Zampini } 6442984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 6443984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 6444984c4197SStefano Zampini } 6445984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 6446cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 6447cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 6448cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 6449cf5a6209SStefano Zampini } 6450cf5a6209SStefano Zampini if (n_ISForFaces) { 6451cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 6452cf5a6209SStefano Zampini } 6453cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 6454cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 6455cf5a6209SStefano Zampini } 6456cf5a6209SStefano Zampini if (n_ISForEdges) { 6457cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 6458cf5a6209SStefano Zampini } 6459cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 646008122e43SStefano Zampini } else { 646108122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 6462984c4197SStefano Zampini 646308122e43SStefano Zampini total_counts = 0; 646408122e43SStefano Zampini n_vertices = 0; 6465d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 6466d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 646708122e43SStefano Zampini } 646808122e43SStefano Zampini max_constraints = 0; 64699162d606SStefano Zampini total_counts_cc = 0; 647008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 647108122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 64729162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 647308122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 647408122e43SStefano Zampini } 64759162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 64769162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 64779162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 64789162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 647974d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 64809162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 64819162d606SStefano Zampini total_counts_cc = 0; 64829162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 64839162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 64849162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 648508122e43SStefano Zampini } 648608122e43SStefano Zampini } 648708122e43SStefano Zampini 64888bec7fa6SStefano Zampini max_size_of_constraint = 0; 64899162d606SStefano 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]); 64909162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 649108122e43SStefano Zampini /* Change of basis */ 6492b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 649308122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 649408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 649508122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 6496b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 649708122e43SStefano Zampini } 649808122e43SStefano Zampini } 649908122e43SStefano Zampini } 650008122e43SStefano Zampini } 6501984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 65024f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 650308122e43SStefano Zampini 65049162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 65059162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 65066080607fSStefano 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); 6507674ae819SStefano Zampini 6508674ae819SStefano Zampini /* Create constraint matrix */ 6509674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 651016f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 6511984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 6512984c4197SStefano Zampini 6513984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 6514a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 65155a52fde0SStefano Zampini qr_needed = pcbddc->use_qr_single; 651674d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 6517984c4197SStefano Zampini total_primal_vertices=0; 6518b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 65199162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 65209162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 652172b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 65229162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 6523b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 652464efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 65259162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 65269162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 6527a717540cSStefano Zampini } 6528b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 652991af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 6530a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 6531a717540cSStefano Zampini qr_needed = PETSC_TRUE; 6532a717540cSStefano Zampini } 6533fa434743SStefano Zampini } else { 6534b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 6535fa434743SStefano Zampini } 6536a717540cSStefano Zampini } 6537b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 6538b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 6539674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 654070022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 65414f1b2e48SStefano 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); 6542580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices);CHKERRQ(ierr); 65430e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 6544984c4197SStefano Zampini 6545984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 654674d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 6547785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 6548984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 654974d5cdf7SStefano Zampini 6550984c4197SStefano Zampini j = total_primal_vertices; 655174d5cdf7SStefano Zampini total_counts = total_primal_vertices; 6552b3d85658SStefano Zampini cum = total_primal_vertices; 65539162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 65544641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 6555b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 6556b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 6557b3d85658SStefano Zampini cum++; 65589162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 655974d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 656074d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 656174d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 656274d5cdf7SStefano Zampini } 65639162d606SStefano Zampini j += constraints_n[i]; 6564674ae819SStefano Zampini } 6565674ae819SStefano Zampini } 6566674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 6567e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->ConstraintMatrix,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 6568674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 6569088faed8SStefano Zampini 6570674ae819SStefano Zampini /* set values in constraint matrix */ 6571984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 65720e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6573674ae819SStefano Zampini } 6574984c4197SStefano Zampini total_counts = total_primal_vertices; 65759162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 65764641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 65779162d606SStefano Zampini PetscInt *cols; 65789162d606SStefano Zampini 65799162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 65809162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 65819162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 65829162d606SStefano Zampini PetscInt row = total_counts+k; 65839162d606SStefano Zampini PetscScalar *vals; 65849162d606SStefano Zampini 65859162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 65869162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 65879162d606SStefano Zampini } 65889162d606SStefano Zampini total_counts += constraints_n[i]; 6589674ae819SStefano Zampini } 6590674ae819SStefano Zampini } 6591674ae819SStefano Zampini /* assembling */ 6592674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6593674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 65947ebab0bbSStefano Zampini ierr = MatViewFromOptions(pcbddc->ConstraintMatrix,(PetscObject)pc,"-pc_bddc_constraint_mat_view");CHKERRQ(ierr); 6595088faed8SStefano Zampini 6596674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 6597674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 6598026de310SStefano Zampini /* dual and primal dofs on a single cc */ 6599984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 6600984c4197SStefano Zampini /* working stuff for GEQRF */ 66015a52fde0SStefano Zampini PetscScalar *qr_basis = NULL,*qr_tau = NULL,*qr_work = NULL,lqr_work_t; 6602984c4197SStefano Zampini PetscBLASInt lqr_work; 6603984c4197SStefano Zampini /* working stuff for UNGQR */ 66045a52fde0SStefano Zampini PetscScalar *gqr_work = NULL,lgqr_work_t; 6605984c4197SStefano Zampini PetscBLASInt lgqr_work; 6606984c4197SStefano Zampini /* working stuff for TRTRS */ 66075a52fde0SStefano Zampini PetscScalar *trs_rhs = NULL; 66083f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 6609984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 6610984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 6611984c4197SStefano Zampini PetscScalar *start_vals; 6612984c4197SStefano Zampini /* working stuff for values insertion */ 66134641a718SStefano Zampini PetscBT is_primal; 661464efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 6615906d46d4SStefano Zampini /* matrix sizes */ 6616906d46d4SStefano Zampini PetscInt global_size,local_size; 6617906d46d4SStefano Zampini /* temporary change of basis */ 6618906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 6619cf5a6209SStefano Zampini /* extra space for debugging */ 66205a52fde0SStefano Zampini PetscScalar *dbg_work = NULL; 6621984c4197SStefano Zampini 6622906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 6623906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 662416f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 6625bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 6626906d46d4SStefano Zampini /* nonzeros for local mat */ 6627bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 66281dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6629bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 66301dd7afcfSStefano Zampini } else { 66311dd7afcfSStefano Zampini const PetscInt *ii; 66321dd7afcfSStefano Zampini PetscInt n; 66331dd7afcfSStefano Zampini PetscBool flg_row; 66341dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 66351dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 66361dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 66371dd7afcfSStefano Zampini } 66389162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 6639a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 66409162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 6641a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 66429162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 6643a717540cSStefano Zampini } else { 66449162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 66459162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 6646a717540cSStefano Zampini } 6647a717540cSStefano Zampini } 6648a717540cSStefano Zampini } 6649906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 6650e1b21442SStefano Zampini ierr = MatSetOption(localChangeOfBasisMatrix,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 6651bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 66521dd7afcfSStefano Zampini /* Set interior change in the matrix */ 66531dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6654bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 6655906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 6656a717540cSStefano Zampini } 66571dd7afcfSStefano Zampini } else { 66581dd7afcfSStefano Zampini const PetscInt *ii,*jj; 66591dd7afcfSStefano Zampini PetscScalar *aa; 66601dd7afcfSStefano Zampini PetscInt n; 66611dd7afcfSStefano Zampini PetscBool flg_row; 66621dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 66631dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 66641dd7afcfSStefano Zampini for (i=0;i<n;i++) { 66651dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 66661dd7afcfSStefano Zampini } 66671dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 66681dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 66691dd7afcfSStefano Zampini } 6670a717540cSStefano Zampini 6671a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6672a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6673a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6674a717540cSStefano Zampini } 6675a717540cSStefano Zampini 6676a717540cSStefano Zampini 6677a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 6678a717540cSStefano Zampini /* 6679a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 6680a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 6681a717540cSStefano Zampini 6682a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 6683a717540cSStefano Zampini 6684a6b551f4SStefano 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) 6685a6b551f4SStefano Zampini 6686a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 6687a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 6688a717540cSStefano Zampini | ... | 6689a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 6690a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 6691a717540cSStefano Zampini 6692a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 6693a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 6694a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 6695a6b551f4SStefano Zampini 6696a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 6697a717540cSStefano Zampini */ 66985a52fde0SStefano Zampini if (qr_needed && max_size_of_constraint) { 6699984c4197SStefano Zampini /* space to store Q */ 6700854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 67014e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 67024e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 6703984c4197SStefano Zampini /* first we issue queries for optimal work */ 67043f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 67053f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 67063f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6707984c4197SStefano Zampini lqr_work = -1; 67083f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 6709984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 6710984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 6711785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 6712984c4197SStefano Zampini lgqr_work = -1; 67133f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 67143f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 67153f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 67163f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 67173f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 6718c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 6719c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to ORGQR/UNGQR Lapack routine %d",(int)lierr); 6720984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 6721785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 6722984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 6723785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 6724a717540cSStefano Zampini /* allocating workspace for check */ 6725a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6726cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 6727a717540cSStefano Zampini } 6728a717540cSStefano Zampini } 6729984c4197SStefano Zampini /* array to store whether a node is primal or not */ 67304641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 6731473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 67320e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 67336080607fSStefano 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); 673439e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 673539e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 673639e2fb2aSStefano Zampini } 673739e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 6738984c4197SStefano Zampini 6739a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 67409162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 67419162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 67424641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 6743984c4197SStefano Zampini /* get constraint info */ 67449162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 6745984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 6746984c4197SStefano Zampini 6747984c4197SStefano Zampini if (pcbddc->dbg_flag) { 67486080607fSStefano 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); 6749674ae819SStefano Zampini } 6750984c4197SStefano Zampini 6751fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 6752a717540cSStefano Zampini 6753a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 6754a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6755580bdb30SBarry Smith ierr = PetscArraycpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs);CHKERRQ(ierr); 6756a717540cSStefano Zampini } 6757984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 6758580bdb30SBarry Smith ierr = PetscArraycpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs);CHKERRQ(ierr); 6759984c4197SStefano Zampini 6760984c4197SStefano Zampini /* compute QR decomposition of constraints */ 67613f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 67623f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 67633f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6764674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 67653f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 6766984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 6767674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6768984c4197SStefano Zampini 6769984c4197SStefano Zampini /* explictly compute R^-T */ 6770580bdb30SBarry Smith ierr = PetscArrayzero(trs_rhs,primal_dofs*primal_dofs);CHKERRQ(ierr); 6771984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 67723f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 67733f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 67743f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 67753f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 6776984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 67773f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 6778984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 6779984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6780984c4197SStefano Zampini 6781a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 67823f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 67833f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 67843f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 67853f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6786984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6787c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 6788c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in ORGQR/UNGQR Lapack routine %d",(int)lierr); 6789984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6790984c4197SStefano Zampini 6791984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 6792984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 6793984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 67943f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 67953f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 67963f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 67973f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 67983f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 67993f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6800984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 68019162d606SStefano 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)); 6802984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6803580bdb30SBarry Smith ierr = PetscArraycpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs);CHKERRQ(ierr); 6804984c4197SStefano Zampini 6805984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 68069162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 6807984c4197SStefano Zampini /* insert cols for primal dofs */ 6808984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 6809984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 68109162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6811906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6812984c4197SStefano Zampini } 6813984c4197SStefano Zampini /* insert cols for dual dofs */ 6814984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 68159162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 6816984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 68179162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6818906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6819984c4197SStefano Zampini j++; 6820674ae819SStefano Zampini } 6821674ae819SStefano Zampini } 6822984c4197SStefano Zampini 6823984c4197SStefano Zampini /* check change of basis */ 6824984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6825984c4197SStefano Zampini PetscInt ii,jj; 6826984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 6827c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 6828c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6829c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 6830c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6831c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 6832c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 6833984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6834cf5a6209SStefano 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)); 6835984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6836984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6837984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6838cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 6839c068d9bbSLisandro 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; 6840674ae819SStefano Zampini } 6841674ae819SStefano Zampini } 6842984c4197SStefano Zampini if (!valid_qr) { 684322d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 6844984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6845984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6846cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 68476080607fSStefano 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); 6848674ae819SStefano Zampini } 6849c068d9bbSLisandro Dalcin if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-(PetscReal)1) > 1.e-12) { 68506080607fSStefano 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); 6851984c4197SStefano Zampini } 6852984c4197SStefano Zampini } 6853984c4197SStefano Zampini } 6854674ae819SStefano Zampini } else { 685522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 6856674ae819SStefano Zampini } 6857674ae819SStefano Zampini } 6858a717540cSStefano Zampini } else { /* simple transformation block */ 6859a717540cSStefano Zampini PetscInt row,col; 6860a6b551f4SStefano Zampini PetscScalar val,norm; 6861a6b551f4SStefano Zampini 6862a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 68639162d606SStefano 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)); 6864a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 68659162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 68669162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6867bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 68689162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 6869906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 68709162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 6871a717540cSStefano Zampini } else { 6872a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 68739162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6874a717540cSStefano Zampini if (row != col) { 68759162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 6876a717540cSStefano Zampini } else { 68779162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 6878a717540cSStefano Zampini } 6879906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 6880a717540cSStefano Zampini } 6881a717540cSStefano Zampini } 6882a717540cSStefano Zampini } 688398a51de6SStefano Zampini if (pcbddc->dbg_flag) { 688422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 6885a717540cSStefano Zampini } 6886674ae819SStefano Zampini } 6887984c4197SStefano Zampini } else { 6888984c4197SStefano Zampini if (pcbddc->dbg_flag) { 68896080607fSStefano 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); 6890674ae819SStefano Zampini } 6891674ae819SStefano Zampini } 6892674ae819SStefano Zampini } 6893a717540cSStefano Zampini 6894a717540cSStefano Zampini /* free workspace */ 6895a717540cSStefano Zampini if (qr_needed) { 6896984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6897cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 6898984c4197SStefano Zampini } 6899984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 6900984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 6901984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 6902984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 6903984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 6904674ae819SStefano Zampini } 6905a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 6906906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6907906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6908906d46d4SStefano Zampini 6909906d46d4SStefano Zampini /* assembling of global change of variable */ 691088c03ad3SStefano Zampini if (!pcbddc->fake_change) { 6911bbb9e6c6SStefano Zampini Mat tmat; 691216f15bc4SStefano Zampini PetscInt bs; 691316f15bc4SStefano Zampini 6914906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 6915906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 6916bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6917bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 6918487b449aSStefano Zampini ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6919487b449aSStefano Zampini ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6920bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6921bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 692216f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 692316f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 6924906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 6925bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 6926487b449aSStefano Zampini ierr = MatConvert(tmat,MATAIJ,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6927bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6928bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6929bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6930e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6931e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6932bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 6933bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 693488c03ad3SStefano Zampini 6935906d46d4SStefano Zampini /* check */ 6936906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 6937906d46d4SStefano Zampini PetscReal error; 6938906d46d4SStefano Zampini Vec x,x_change; 6939906d46d4SStefano Zampini 6940906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 6941906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 6942906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 6943906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 6944e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6945e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6946bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 6947e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6948e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6949906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 6950906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 6951906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 6952637e8532SStefano Zampini if (error > PETSC_SMALL) { 69536080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e",error); 6954637e8532SStefano Zampini } 6955906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 6956906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 6957906d46d4SStefano Zampini } 6958b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 6959b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6960b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6961bf3a8328SStefano Zampini 696213903a91SSatish 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"); 6963b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6964ac632422SStefano Zampini Mat S_new,tmat; 6965bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6966bbb9e6c6SStefano Zampini 6967bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 69687dae84e0SHong Zhang ierr = MatCreateSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 6969bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6970bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 6971bf3a8328SStefano Zampini IS is_V; 6972b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 6973b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 6974b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 6975b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 6976b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 6977bf3a8328SStefano Zampini } 6978bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 6979ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6980b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 6981ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6982bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6983bf3a8328SStefano Zampini const PetscScalar *array; 6984bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6985bf3a8328SStefano Zampini PetscInt i,n_V; 6986bf3a8328SStefano Zampini 6987b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6988b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6989b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6990b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6991b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6992b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6993b087196eSStefano Zampini PetscScalar val; 6994b087196eSStefano Zampini PetscInt idx; 6995b087196eSStefano Zampini 6996b087196eSStefano Zampini idx = idxs_V[i]; 6997b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6998b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6999b087196eSStefano Zampini } 7000b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7001b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7002bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 7003bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 7004bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 7005bf3a8328SStefano Zampini } 7006ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 7007ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 7008ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 7009ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 7010b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 7011ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 7012bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 7013b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 7014bf3a8328SStefano Zampini } 7015ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 7016ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 7017ac632422SStefano Zampini } 7018b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 701988c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 7020b96c3477SStefano Zampini } 7021c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 7022b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 7023c9db6a07SStefano Zampini PetscInt i; 7024c9db6a07SStefano Zampini 7025c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 7026c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 7027c9db6a07SStefano Zampini } 7028c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 7029c9db6a07SStefano Zampini } 7030b96c3477SStefano Zampini } 703116909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 703216909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 703316909a7fSStefano Zampini } else { 7034906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 703516909a7fSStefano Zampini } 70361dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 703727b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 703872b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 703972b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 704072b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 704172b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 704272b8c272SStefano Zampini } 70431dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 704427b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 7045b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 7046b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 7047906d46d4SStefano Zampini } else { 70481dd7afcfSStefano Zampini Mat benign_global = NULL; 704927b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 70501dd7afcfSStefano Zampini Mat M; 70511dd7afcfSStefano Zampini 70529e9b7b1fSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 70539e9b7b1fSStefano Zampini ierr = VecCopy(matis->counter,pcis->vec1_N);CHKERRQ(ierr); 70549e9b7b1fSStefano Zampini ierr = VecReciprocal(pcis->vec1_N);CHKERRQ(ierr); 70559e9b7b1fSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&benign_global);CHKERRQ(ierr); 70569e9b7b1fSStefano Zampini if (pcbddc->benign_change) { 70571dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 70581dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 7059906d46d4SStefano Zampini } else { 70609e9b7b1fSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&M);CHKERRQ(ierr); 70619e9b7b1fSStefano Zampini ierr = MatDiagonalSet(M,pcis->vec1_N,INSERT_VALUES);CHKERRQ(ierr); 7062906d46d4SStefano Zampini } 70639e9b7b1fSStefano Zampini ierr = MatISSetLocalMat(benign_global,M);CHKERRQ(ierr); 70649e9b7b1fSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 70659e9b7b1fSStefano Zampini ierr = MatAssemblyBegin(benign_global,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 70669e9b7b1fSStefano Zampini ierr = MatAssemblyEnd(benign_global,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 70671dd7afcfSStefano Zampini } 70681dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 70691dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 70701dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 707127b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 70721dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 70731dd7afcfSStefano Zampini } 70741dd7afcfSStefano Zampini } 707516909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 707616909a7fSStefano Zampini IS is_global; 707716909a7fSStefano Zampini const PetscInt *gidxs; 707816909a7fSStefano Zampini 707916909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 708016909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 708116909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 70827dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 708316909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 708416909a7fSStefano Zampini } 70851dd7afcfSStefano Zampini } 70861dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 70871dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 7088b9b85e73SStefano Zampini } 7089a717540cSStefano Zampini 709072b8c272SStefano Zampini if (!pcbddc->fake_change) { 70914f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 70924f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 70934f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 70944f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 7095019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 7096019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 7097019a44ceSStefano Zampini pcbddc->local_primal_size++; 7098019a44ceSStefano Zampini } 7099019a44ceSStefano Zampini 7100019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 7101727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 7102727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 7103580bdb30SBarry Smith ierr = PetscArraycmp(pcbddc->local_primal_ref_node,olocal_primal_ref_node,olocal_primal_size_cc,&pcbddc->new_primal_space_local);CHKERRQ(ierr); 7104c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 71050e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 7106580bdb30SBarry Smith ierr = PetscArraycmp(pcbddc->local_primal_ref_mult,olocal_primal_ref_mult,olocal_primal_size_cc,&pcbddc->new_primal_space_local);CHKERRQ(ierr); 7107727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 7108727cdba6SStefano Zampini } 71090e6343abSStefano Zampini } 7110727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 7111b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 711272b8c272SStefano Zampini } 711372b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 7114727cdba6SStefano Zampini 7115a717540cSStefano Zampini /* flush dbg viewer */ 7116b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 7117b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7118b8ffe317SStefano Zampini } 7119a717540cSStefano Zampini 7120e310c8b4SStefano Zampini /* free workspace */ 7121a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 71224641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 712308122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 71249162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 71259162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 712608122e43SStefano Zampini } else { 71279162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 71289162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 71299162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 713008122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 713108122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 71329162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 71339162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 713408122e43SStefano Zampini } 7135674ae819SStefano Zampini PetscFunctionReturn(0); 7136674ae819SStefano Zampini } 7137674ae819SStefano Zampini 7138674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 7139674ae819SStefano Zampini { 714071582508SStefano Zampini ISLocalToGlobalMapping map; 7141674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7142674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 714366da6bd7Sstefano_zampini PetscInt i,N; 714466da6bd7Sstefano_zampini PetscBool rcsr = PETSC_FALSE; 714566da6bd7Sstefano_zampini PetscErrorCode ierr; 7146674ae819SStefano Zampini 7147674ae819SStefano Zampini PetscFunctionBegin; 71488af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 7149b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 71508e61c736SStefano Zampini /* Reset previously computed graph */ 71518e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 7152674ae819SStefano Zampini /* Init local Graph struct */ 71537fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 715471582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 7155be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 7156674ae819SStefano Zampini 71577a0e7b2cSstefano_zampini if (pcbddc->user_primal_vertices_local && !pcbddc->user_primal_vertices) { 71587a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 71597a0e7b2cSstefano_zampini } 7160575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 71616080607fSStefano 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); 71629577ea80SStefano Zampini 7163674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 716466da6bd7Sstefano_zampini if (!pcbddc->mat_graph->xadj && pcbddc->use_local_adj) { 71654d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 71664d379d7bSStefano Zampini PetscInt nvtxs; 7167e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 7168674ae819SStefano Zampini 71692fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 71702fffb893SStefano Zampini if (flg_row) { 71714d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 7172b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 71732fffb893SStefano Zampini } 71742fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 717566da6bd7Sstefano_zampini rcsr = PETSC_TRUE; 7176674ae819SStefano Zampini } 71779b28b941SStefano Zampini if (pcbddc->dbg_flag) { 71789b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7179674ae819SStefano Zampini } 7180674ae819SStefano Zampini 7181ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cdim && !pcbddc->mat_graph->cloc) { 7182ab8c8b98SStefano Zampini PetscReal *lcoords; 7183ab8c8b98SStefano Zampini PetscInt n; 7184ab8c8b98SStefano Zampini MPI_Datatype dimrealtype; 7185ab8c8b98SStefano Zampini 71864f819b78SStefano Zampini /* TODO: support for blocked */ 7187ab8c8b98SStefano 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); 7188ab8c8b98SStefano Zampini ierr = MatGetLocalSize(matis->A,&n,NULL);CHKERRQ(ierr); 7189ab8c8b98SStefano Zampini ierr = PetscMalloc1(pcbddc->mat_graph->cdim*n,&lcoords);CHKERRQ(ierr); 7190ab8c8b98SStefano Zampini ierr = MPI_Type_contiguous(pcbddc->mat_graph->cdim,MPIU_REAL,&dimrealtype);CHKERRQ(ierr); 7191ab8c8b98SStefano Zampini ierr = MPI_Type_commit(&dimrealtype);CHKERRQ(ierr); 7192ab8c8b98SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 7193ab8c8b98SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 7194ab8c8b98SStefano Zampini ierr = MPI_Type_free(&dimrealtype);CHKERRQ(ierr); 7195ab8c8b98SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->coords);CHKERRQ(ierr); 7196ab8c8b98SStefano Zampini 7197ab8c8b98SStefano Zampini pcbddc->mat_graph->coords = lcoords; 7198ab8c8b98SStefano Zampini pcbddc->mat_graph->cloc = PETSC_TRUE; 7199ab8c8b98SStefano Zampini pcbddc->mat_graph->cnloc = n; 7200ab8c8b98SStefano Zampini } 7201ab8c8b98SStefano 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); 72021c7a958bSStefano Zampini pcbddc->mat_graph->active_coords = (PetscBool)(pcbddc->corner_selection && !pcbddc->corner_selected); 7203ab8c8b98SStefano Zampini 7204674ae819SStefano Zampini /* Setup of Graph */ 72054b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 720614f95afaSStefano 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); 7207674ae819SStefano Zampini 72084f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 72094f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 721020c3699dSStefano Zampini PetscInt *local_subs,n,totn; 72114f1b2e48SStefano Zampini 721220c3699dSStefano Zampini ierr = MatGetLocalSize(matis->A,&n,NULL);CHKERRQ(ierr); 721320c3699dSStefano Zampini ierr = PetscMalloc1(n,&local_subs);CHKERRQ(ierr); 721420c3699dSStefano Zampini for (i=0;i<n;i++) local_subs[i] = pcbddc->n_local_subs; 72154f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 72164f1b2e48SStefano Zampini const PetscInt *idxs; 72174f1b2e48SStefano Zampini PetscInt nl,j; 72184f1b2e48SStefano Zampini 72194f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 72204f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 722171582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 72224f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 72234f1b2e48SStefano Zampini } 722420c3699dSStefano Zampini for (i=0,totn=0;i<n;i++) totn = PetscMax(totn,local_subs[i]); 722520c3699dSStefano Zampini pcbddc->mat_graph->n_local_subs = totn + 1; 72264f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 72274f1b2e48SStefano Zampini } 72288af8fcf9SStefano Zampini } 72294f1b2e48SStefano Zampini 7230cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 7231674ae819SStefano Zampini /* Graph's connected components analysis */ 7232674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 723371582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 72344f819b78SStefano Zampini pcbddc->corner_selected = pcbddc->corner_selection; 72358af8fcf9SStefano Zampini } 723666da6bd7Sstefano_zampini if (rcsr) pcbddc->mat_graph->nvtxs_csr = 0; 7237674ae819SStefano Zampini PetscFunctionReturn(0); 7238674ae819SStefano Zampini } 7239674ae819SStefano Zampini 7240295df10fSStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt *nio, Vec vecs[]) 72419a7d3425SStefano Zampini { 7242295df10fSStefano Zampini PetscInt i,j,n; 72439a7d3425SStefano Zampini PetscScalar *alphas; 7244295df10fSStefano Zampini PetscReal norm,*onorms; 72459a7d3425SStefano Zampini PetscErrorCode ierr; 72469a7d3425SStefano Zampini 72479a7d3425SStefano Zampini PetscFunctionBegin; 7248295df10fSStefano Zampini n = *nio; 72498c0031efSStefano Zampini if (!n) PetscFunctionReturn(0); 7250295df10fSStefano Zampini ierr = PetscMalloc2(n,&alphas,n,&onorms);CHKERRQ(ierr); 725192cccca0SStefano Zampini ierr = VecNormalize(vecs[0],&norm);CHKERRQ(ierr); 725292cccca0SStefano Zampini if (norm < PETSC_SMALL) { 7253295df10fSStefano Zampini onorms[0] = 0.0; 725492cccca0SStefano Zampini ierr = VecSet(vecs[0],0.0);CHKERRQ(ierr); 7255295df10fSStefano Zampini } else { 7256295df10fSStefano Zampini onorms[0] = norm; 725792cccca0SStefano Zampini } 7258295df10fSStefano Zampini 72598c0031efSStefano Zampini for (i=1;i<n;i++) { 72608c0031efSStefano Zampini ierr = VecMDot(vecs[i],i,vecs,alphas);CHKERRQ(ierr); 72618c0031efSStefano Zampini for (j=0;j<i;j++) alphas[j] = PetscConj(-alphas[j]); 72628c0031efSStefano Zampini ierr = VecMAXPY(vecs[i],i,alphas,vecs);CHKERRQ(ierr); 726392cccca0SStefano Zampini ierr = VecNormalize(vecs[i],&norm);CHKERRQ(ierr); 726492cccca0SStefano Zampini if (norm < PETSC_SMALL) { 7265295df10fSStefano Zampini onorms[i] = 0.0; 726692cccca0SStefano Zampini ierr = VecSet(vecs[i],0.0);CHKERRQ(ierr); 7267295df10fSStefano Zampini } else { 7268295df10fSStefano Zampini onorms[i] = norm; 726992cccca0SStefano Zampini } 72709a7d3425SStefano Zampini } 7271295df10fSStefano Zampini /* push nonzero vectors at the beginning */ 7272295df10fSStefano Zampini for (i=0;i<n;i++) { 7273295df10fSStefano Zampini if (onorms[i] == 0.0) { 7274295df10fSStefano Zampini for (j=i+1;j<n;j++) { 7275295df10fSStefano Zampini if (onorms[j] != 0.0) { 7276295df10fSStefano Zampini ierr = VecCopy(vecs[j],vecs[i]);CHKERRQ(ierr); 7277295df10fSStefano Zampini onorms[j] = 0.0; 7278295df10fSStefano Zampini } 7279295df10fSStefano Zampini } 7280295df10fSStefano Zampini } 7281295df10fSStefano Zampini } 7282295df10fSStefano Zampini for (i=0,*nio=0;i<n;i++) *nio += onorms[i] != 0.0 ? 1 : 0; 7283295df10fSStefano Zampini ierr = PetscFree2(alphas,onorms);CHKERRQ(ierr); 72849a7d3425SStefano Zampini PetscFunctionReturn(0); 72859a7d3425SStefano Zampini } 72869a7d3425SStefano Zampini 7287bb360cb4SStefano Zampini PetscErrorCode PCBDDCMatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 7288e7931f94SStefano Zampini { 728957de7509SStefano Zampini Mat A; 7290e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 7291e7931f94SStefano Zampini PetscMPIInt size,rank,color; 729252e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 729352e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 7294bb360cb4SStefano Zampini PetscInt im_active,active_procs,N,n,i,j,threshold = 2; 729557de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 729627b6a85dSStefano Zampini PetscInt xadj_count,*count; 729727b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 729827b6a85dSStefano Zampini PetscSubcomm psubcomm; 729927b6a85dSStefano Zampini MPI_Comm subcomm; 730052e5ac9dSStefano Zampini PetscErrorCode ierr; 7301a57a6d2fSStefano Zampini 7302e7931f94SStefano Zampini PetscFunctionBegin; 730357de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 730457de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7305fbfcfee5SBarry 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); 730657de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 730757de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 73086080607fSStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %D",*n_subdomains); 730957de7509SStefano Zampini 731057de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 731157de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 731257de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 731357de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 731457de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 7315bb360cb4SStefano Zampini im_active = !!n; 731657de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 731757de7509SStefano Zampini void_procs = size - active_procs; 731857de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 731957de7509SStefano Zampini if (void_procs) { 732057de7509SStefano Zampini PetscInt ncand; 732157de7509SStefano Zampini 732257de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 732357de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 732457de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 732557de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 732657de7509SStefano Zampini if (!procs_candidates[i]) { 732757de7509SStefano Zampini procs_candidates[ncand++] = i; 732857de7509SStefano Zampini } 732957de7509SStefano Zampini } 733057de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 733157de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 733257de7509SStefano Zampini } 733357de7509SStefano Zampini 7334bb360cb4SStefano Zampini /* number of subdomains requested greater than active processes or matrix size -> just shift the matrix 733514f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 7336bb360cb4SStefano Zampini ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 7337bb360cb4SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1 || N <= *n_subdomains) { 733814f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 733914f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 734014f0bfb9SStefano Zampini else dest = rank; 734157de7509SStefano Zampini if (im_active) { 734257de7509SStefano Zampini issize = 1; 734357de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 734414f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 734557de7509SStefano Zampini } else { 734614f0bfb9SStefano Zampini isidx = dest; 734757de7509SStefano Zampini } 734857de7509SStefano Zampini } else { 734957de7509SStefano Zampini issize = 0; 735057de7509SStefano Zampini isidx = -1; 735157de7509SStefano Zampini } 7352bb360cb4SStefano Zampini if (*n_subdomains != 1) *n_subdomains = active_procs; 735357de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 7354daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 735557de7509SStefano Zampini PetscFunctionReturn(0); 735657de7509SStefano Zampini } 7357c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 7358c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 735927b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 7360e7931f94SStefano Zampini 7361e7931f94SStefano Zampini /* Get info on mapping */ 73623bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 7363e7931f94SStefano Zampini 7364e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 7365785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 7366e7931f94SStefano Zampini xadj[0] = 0; 7367e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 7368785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 7369785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 7370bb360cb4SStefano Zampini ierr = PetscCalloc1(n,&count);CHKERRQ(ierr); 737127b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 737227b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 737327b6a85dSStefano Zampini count[shared[i][j]] += 1; 7374e7931f94SStefano Zampini 737527b6a85dSStefano Zampini xadj_count = 0; 73762b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 737727b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 737827b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 7379d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 7380d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 7381d023bfaeSStefano Zampini xadj_count++; 738227b6a85dSStefano Zampini break; 738327b6a85dSStefano Zampini } 7384e7931f94SStefano Zampini } 7385e7931f94SStefano Zampini } 7386d023bfaeSStefano Zampini xadj[1] = xadj_count; 738727b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 73883bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 7389e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 7390e7931f94SStefano Zampini 73913837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 7392e7931f94SStefano Zampini 739327b6a85dSStefano Zampini /* Restrict work on active processes only */ 739427b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 739527b6a85dSStefano Zampini if (void_procs) { 739627b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 739727b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 739827b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 739927b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 740027b6a85dSStefano Zampini } else { 740127b6a85dSStefano Zampini psubcomm = NULL; 740227b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 740327b6a85dSStefano Zampini } 740427b6a85dSStefano Zampini 740527b6a85dSStefano Zampini v_wgt = NULL; 740627b6a85dSStefano Zampini if (!color) { 7407e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 7408e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 7409e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7410c8587f34SStefano Zampini } else { 741152e5ac9dSStefano Zampini Mat subdomain_adj; 741252e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 741352e5ac9dSStefano Zampini MatPartitioning partitioner; 741427b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 741552e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 741657de7509SStefano Zampini PetscMPIInt size; 7417b0c7d250SStefano Zampini PetscBool aggregate; 7418b0c7d250SStefano Zampini 741927b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 742027b6a85dSStefano Zampini if (void_procs) { 742127b6a85dSStefano Zampini PetscInt prank = rank; 7422785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 742327b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 7424e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 7425e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 7426c8587f34SStefano Zampini } 7427e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 742827b6a85dSStefano Zampini } else { 742927b6a85dSStefano Zampini oldranks = NULL; 743027b6a85dSStefano Zampini } 7431b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 743227b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 7433b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 7434b0c7d250SStefano Zampini PetscMPIInt nrank; 7435b0c7d250SStefano Zampini PetscScalar *vals; 7436b0c7d250SStefano Zampini 743727b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 7438b0c7d250SStefano Zampini lrows = 0; 7439b0c7d250SStefano Zampini if (nrank<redprocs) { 7440b0c7d250SStefano Zampini lrows = size/redprocs; 7441b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 7442b0c7d250SStefano Zampini } 744327b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 7444b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 7445b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7446b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7447b0c7d250SStefano Zampini row = nrank; 7448b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 7449b0c7d250SStefano Zampini cols = adjncy; 7450b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 7451b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 7452b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 7453b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7454b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 745552e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 745652e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 745752e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7458b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 745927b6a85dSStefano Zampini if (use_vwgt) { 746027b6a85dSStefano Zampini Vec v; 746127b6a85dSStefano Zampini const PetscScalar *array; 746227b6a85dSStefano Zampini PetscInt nl; 746327b6a85dSStefano Zampini 746427b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 7465bb360cb4SStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)n,INSERT_VALUES);CHKERRQ(ierr); 746627b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 746727b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 746827b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 746927b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 747027b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 747122db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 747227b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 747327b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 747427b6a85dSStefano Zampini } 7475b0c7d250SStefano Zampini } else { 747627b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 747727b6a85dSStefano Zampini if (use_vwgt) { 747827b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 7479bb360cb4SStefano Zampini v_wgt[0] = n; 748027b6a85dSStefano Zampini } 7481b0c7d250SStefano Zampini } 748222b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 7483e7931f94SStefano Zampini 7484e7931f94SStefano Zampini /* Partition */ 748527b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 7486ce64c636SStefano Zampini #if defined(PETSC_HAVE_PTSCOTCH) 7487ce64c636SStefano Zampini ierr = MatPartitioningSetType(partitioner,MATPARTITIONINGPTSCOTCH);CHKERRQ(ierr); 7488ce64c636SStefano Zampini #elif defined(PETSC_HAVE_PARMETIS) 7489ce64c636SStefano Zampini ierr = MatPartitioningSetType(partitioner,MATPARTITIONINGPARMETIS);CHKERRQ(ierr); 7490ce64c636SStefano Zampini #else 7491ce64c636SStefano Zampini ierr = MatPartitioningSetType(partitioner,MATPARTITIONINGAVERAGE);CHKERRQ(ierr); 7492ce64c636SStefano Zampini #endif 7493e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 749427b6a85dSStefano Zampini if (v_wgt) { 7495e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 7496c8587f34SStefano Zampini } 749757de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 749857de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 7499e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 7500e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 750122b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 7502e7931f94SStefano Zampini 750352e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 75046583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 750552e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 750652e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 750757de7509SStefano Zampini if (!aggregate) { 750857de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 750927b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 751027b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 751127b6a85dSStefano Zampini #endif 751257de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 751327b6a85dSStefano Zampini } else if (oldranks) { 7514b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 751527b6a85dSStefano Zampini } else { 751627b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 751757de7509SStefano Zampini } 751828143c3dSStefano Zampini } else { 75197fb8a5e4SKarl Rupp PetscInt idx = 0; 7520b0c7d250SStefano Zampini PetscMPIInt tag; 7521b0c7d250SStefano Zampini MPI_Request *reqs; 7522b0c7d250SStefano Zampini 7523b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 7524b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 7525b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 752627b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 752728143c3dSStefano Zampini } 75287fb8a5e4SKarl Rupp ierr = MPI_Recv(&idx,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 7529b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7530b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 753157de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 753227b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 753327b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 753427b6a85dSStefano Zampini #endif 75357fb8a5e4SKarl Rupp ranks_send_to_idx[0] = procs_candidates[oldranks[idx]]; 753627b6a85dSStefano Zampini } else if (oldranks) { 75377fb8a5e4SKarl Rupp ranks_send_to_idx[0] = oldranks[idx]; 753827b6a85dSStefano Zampini } else { 75397fb8a5e4SKarl Rupp ranks_send_to_idx[0] = idx; 7540e7931f94SStefano Zampini } 754157de7509SStefano Zampini } 754252e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 7543e7931f94SStefano Zampini /* clean up */ 7544e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 754552e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 7546e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 7547e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 7548e7931f94SStefano Zampini } 754927b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 755057de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 7551e7931f94SStefano Zampini 7552e7931f94SStefano Zampini /* assemble parallel IS for sends */ 7553e7931f94SStefano Zampini i = 1; 755427b6a85dSStefano Zampini if (!color) i=0; 755557de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 7556e7931f94SStefano Zampini PetscFunctionReturn(0); 7557e7931f94SStefano Zampini } 7558e7931f94SStefano Zampini 7559e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 7560e7931f94SStefano Zampini 75611e0482f5SStefano 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[]) 7562e7931f94SStefano Zampini { 756370cf5478SStefano Zampini Mat local_mat; 7564e7931f94SStefano Zampini IS is_sends_internal; 75659d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 75661ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 75679d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 7568e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 7569e7931f94SStefano Zampini PetscInt* l2gmap_indices; 7570e7931f94SStefano Zampini const PetscInt* is_indices; 7571e7931f94SStefano Zampini MatType new_local_type; 7572e7931f94SStefano Zampini /* buffers */ 7573e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 757428143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 75759d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 75761683a169SBarry Smith PetscScalar *ptr_vals,*recv_buffer_vals; 75771683a169SBarry Smith const PetscScalar *send_buffer_vals; 75781ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 7579e7931f94SStefano Zampini /* MPI */ 758028143c3dSStefano Zampini MPI_Comm comm,comm_n; 758128143c3dSStefano Zampini PetscSubcomm subcomm; 7582e569e4e1SStefano Zampini PetscMPIInt n_sends,n_recvs,size; 758328143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 758428143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 75851ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 75861ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 75871ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 7588e7931f94SStefano Zampini PetscErrorCode ierr; 7589e7931f94SStefano Zampini 7590e7931f94SStefano Zampini PetscFunctionBegin; 759157de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7592e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7593fbfcfee5SBarry 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); 759457de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 759557de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 759657de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 759757de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 759857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 75991ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 76001ae86dd6SStefano Zampini if (nvecs) { 76011ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 76021ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 76031ae86dd6SStefano Zampini } 760457de7509SStefano Zampini /* further checks */ 7605e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7606e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 7607e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 7608e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 7609e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 761057de7509SStefano Zampini if (reuse && *mat_n) { 761170cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 761257de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 761370cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 761428143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 761570cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 761670cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 761770cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 761870cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 761970cf5478SStefano Zampini } 7620e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 7621e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 762257de7509SStefano Zampini 7623e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 7624e7931f94SStefano Zampini if (!is_sends) { 762528143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 7626bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 7627c8587f34SStefano Zampini } else { 7628e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 7629e7931f94SStefano Zampini is_sends_internal = is_sends; 7630c8587f34SStefano Zampini } 7631e7931f94SStefano Zampini 7632e7931f94SStefano Zampini /* get comm */ 7633a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 7634e7931f94SStefano Zampini 7635e7931f94SStefano Zampini /* compute number of sends */ 7636e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 7637e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 7638e7931f94SStefano Zampini 7639e7931f94SStefano Zampini /* compute number of receives */ 7640e569e4e1SStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 7641e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&iflags);CHKERRQ(ierr); 7642580bdb30SBarry Smith ierr = PetscArrayzero(iflags,size);CHKERRQ(ierr); 7643e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7644e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 7645e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 7646e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 7647e7931f94SStefano Zampini 764828143c3dSStefano Zampini /* restrict comm if requested */ 764928143c3dSStefano Zampini subcomm = 0; 765028143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 765128143c3dSStefano Zampini if (restrict_comm) { 7652779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 7653779c1cceSStefano Zampini 765428143c3dSStefano Zampini color = 0; 765553a05cb3SStefano Zampini if (restrict_full) { 765653a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 765753a05cb3SStefano Zampini } else { 765853a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 765953a05cb3SStefano Zampini } 7660b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 7661e569e4e1SStefano Zampini subcommsize = size - subcommsize; 766228143c3dSStefano Zampini /* check if reuse has been requested */ 766357de7509SStefano Zampini if (reuse) { 766428143c3dSStefano Zampini if (*mat_n) { 766528143c3dSStefano Zampini PetscMPIInt subcommsize2; 766628143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 766728143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 766828143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 766928143c3dSStefano Zampini } else { 767028143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 767128143c3dSStefano Zampini } 767228143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 7673779c1cceSStefano Zampini PetscMPIInt rank; 7674779c1cceSStefano Zampini 7675779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 767628143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 767728143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 767828143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 7679306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 768028143c3dSStefano Zampini } 768128143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 768228143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 768328143c3dSStefano Zampini } else { 768428143c3dSStefano Zampini comm_n = comm; 768528143c3dSStefano Zampini } 768628143c3dSStefano Zampini 7687e7931f94SStefano Zampini /* prepare send/receive buffers */ 7688e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&ilengths_idxs);CHKERRQ(ierr); 7689580bdb30SBarry Smith ierr = PetscArrayzero(ilengths_idxs,size);CHKERRQ(ierr); 7690e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&ilengths_vals);CHKERRQ(ierr); 7691580bdb30SBarry Smith ierr = PetscArrayzero(ilengths_vals,size);CHKERRQ(ierr); 769228143c3dSStefano Zampini if (nis) { 7693e569e4e1SStefano Zampini ierr = PetscCalloc1(size,&ilengths_idxs_is);CHKERRQ(ierr); 769428143c3dSStefano Zampini } 7695e7931f94SStefano Zampini 769628143c3dSStefano Zampini /* Get data from local matrices */ 76976c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 7698e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 7699e7931f94SStefano Zampini /* 7700e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 7701e7931f94SStefano Zampini send_buffer_idxs should contain: 7702e7931f94SStefano Zampini - MatType_PRIVATE type 7703e7931f94SStefano Zampini - PetscInt size_of_l2gmap 7704e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 7705e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 7706e7931f94SStefano Zampini */ 77076c4ed002SBarry Smith else { 77081683a169SBarry Smith ierr = MatDenseGetArrayRead(local_mat,&send_buffer_vals);CHKERRQ(ierr); 77093bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 7710854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 7711e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 7712e7931f94SStefano Zampini send_buffer_idxs[1] = i; 77133bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7714580bdb30SBarry Smith ierr = PetscArraycpy(&send_buffer_idxs[2],ptr_idxs,i);CHKERRQ(ierr); 77153bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7716e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 7717e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7718e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 7719e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 7720c8587f34SStefano Zampini } 7721c8587f34SStefano Zampini } 7722e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 772328143c3dSStefano Zampini /* additional is (if any) */ 772428143c3dSStefano Zampini if (nis) { 772528143c3dSStefano Zampini PetscMPIInt psum; 772628143c3dSStefano Zampini PetscInt j; 772728143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 772828143c3dSStefano Zampini PetscInt plen; 772928143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 773028143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 773128143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 773228143c3dSStefano Zampini } 7733854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 773428143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 773528143c3dSStefano Zampini PetscInt plen; 773628143c3dSStefano Zampini const PetscInt *is_array_idxs; 773728143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 773828143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 773928143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 7740580bdb30SBarry Smith ierr = PetscArraycpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen);CHKERRQ(ierr); 774128143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 774228143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 774328143c3dSStefano Zampini } 774428143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 774528143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 774628143c3dSStefano Zampini } 774728143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 774828143c3dSStefano Zampini } 77493b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 775028143c3dSStefano Zampini 7751e7931f94SStefano Zampini buf_size_idxs = 0; 7752e7931f94SStefano Zampini buf_size_vals = 0; 775328143c3dSStefano Zampini buf_size_idxs_is = 0; 77541ae86dd6SStefano Zampini buf_size_vecs = 0; 7755e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7756e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 7757e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 775828143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 77591ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 7760e7931f94SStefano Zampini } 7761785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 7762785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 776395ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 77641ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 7765e7931f94SStefano Zampini 7766e7931f94SStefano Zampini /* get new tags for clean communications */ 7767e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 7768e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 776928143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 77701ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 7771e7931f94SStefano Zampini 7772e7931f94SStefano Zampini /* allocate for requests */ 7773785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 7774785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 777595ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 77761ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 7777785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 7778785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 777995ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 77801ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 7781e7931f94SStefano Zampini 7782e7931f94SStefano Zampini /* communications */ 7783e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7784e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 778528143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 77861ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 7787e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7788e7931f94SStefano Zampini source_dest = onodes[i]; 7789e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 7790e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 7791e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7792e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 779328143c3dSStefano Zampini if (nis) { 779457de7509SStefano Zampini source_dest = onodes_is[i]; 779528143c3dSStefano 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); 779628143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 779728143c3dSStefano Zampini } 77981ae86dd6SStefano Zampini if (nvecs) { 77991ae86dd6SStefano Zampini source_dest = onodes[i]; 78001ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 78011ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 78021ae86dd6SStefano Zampini } 7803e7931f94SStefano Zampini } 7804e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7805e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 7806e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 7807ba2698f1SMatthew G. Knepley ierr = MPI_Isend((PetscScalar*)send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 780828143c3dSStefano Zampini if (nis) { 780928143c3dSStefano 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); 781028143c3dSStefano Zampini } 78111ae86dd6SStefano Zampini if (nvecs) { 78121ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 78131ae86dd6SStefano 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); 78141ae86dd6SStefano Zampini } 7815e7931f94SStefano Zampini } 7816e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7817e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 7818e7931f94SStefano Zampini 7819e7931f94SStefano Zampini /* assemble new l2g map */ 7820e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7821e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 78229d30be91SStefano Zampini new_local_rows = 0; 7823e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 78249d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7825e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7826e7931f94SStefano Zampini } 78279d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 7828e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 78299d30be91SStefano Zampini new_local_rows = 0; 7830e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7831580bdb30SBarry Smith ierr = PetscArraycpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,*(ptr_idxs+1));CHKERRQ(ierr); 78329d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7833e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7834e7931f94SStefano Zampini } 78359d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 78369d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 7837e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 7838e7931f94SStefano Zampini 7839e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 7840e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 7841e7931f94SStefano 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) */ 7842e7931f94SStefano Zampini if (n_recvs) { 784328143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 7844e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7845e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7846e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 7847e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 7848e7931f94SStefano Zampini break; 7849e7931f94SStefano Zampini } 7850e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7851e7931f94SStefano Zampini } 7852e7931f94SStefano Zampini switch (new_local_type_private) { 785328143c3dSStefano Zampini case MATDENSE_PRIVATE: 7854e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7855e7931f94SStefano Zampini bs = 1; 7856e7931f94SStefano Zampini break; 7857e7931f94SStefano Zampini case MATAIJ_PRIVATE: 7858e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7859e7931f94SStefano Zampini bs = 1; 7860e7931f94SStefano Zampini break; 7861e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 7862e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 7863e7931f94SStefano Zampini break; 7864e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 7865e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 7866e7931f94SStefano Zampini break; 7867e7931f94SStefano Zampini default: 7868fbfcfee5SBarry Smith SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,PETSC_FUNCTION_NAME); 7869e7931f94SStefano Zampini break; 7870e7931f94SStefano Zampini } 7871ed8ed4edSstefano_zampini } else { /* by default, new_local_type is seqaij */ 7872ed8ed4edSstefano_zampini new_local_type = MATSEQAIJ; 787328143c3dSStefano Zampini bs = 1; 7874e7931f94SStefano Zampini } 7875e7931f94SStefano Zampini 787670cf5478SStefano Zampini /* create MATIS object if needed */ 787757de7509SStefano Zampini if (!reuse) { 7878e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 7879e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 788070cf5478SStefano Zampini } else { 788170cf5478SStefano Zampini /* it also destroys the local matrices */ 788257de7509SStefano Zampini if (*mat_n) { 788370cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 788457de7509SStefano Zampini } else { /* this is a fake object */ 788557de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 788657de7509SStefano Zampini } 788770cf5478SStefano Zampini } 788870cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 7889e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 78909d30be91SStefano Zampini 78919d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 78929d30be91SStefano Zampini 78939d30be91SStefano Zampini /* Global to local map of received indices */ 78949d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 78959d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 78969d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 78979d30be91SStefano Zampini 78989d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 78999d30be91SStefano Zampini buf_size_idxs = 0; 79009d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 79019d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 79029d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 79039d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 79049d30be91SStefano Zampini } 79059d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 79069d30be91SStefano Zampini 79079d30be91SStefano Zampini /* set preallocation */ 79089d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 79099d30be91SStefano Zampini if (!newisdense) { 79109d30be91SStefano Zampini PetscInt *new_local_nnz=0; 79119d30be91SStefano Zampini 79129d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 79139d30be91SStefano Zampini if (n_recvs) { 79149d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 79159d30be91SStefano Zampini } 79169d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 79179d30be91SStefano Zampini PetscInt j; 79189d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 79199d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 79209d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 79219d30be91SStefano Zampini } 79229d30be91SStefano Zampini } else { 79239d30be91SStefano Zampini /* TODO */ 79249d30be91SStefano Zampini } 79259d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 79269d30be91SStefano Zampini } 79279d30be91SStefano Zampini if (new_local_nnz) { 79289d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 79299d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 79309d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 79319d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 79329d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 79339d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 79349d30be91SStefano Zampini } else { 79359d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 79369d30be91SStefano Zampini } 79379d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 79389d30be91SStefano Zampini } else { 79399d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 79409d30be91SStefano Zampini } 7941e7931f94SStefano Zampini 7942e7931f94SStefano Zampini /* set values */ 7943e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 79449d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 7945e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7946e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 7947e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 79489d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 7949e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7950e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7951e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 795228143c3dSStefano Zampini } else { 795328143c3dSStefano Zampini /* TODO */ 7954e7931f94SStefano Zampini } 7955e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7956e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 7957e7931f94SStefano Zampini } 7958e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7959e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 79603b3b1effSJed Brown ierr = MatISRestoreLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 796170cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 796270cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 79639d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 7964e7931f94SStefano Zampini 7965dfd14d43SStefano Zampini #if 0 796628143c3dSStefano Zampini if (!restrict_comm) { /* check */ 7967e7931f94SStefano Zampini Vec lvec,rvec; 7968e7931f94SStefano Zampini PetscReal infty_error; 7969e7931f94SStefano Zampini 79702a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 7971e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 7972e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 7973e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 797470cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 7975e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 7976e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 7977e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 7978e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 7979e7931f94SStefano Zampini } 798028143c3dSStefano Zampini #endif 7981e7931f94SStefano Zampini 798228143c3dSStefano Zampini /* assemble new additional is (if any) */ 798328143c3dSStefano Zampini if (nis) { 798428143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 798528143c3dSStefano Zampini 798628143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7987854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 798828143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 798928143c3dSStefano Zampini psum = 0; 799028143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 799128143c3dSStefano Zampini for (j=0;j<nis;j++) { 799228143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 799328143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 799428143c3dSStefano Zampini psum += plen; 799528143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 799628143c3dSStefano Zampini } 799728143c3dSStefano Zampini } 7998854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 7999854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 800028143c3dSStefano Zampini for (i=1;i<nis;i++) { 800128143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 800228143c3dSStefano Zampini } 8003580bdb30SBarry Smith ierr = PetscArrayzero(count_is,nis);CHKERRQ(ierr); 800428143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 800528143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 800628143c3dSStefano Zampini for (j=0;j<nis;j++) { 800728143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 8008580bdb30SBarry Smith ierr = PetscArraycpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen);CHKERRQ(ierr); 800928143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 801028143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 801128143c3dSStefano Zampini } 801228143c3dSStefano Zampini } 801328143c3dSStefano Zampini for (i=0;i<nis;i++) { 801428143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 8015c3b366b1Sprj- ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr); 801628143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 801728143c3dSStefano Zampini } 801828143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 801928143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 802028143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 802128143c3dSStefano Zampini } 8022e7931f94SStefano Zampini /* free workspace */ 802328143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 8024e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 8025e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 8026e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 8027e7931f94SStefano Zampini if (isdense) { 8028e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 80291683a169SBarry Smith ierr = MatDenseRestoreArrayRead(local_mat,&send_buffer_vals);CHKERRQ(ierr); 80303b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 8031e7931f94SStefano Zampini } else { 8032e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 8033e7931f94SStefano Zampini } 803428143c3dSStefano Zampini if (nis) { 803528143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 803628143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 803728143c3dSStefano Zampini } 80381ae86dd6SStefano Zampini 80391ae86dd6SStefano Zampini if (nvecs) { 80401ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 80411ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 80421ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 80431ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 80441ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 80451ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 80461ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 80471ae86dd6SStefano Zampini /* set values */ 80481ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 80491ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 80501ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 80511ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 80521ae86dd6SStefano Zampini PetscInt j; 80531ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 80541ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 80551ae86dd6SStefano Zampini } 80561ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 80571ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 80581ae86dd6SStefano Zampini } 80591ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 80601ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 80611ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 80621ae86dd6SStefano Zampini } 80631ae86dd6SStefano Zampini 80641ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 80651ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 8066e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 8067e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 80681ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 806928143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 8070e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 8071e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 80721ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 807328143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 8074e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 8075e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 8076e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 8077e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 8078e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 807928143c3dSStefano Zampini if (nis) { 808028143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 808128143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 808228143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 808328143c3dSStefano Zampini } 808428143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 808528143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 808628143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 808728143c3dSStefano Zampini for (i=0;i<nis;i++) { 808828143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 808928143c3dSStefano Zampini } 80901ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 80911ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 80921ae86dd6SStefano Zampini } 809353a05cb3SStefano Zampini *mat_n = NULL; 809428143c3dSStefano Zampini } 8095e7931f94SStefano Zampini PetscFunctionReturn(0); 8096e7931f94SStefano Zampini } 8097a57a6d2fSStefano Zampini 809812edc857SStefano Zampini /* temporary hack into ksp private data structure */ 8099af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 810012edc857SStefano Zampini 8101c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 8102c8587f34SStefano Zampini { 8103c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 8104c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 810520a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 81061ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 81071e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 81089881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 810920a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 81104f819b78SStefano Zampini IS coarse_is,*isarray,corners; 81116e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 811230368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 8113e569e4e1SStefano Zampini PetscInt coarse_eqs_per_proc; 8114f9eb5b7dSStefano Zampini PC pc_temp; 8115c8587f34SStefano Zampini PCType coarse_pc_type; 8116c8587f34SStefano Zampini KSPType coarse_ksp_type; 8117f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 81187274672aSStefano Zampini PetscBool coarse_reuse; 81191e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 812068457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 812122bc73bbSStefano Zampini PetscScalar *array; 812257de7509SStefano Zampini MatReuse coarse_mat_reuse; 812357de7509SStefano Zampini PetscBool restr, full_restr, have_void; 8124e569e4e1SStefano Zampini PetscMPIInt size; 81259881197aSStefano Zampini PetscErrorCode ierr; 8126fdc09c96SStefano Zampini 8127c8587f34SStefano Zampini PetscFunctionBegin; 812843371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CoarseSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8129c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 813068457ee5SStefano 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 */ 8131fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 81325a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 81337de4f681Sstefano_zampini 81347de4f681Sstefano_zampini pcbddc->new_primal_space = PETSC_TRUE; 8135fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 8136f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 8137f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 8138f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 8139fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 814051bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 814151bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 8142727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 8143fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 8144fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 8145fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 8146f4ddd8eeSStefano Zampini } 8147fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 8148fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 8149f4ddd8eeSStefano Zampini } 815070cf5478SStefano Zampini /* reset any subassembling information */ 815157de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 815270cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 815357de7509SStefano Zampini } 81546e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 8155fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 8156f4ddd8eeSStefano Zampini } 815757de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 815857de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 815957de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 816057de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 816118a45a71SStefano Zampini } else { 816257de7509SStefano Zampini coarse_mat = NULL; 816357de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 81646e683305SStefano Zampini } 8165e7931f94SStefano Zampini 8166abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 8167abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 8168abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 8169abbbba34SStefano Zampini 8170abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 81714f819b78SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_submat_dense);CHKERRQ(ierr); 8172e176bc59SStefano 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); 81736e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 81746e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 81756e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 8176abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 8177abbbba34SStefano Zampini 817857de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 817957de7509SStefano Zampini im_active = !!(pcis->n); 818057de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 818157de7509SStefano Zampini 818214f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 818328d58a37SPierre Jolivet /* restr : whether we want to exclude senders (which are not receivers) from the subassembling pattern */ 818457de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 8185e569e4e1SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 818657de7509SStefano Zampini coarse_mat_is = NULL; 818757de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 818857de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 8189e569e4e1SStefano Zampini coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 8190ce64c636SStefano Zampini if (coarse_eqs_per_proc < 0) coarse_eqs_per_proc = pcbddc->coarse_size; 819157de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 8192e569e4e1SStefano Zampini if (pcbddc->coarse_size <= pcbddc->coarse_eqs_limit) multilevel_requested = PETSC_FALSE; 819357de7509SStefano Zampini if (multilevel_requested) { 819457de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 819557de7509SStefano Zampini restr = PETSC_FALSE; 819657de7509SStefano Zampini full_restr = PETSC_FALSE; 819757de7509SStefano Zampini } else { 8198e569e4e1SStefano Zampini ncoarse = pcbddc->coarse_size/coarse_eqs_per_proc + !!(pcbddc->coarse_size%coarse_eqs_per_proc); 819957de7509SStefano Zampini restr = PETSC_TRUE; 820057de7509SStefano Zampini full_restr = PETSC_TRUE; 820157de7509SStefano Zampini } 8202e569e4e1SStefano Zampini if (!pcbddc->coarse_size || size == 1) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 820357de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 820457de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 8205a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 8206bb360cb4SStefano Zampini if (multilevel_requested) { 8207bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 8208bb360cb4SStefano Zampini } else { 8209bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 8210bb360cb4SStefano Zampini } 8211a198735bSStefano Zampini } else { 82127de4f681Sstefano_zampini PetscMPIInt rank; 821328d58a37SPierre Jolivet 8214a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 8215e569e4e1SStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 8216a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 8217a198735bSStefano Zampini } 821857de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 821957de7509SStefano Zampini PetscInt psum; 822057de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 822157de7509SStefano Zampini else psum = 0; 822257de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8223075e25bcSStefano Zampini have_void = ncoarse < size ? PETSC_TRUE : PETSC_FALSE; 822457de7509SStefano Zampini } 822557de7509SStefano Zampini /* determine if we can go multilevel */ 822657de7509SStefano Zampini if (multilevel_requested) { 822757de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 822857de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 822957de7509SStefano Zampini } 823057de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 823157de7509SStefano Zampini 8232e4d548c7SStefano Zampini /* dump subassembling pattern */ 8233e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 8234e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 8235e4d548c7SStefano Zampini } 82366e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 82371e0482f5SStefano Zampini nedcfield = -1; 82384f819b78SStefano Zampini corners = NULL; 82398966356dSPierre Jolivet if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal || pcbddc->corner_selected)) { /* protects from unneeded computations */ 82406e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 82416e683305SStefano Zampini const PetscInt *idxs; 82426e683305SStefano Zampini ISLocalToGlobalMapping tmap; 82436e683305SStefano Zampini 82446e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 82450be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 82466e683305SStefano Zampini /* allocate space for temporary storage */ 8247854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 8248854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 82496e683305SStefano Zampini /* allocate for IS array */ 82506e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 82511e0482f5SStefano Zampini if (pcbddc->nedclocal) { 82521e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 82531e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 82541e0482f5SStefano Zampini } else { 82551e0482f5SStefano Zampini nedcfield = 0; 82566080607fSStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%D)",nisdofs); 82571e0482f5SStefano Zampini nisdofs = 1; 82581e0482f5SStefano Zampini } 82591e0482f5SStefano Zampini } 82606e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 826127b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 826230368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 8263854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 82646e683305SStefano Zampini /* dofs splitting */ 82656e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 82666e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 82671e0482f5SStefano Zampini if (nedcfield != i) { 82686e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 82696e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 82706e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 82716e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 82721e0482f5SStefano Zampini } else { 82731e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 82741e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 82751e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 82766080607fSStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %D != %D",tsize,nout); 82771e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 82781e0482f5SStefano Zampini } 82796e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 828030368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 82816e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 82826e683305SStefano Zampini } 82836e683305SStefano Zampini /* neumann boundaries */ 82846e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 82856e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 82866e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 82876e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 82886e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 82896e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 82906e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 829130368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 82926e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 82936e683305SStefano Zampini } 82944f819b78SStefano Zampini /* coordinates */ 82954f819b78SStefano Zampini if (pcbddc->corner_selected) { 82964f819b78SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&corners);CHKERRQ(ierr); 82974f819b78SStefano Zampini ierr = ISGetLocalSize(corners,&tsize);CHKERRQ(ierr); 82984f819b78SStefano Zampini ierr = ISGetIndices(corners,&idxs);CHKERRQ(ierr); 82994f819b78SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 83004f819b78SStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping corners! %D != %D",tsize,nout); 83014f819b78SStefano Zampini ierr = ISRestoreIndices(corners,&idxs);CHKERRQ(ierr); 83024f819b78SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&corners);CHKERRQ(ierr); 83034f819b78SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 83044f819b78SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&corners);CHKERRQ(ierr); 83054f819b78SStefano Zampini } 83066e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 83076e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 83086e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 83096e683305SStefano Zampini } else { 83106e683305SStefano Zampini nis = 0; 83116e683305SStefano Zampini nisdofs = 0; 83126e683305SStefano Zampini nisneu = 0; 831330368db7SStefano Zampini nisvert = 0; 83146e683305SStefano Zampini isarray = NULL; 83156e683305SStefano Zampini } 83166e683305SStefano Zampini /* destroy no longer needed map */ 83176e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 83186e683305SStefano Zampini 831957de7509SStefano Zampini /* subassemble */ 832057de7509SStefano Zampini if (multilevel_allowed) { 83211ae86dd6SStefano Zampini Vec vp[1]; 83221ae86dd6SStefano Zampini PetscInt nvecs = 0; 832357de7509SStefano Zampini PetscBool reuse,reuser; 83241ae86dd6SStefano Zampini 832557de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 832657de7509SStefano Zampini else reuse = PETSC_FALSE; 832757de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 83281ae86dd6SStefano Zampini vp[0] = NULL; 83291ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 83301ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 83311ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 83321ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 83331ae86dd6SStefano Zampini nvecs = 1; 83341ae86dd6SStefano Zampini 83351ae86dd6SStefano Zampini if (pcbddc->divudotp) { 8336a198735bSStefano Zampini Mat B,loc_divudotp; 83371ae86dd6SStefano Zampini Vec v,p; 83381ae86dd6SStefano Zampini IS dummy; 83391ae86dd6SStefano Zampini PetscInt np; 83401ae86dd6SStefano Zampini 8341a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 8342a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 83431ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 83447dae84e0SHong Zhang ierr = MatCreateSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 83451ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 83461ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 83471ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 83481ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 83491ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 83501ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 83511ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 83521ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 83531ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 83541ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 83551ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 83561ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 835774e2c79eSStefano Zampini } 83581ae86dd6SStefano Zampini } 83591ae86dd6SStefano Zampini if (reuser) { 83601e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 836174e2c79eSStefano Zampini } else { 83621e0482f5SStefano 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); 83631ae86dd6SStefano Zampini } 83641ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 83651683a169SBarry Smith PetscScalar *arraym; 83661683a169SBarry Smith const PetscScalar *arrayv; 83671ae86dd6SStefano Zampini PetscInt nl; 83681ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 83691ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 83701ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 83711683a169SBarry Smith ierr = VecGetArrayRead(vp[0],&arrayv);CHKERRQ(ierr); 8372580bdb30SBarry Smith ierr = PetscArraycpy(arraym,arrayv,nl);CHKERRQ(ierr); 83731683a169SBarry Smith ierr = VecRestoreArrayRead(vp[0],&arrayv);CHKERRQ(ierr); 83741ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 83751ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 8376a198735bSStefano Zampini } else { 8377a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 83781ae86dd6SStefano Zampini } 83791ae86dd6SStefano Zampini } else { 83801e0482f5SStefano 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); 83816e683305SStefano Zampini } 838257de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 838357de7509SStefano Zampini if (!multilevel_allowed) { 8384487b449aSStefano Zampini ierr = MatConvert(coarse_mat_is,MATAIJ,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 83856e683305SStefano Zampini } else { 838657de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 838757de7509SStefano Zampini if (coarse_mat_is) { 838857de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 838957de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 839057de7509SStefano Zampini coarse_mat = coarse_mat_is; 839157de7509SStefano Zampini } 8392779c1cceSStefano Zampini } 8393779c1cceSStefano Zampini } 839457de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 839557de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 83966e683305SStefano Zampini 83976e683305SStefano Zampini /* create local to global scatters for coarse problem */ 839868457ee5SStefano Zampini if (compute_vecs) { 83996e683305SStefano Zampini PetscInt lrows; 84006e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 840157de7509SStefano Zampini if (coarse_mat) { 840257de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 84036e683305SStefano Zampini } else { 84046e683305SStefano Zampini lrows = 0; 84056e683305SStefano Zampini } 84066e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 84076e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 840889535278SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,coarse_mat ? coarse_mat->defaultvectype : VECSTANDARD);CHKERRQ(ierr); 84096e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 84109448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 84116e683305SStefano Zampini } 84126e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 8413c8587f34SStefano Zampini 8414f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 8415f9eb5b7dSStefano Zampini if (multilevel_allowed) { 8416f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 8417f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 8418f9eb5b7dSStefano Zampini } else { 8419f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 8420f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 8421c8587f34SStefano Zampini } 8422c8587f34SStefano Zampini 84236e683305SStefano Zampini /* print some info if requested */ 84246e683305SStefano Zampini if (pcbddc->dbg_flag) { 84256e683305SStefano Zampini if (!multilevel_allowed) { 84266e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 84276e683305SStefano Zampini if (multilevel_requested) { 84286080607fSStefano 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); 84296e683305SStefano Zampini } else if (pcbddc->max_levels) { 84306080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%D)\n",pcbddc->max_levels);CHKERRQ(ierr); 84316e683305SStefano Zampini } 84326e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 84336e683305SStefano Zampini } 84346e683305SStefano Zampini } 84356e683305SStefano Zampini 84361e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 84371e0482f5SStefano Zampini coarseG = NULL; 84381e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 84391e0482f5SStefano Zampini MPI_Comm ccomm; 84401e0482f5SStefano Zampini if (coarse_mat) { 84411e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 84421e0482f5SStefano Zampini } else { 84431e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 84441e0482f5SStefano Zampini } 84451e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 84461e0482f5SStefano Zampini } 84471e0482f5SStefano Zampini 8448f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 844957de7509SStefano Zampini if (coarse_mat) { 845028d58a37SPierre Jolivet PetscBool isredundant,isbddc,force,valid; 84516a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 84527274672aSStefano Zampini 84536e683305SStefano Zampini if (pcbddc->dbg_flag) { 845457de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 84556e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 84566e683305SStefano Zampini } 8457f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 8458312be037SStefano Zampini char prefix[256],str_level[16]; 8459e604994aSStefano Zampini size_t len; 84601e0482f5SStefano Zampini 846157de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 8462422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 8463c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 8464f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 846557de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8466c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 84676e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 8468c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 84691e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 8470c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8471e604994aSStefano Zampini /* prefix */ 8472e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 8473e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 8474e604994aSStefano Zampini if (!pcbddc->current_level) { 8475a126751eSBarry Smith ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,sizeof(prefix));CHKERRQ(ierr); 8476a126751eSBarry Smith ierr = PetscStrlcat(prefix,"pc_bddc_coarse_",sizeof(prefix));CHKERRQ(ierr); 8477c8587f34SStefano Zampini } else { 8478e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 8479312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 8480312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 8481a126751eSBarry Smith /* Nonstandard use of PetscStrncpy() to copy only a portion of the string */ 848234d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 848335529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 8484a126751eSBarry Smith ierr = PetscStrlcat(prefix,str_level,sizeof(prefix));CHKERRQ(ierr); 8485e604994aSStefano Zampini } 8486e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 84873e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 84883e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 84893e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 84903e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 8491f9eb5b7dSStefano Zampini /* allow user customization */ 8492f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 8493e569e4e1SStefano Zampini /* get some info after set from options */ 8494e569e4e1SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 849528d58a37SPierre Jolivet /* multilevel cannot be done with coarse PC different from BDDC, NN, HPDDM, unless forced to */ 849628d58a37SPierre Jolivet force = PETSC_FALSE; 849728d58a37SPierre Jolivet ierr = PetscOptionsGetBool(NULL,((PetscObject)pc_temp)->prefix,"-pc_type_forced",&force,NULL);CHKERRQ(ierr); 849828d58a37SPierre Jolivet ierr = PetscObjectTypeCompareAny((PetscObject)pc_temp,&valid,PCBDDC,PCNN,PCHPDDM,"");CHKERRQ(ierr); 8499e569e4e1SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 850028d58a37SPierre Jolivet if (multilevel_allowed && !force && !valid) { 8501e569e4e1SStefano Zampini isbddc = PETSC_TRUE; 8502e569e4e1SStefano Zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 8503e569e4e1SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 8504e569e4e1SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 8505e569e4e1SStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 85064f819b78SStefano Zampini if (pc_temp->ops->setfromoptions) { /* need to setfromoptions again, skipping the pc_type */ 85074f819b78SStefano Zampini ierr = PetscObjectOptionsBegin((PetscObject)pc_temp);CHKERRQ(ierr); 85084f819b78SStefano Zampini ierr = (*pc_temp->ops->setfromoptions)(PetscOptionsObject,pc_temp);CHKERRQ(ierr); 85094f819b78SStefano Zampini ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pc_temp);CHKERRQ(ierr); 85104f819b78SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 85114f819b78SStefano Zampini pc_temp->setfromoptionscalled++; 85124f819b78SStefano Zampini } 8513e569e4e1SStefano Zampini } 85143e3c6dadSStefano Zampini } 85153e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 851651bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 85173e3c6dadSStefano Zampini if (nisdofs) { 85183e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 85193e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 85203e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 85213e3c6dadSStefano Zampini } 85223e3c6dadSStefano Zampini } 85233e3c6dadSStefano Zampini if (nisneu) { 85243e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 85253e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 8526312be037SStefano Zampini } 852730368db7SStefano Zampini if (nisvert) { 852830368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 852930368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 853030368db7SStefano Zampini } 85311e0482f5SStefano Zampini if (coarseG) { 85321e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 85331e0482f5SStefano Zampini } 8534f9eb5b7dSStefano Zampini 8535f9eb5b7dSStefano Zampini /* get some info after set from options */ 8536f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 85374f819b78SStefano Zampini 8538b76f3995Sstefano_zampini /* multilevel can only be requested via -pc_bddc_levels or PCBDDCSetLevels */ 8539b76f3995Sstefano_zampini if (isbddc && !multilevel_allowed) { 8540f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8541f9eb5b7dSStefano Zampini } 854228d58a37SPierre Jolivet /* multilevel cannot be done with coarse PC different from BDDC, NN, HPDDM, unless forced to */ 854328d58a37SPierre Jolivet force = PETSC_FALSE; 854428d58a37SPierre Jolivet ierr = PetscOptionsGetBool(NULL,((PetscObject)pc_temp)->prefix,"-pc_type_forced",&force,NULL);CHKERRQ(ierr); 854528d58a37SPierre Jolivet ierr = PetscObjectTypeCompareAny((PetscObject)pc_temp,&valid,PCBDDC,PCNN,PCHPDDM,"");CHKERRQ(ierr); 854628d58a37SPierre Jolivet if (multilevel_requested && multilevel_allowed && !valid && !force) { 8547b76f3995Sstefano_zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 8548b76f3995Sstefano_zampini } 85497274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 85504f3a063dSStefano Zampini if (isredundant) { 85514f3a063dSStefano Zampini KSP inner_ksp; 85524f3a063dSStefano Zampini PC inner_pc; 85539326c5c6Sstefano_zampini 85544f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 85554f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 85564f3a063dSStefano Zampini } 8557f9eb5b7dSStefano Zampini 855857de7509SStefano Zampini /* parameters which miss an API */ 85597274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 856057de7509SStefano Zampini if (isbddc) { 8561720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 85627274672aSStefano Zampini 8563720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 856457de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 8565e569e4e1SStefano Zampini pcbddc_coarse->coarse_eqs_limit = pcbddc->coarse_eqs_limit; 856627b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 856727b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 8568a198735bSStefano Zampini Mat coarsedivudotp_is; 8569a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 8570a198735bSStefano Zampini IS row,col; 8571a198735bSStefano Zampini const PetscInt *gidxs; 8572a198735bSStefano Zampini PetscInt n,st,M,N; 8573a198735bSStefano Zampini 8574a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 8575a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 8576a198735bSStefano Zampini st = st-n; 8577a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 8578a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 8579a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 8580a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8581a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 8582a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8583a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 8584a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 8585a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 8586a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 8587a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 8588a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 8589a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 8590a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 8591a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 8592a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 8593a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 8594a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 8595a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 8596a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 85978ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 8598a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 8599720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 8600bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[0] == 0.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 8601720d30f9SStefano Zampini } 8602d4d8cf7bSStefano Zampini } 86039881197aSStefano Zampini 86043301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 86055a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 86063301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 86073301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 86083301b35fSStefano Zampini } 86093301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 86103301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 86113301b35fSStefano Zampini } 86123301b35fSStefano Zampini if (pc->pmat->spd_set) { 86133301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 86143301b35fSStefano Zampini } 861527b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 861627b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 861727b6a85dSStefano Zampini } 86186e683305SStefano Zampini /* set operators */ 861904fe1396SStefano Zampini ierr = MatViewFromOptions(coarse_mat,(PetscObject)pc,"-pc_bddc_coarse_mat_view");CHKERRQ(ierr); 86203007b4efSStefano Zampini ierr = MatSetOptionsPrefix(coarse_mat,((PetscObject)pcbddc->coarse_ksp)->prefix);CHKERRQ(ierr); 86215f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 86226e683305SStefano Zampini if (pcbddc->dbg_flag) { 86236e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 86246e683305SStefano Zampini } 86256e683305SStefano Zampini } 86261e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 86276e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 8628b1ecc7b1SStefano Zampini #if 0 8629b9b85e73SStefano Zampini { 8630b9b85e73SStefano Zampini PetscViewer viewer; 8631b9b85e73SStefano Zampini char filename[256]; 8632b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 8633b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 86346a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 8635b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 8636f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 8637b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 8638b9b85e73SStefano Zampini } 8639b9b85e73SStefano Zampini #endif 8640f9eb5b7dSStefano Zampini 86414f819b78SStefano Zampini if (corners) { 86424f819b78SStefano Zampini Vec gv; 86434f819b78SStefano Zampini IS is; 86444f819b78SStefano Zampini const PetscInt *idxs; 86454f819b78SStefano Zampini PetscInt i,d,N,n,cdim = pcbddc->mat_graph->cdim; 86464f819b78SStefano Zampini PetscScalar *coords; 86474f819b78SStefano Zampini 86484f819b78SStefano Zampini if (!pcbddc->mat_graph->cloc) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing local coordinates"); 86494f819b78SStefano Zampini ierr = VecGetSize(pcbddc->coarse_vec,&N);CHKERRQ(ierr); 86504f819b78SStefano Zampini ierr = VecGetLocalSize(pcbddc->coarse_vec,&n);CHKERRQ(ierr); 86514f819b78SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcbddc->coarse_vec),&gv);CHKERRQ(ierr); 86524f819b78SStefano Zampini ierr = VecSetBlockSize(gv,cdim);CHKERRQ(ierr); 86534f819b78SStefano Zampini ierr = VecSetSizes(gv,n*cdim,N*cdim);CHKERRQ(ierr); 86544f819b78SStefano Zampini ierr = VecSetType(gv,VECSTANDARD);CHKERRQ(ierr); 86554f819b78SStefano Zampini ierr = VecSetFromOptions(gv);CHKERRQ(ierr); 86564f819b78SStefano Zampini ierr = VecSet(gv,PETSC_MAX_REAL);CHKERRQ(ierr); /* we only propagate coordinates from vertices constraints */ 86574f819b78SStefano Zampini 86584f819b78SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&is);CHKERRQ(ierr); 86594f819b78SStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 86604f819b78SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 86614f819b78SStefano Zampini ierr = PetscMalloc1(n*cdim,&coords);CHKERRQ(ierr); 86624f819b78SStefano Zampini for (i=0;i<n;i++) { 86634f819b78SStefano Zampini for (d=0;d<cdim;d++) { 86644f819b78SStefano Zampini coords[cdim*i+d] = pcbddc->mat_graph->coords[cdim*idxs[i]+d]; 86654f819b78SStefano Zampini } 86664f819b78SStefano Zampini } 86674f819b78SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 86684f819b78SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&is);CHKERRQ(ierr); 86694f819b78SStefano Zampini 86704f819b78SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 86714f819b78SStefano Zampini ierr = ISGetIndices(corners,&idxs);CHKERRQ(ierr); 86724f819b78SStefano Zampini ierr = VecSetValuesBlocked(gv,n,idxs,coords,INSERT_VALUES);CHKERRQ(ierr); 86734f819b78SStefano Zampini ierr = ISRestoreIndices(corners,&idxs);CHKERRQ(ierr); 86744f819b78SStefano Zampini ierr = PetscFree(coords);CHKERRQ(ierr); 86754f819b78SStefano Zampini ierr = VecAssemblyBegin(gv);CHKERRQ(ierr); 86764f819b78SStefano Zampini ierr = VecAssemblyEnd(gv);CHKERRQ(ierr); 86774f819b78SStefano Zampini ierr = VecGetArray(gv,&coords);CHKERRQ(ierr); 86784f819b78SStefano Zampini if (pcbddc->coarse_ksp) { 86794f819b78SStefano Zampini PC coarse_pc; 86804f819b78SStefano Zampini PetscBool isbddc; 86814f819b78SStefano Zampini 86824f819b78SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 86834f819b78SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 86844f819b78SStefano Zampini if (isbddc) { /* coarse coordinates have PETSC_MAX_REAL, specific for BDDC */ 86854f819b78SStefano Zampini PetscReal *realcoords; 86864f819b78SStefano Zampini 86874f819b78SStefano Zampini ierr = VecGetLocalSize(gv,&n);CHKERRQ(ierr); 86884f819b78SStefano Zampini #if defined(PETSC_USE_COMPLEX) 86894f819b78SStefano Zampini ierr = PetscMalloc1(n,&realcoords);CHKERRQ(ierr); 86904f819b78SStefano Zampini for (i=0;i<n;i++) realcoords[i] = PetscRealPart(coords[i]); 86914f819b78SStefano Zampini #else 86924f819b78SStefano Zampini realcoords = coords; 86934f819b78SStefano Zampini #endif 86944f819b78SStefano Zampini ierr = PCSetCoordinates(coarse_pc,cdim,n/cdim,realcoords);CHKERRQ(ierr); 86954f819b78SStefano Zampini #if defined(PETSC_USE_COMPLEX) 86964f819b78SStefano Zampini ierr = PetscFree(realcoords);CHKERRQ(ierr); 86974f819b78SStefano Zampini #endif 86984f819b78SStefano Zampini } 86994f819b78SStefano Zampini } 87004f819b78SStefano Zampini ierr = VecRestoreArray(gv,&coords);CHKERRQ(ierr); 87014f819b78SStefano Zampini ierr = VecDestroy(&gv);CHKERRQ(ierr); 87024f819b78SStefano Zampini } 87034f819b78SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 87044f819b78SStefano Zampini 870598a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 870698a51de6SStefano Zampini Vec crhs,csol; 870704708bb6SStefano Zampini 8708f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 8709f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 8710f347579bSStefano Zampini if (!csol) { 87112a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 8712f9eb5b7dSStefano Zampini } 8713f347579bSStefano Zampini if (!crhs) { 87142a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 8715f347579bSStefano Zampini } 8716b0f5fe93SStefano Zampini } 87171ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 8718b0f5fe93SStefano Zampini 8719b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 8720b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 8721b0f5fe93SStefano Zampini 8722b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 87234f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 87244f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 87254f1b2e48SStefano Zampini } 8726b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 8727b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 8728b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8729b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8730b0f5fe93SStefano Zampini if (coarse_mat) { 8731b0f5fe93SStefano Zampini Vec nullv; 8732b0f5fe93SStefano Zampini PetscScalar *array,*array2; 8733b0f5fe93SStefano Zampini PetscInt nl; 8734b0f5fe93SStefano Zampini 8735b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 8736b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 8737b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8738b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 8739580bdb30SBarry Smith ierr = PetscArraycpy(array2,array,nl);CHKERRQ(ierr); 8740b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 8741b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8742b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 8743b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 8744b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 8745b0f5fe93SStefano Zampini } 8746b0f5fe93SStefano Zampini } 874743371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CoarseSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8748b0f5fe93SStefano Zampini 874943371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CoarseSolver[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8750b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 8751b0f5fe93SStefano Zampini PetscBool ispreonly; 8752b0f5fe93SStefano Zampini 8753b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8754b0f5fe93SStefano Zampini PetscBool isnull; 8755b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 8756bef83e63SStefano Zampini if (isnull) { 8757b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 8758b0f5fe93SStefano Zampini } 8759bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 8760b0f5fe93SStefano Zampini } 8761b0f5fe93SStefano Zampini /* setup coarse ksp */ 8762b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 8763cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 8764cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 87656e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 8766c8587f34SStefano Zampini KSP check_ksp; 87672b510759SStefano Zampini KSPType check_ksp_type; 8768c8587f34SStefano Zampini PC check_pc; 87696e683305SStefano Zampini Vec check_vec,coarse_vec; 87706a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 87712b510759SStefano Zampini PetscInt its; 87726e683305SStefano Zampini PetscBool compute_eigs; 87736e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 87746e683305SStefano Zampini PetscInt neigs; 87758e185a42SStefano Zampini const char *prefix; 8776c8587f34SStefano Zampini 87772b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 87786e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 877915579a77SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)check_ksp,(PetscObject)pcbddc->coarse_ksp,0);CHKERRQ(ierr); 8780399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 878123ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8782f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 8783e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 8784e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 8785e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 87862b510759SStefano Zampini if (ispreonly) { 87872b510759SStefano Zampini check_ksp_type = KSPPREONLY; 87886e683305SStefano Zampini compute_eigs = PETSC_FALSE; 87892b510759SStefano Zampini } else { 8790cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 87916e683305SStefano Zampini compute_eigs = PETSC_TRUE; 8792c8587f34SStefano Zampini } 8793c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 87946e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 87956e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 87966e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 8797a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 8798a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 8799a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 8800a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 8801c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 8802c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 8803c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 8804c8587f34SStefano Zampini /* create random vec */ 88052701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 8806c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 88076e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 8808c8587f34SStefano Zampini /* solve coarse problem */ 88096e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 8810c0decd05SBarry Smith ierr = KSPCheckSolve(check_ksp,pc,coarse_vec);CHKERRQ(ierr); 8811cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 88126e683305SStefano Zampini if (compute_eigs) { 8813854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 8814854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 88156e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 88161ae86dd6SStefano Zampini if (neigs) { 88176e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 88186e683305SStefano Zampini lambda_min = eigs_r[0]; 88196e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 88202701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 88212701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 8822cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 8823cbcc2c2aSStefano Zampini } 8824c8587f34SStefano Zampini } 8825c8587f34SStefano Zampini } 88261ae86dd6SStefano Zampini } 8827cbcc2c2aSStefano Zampini 8828c8587f34SStefano Zampini /* check coarse problem residual error */ 88296e683305SStefano Zampini if (pcbddc->dbg_flag) { 88306e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 88316e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 88326e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 8833c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 88346e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 88356e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 8836779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 88376e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 88386e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 88396e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 88406e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 8841b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8842b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 8843b0f5fe93SStefano Zampini } 88446e683305SStefano Zampini if (compute_eigs) { 88456e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 8846b03ebc13SStefano Zampini KSPConvergedReason reason; 8847deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 8848c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 8849b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 88506e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 8851b03ebc13SStefano 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); 88526e683305SStefano Zampini for (i=0;i<neigs;i++) { 88536e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 8854c8587f34SStefano Zampini } 88556e683305SStefano Zampini } 88566e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 88576e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 88586e683305SStefano Zampini } 8859e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 88602701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 8861c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 88626e683305SStefano Zampini if (compute_eigs) { 88636e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 88646e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 8865c8587f34SStefano Zampini } 88666e683305SStefano Zampini } 88676e683305SStefano Zampini } 8868bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 8869cbcc2c2aSStefano Zampini /* print additional info */ 8870cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 88716e683305SStefano Zampini /* waits until all processes reaches this point */ 88726e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 88736080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %D\n",pcbddc->current_level);CHKERRQ(ierr); 8874cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8875cbcc2c2aSStefano Zampini } 8876cbcc2c2aSStefano Zampini 88772b510759SStefano Zampini /* free memory */ 8878fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 887943371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CoarseSolver[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8880c8587f34SStefano Zampini PetscFunctionReturn(0); 8881c8587f34SStefano Zampini } 8882674ae819SStefano Zampini 8883f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 8884f34684f1SStefano Zampini { 8885f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8886f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 8887f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 8888dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 8889dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 889073be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 8891dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 8892f34684f1SStefano Zampini PetscErrorCode ierr; 8893f34684f1SStefano Zampini 8894f34684f1SStefano Zampini PetscFunctionBegin; 8895f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 88966c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 8897dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 88983bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 8899dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8900dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 89016583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 8902dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 8903dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 8904dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 89056c4ed002SBarry 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); 8906dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 8907dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8908580bdb30SBarry Smith ierr = PetscArraycpy(local_primal_indices,t_local_primal_indices,local_size);CHKERRQ(ierr); 8909dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8910dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8911f34684f1SStefano Zampini 8912f34684f1SStefano Zampini /* check numbering */ 8913f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 8914019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 8915dc456d91SStefano Zampini PetscInt i; 8916b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 8917f34684f1SStefano Zampini 8918f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8919f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8920f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 89211575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8922019a44ceSStefano Zampini /* counter */ 8923019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8924019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 8925019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8926019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8927019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8928019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8929f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 8930f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 8931727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 8932f34684f1SStefano Zampini } 8933f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8934f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8935f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8936e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8937e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8938e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8939e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8940f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8941019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8942f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8943019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 89442c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 894575c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 8946b9b85e73SStefano Zampini set_error = PETSC_TRUE; 89472c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 89486080607fSStefano 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); 8949f34684f1SStefano Zampini } 8950f34684f1SStefano Zampini } 8951019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8952b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8953f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8954f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8955f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 8956f34684f1SStefano Zampini } 8957f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8958f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8959e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8960e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8961f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 89626080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %D (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 8963b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 8964ca8b9ea9SStefano Zampini PetscInt *gidxs; 8965ca8b9ea9SStefano Zampini 8966ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 89673bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 8968f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 8969f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8970f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 8971f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 89726080607fSStefano 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); 8973f34684f1SStefano Zampini } 8974f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8975ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 8976f34684f1SStefano Zampini } 8977f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 89781575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8979302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 8980f34684f1SStefano Zampini } 89816080607fSStefano Zampini 8982f34684f1SStefano Zampini /* get back data */ 8983f34684f1SStefano Zampini *coarse_size_n = coarse_size; 8984f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 8985674ae819SStefano Zampini PetscFunctionReturn(0); 8986674ae819SStefano Zampini } 8987674ae819SStefano Zampini 8988a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 8989e456f2a8SStefano Zampini { 8990e456f2a8SStefano Zampini IS localis_t; 8991a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 8992e456f2a8SStefano Zampini PetscScalar *vals; 8993e456f2a8SStefano Zampini PetscErrorCode ierr; 8994e456f2a8SStefano Zampini 8995e456f2a8SStefano Zampini PetscFunctionBegin; 8996a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 8997e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 8998854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 8999e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 9000e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 9001a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 9002a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 90031035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 90043151afb1SStefano Zampini ierr = VecSetOption(gwork,VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE);CHKERRQ(ierr); 9005a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 90061035eff8SStefano Zampini } 9007a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 9008e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 9009e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 9010a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 9011a7dc3881SStefano Zampini /* now compute set in local ordering */ 9012a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9013a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9014a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 9015a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 9016a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 9017ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 9018e456f2a8SStefano Zampini lsize++; 9019e456f2a8SStefano Zampini } 9020e456f2a8SStefano Zampini } 9021854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 9022a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 9023ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 9024e456f2a8SStefano Zampini idxs[lsize++] = i; 9025e456f2a8SStefano Zampini } 9026e456f2a8SStefano Zampini } 9027a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 9028a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 9029e456f2a8SStefano Zampini *localis = localis_t; 9030e456f2a8SStefano Zampini PetscFunctionReturn(0); 9031e456f2a8SStefano Zampini } 9032906d46d4SStefano Zampini 903308122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 9034b96c3477SStefano Zampini { 9035a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 9036b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 9037b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 9038a64f4aa4SStefano Zampini Mat S_j; 9039b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 9040b96c3477SStefano Zampini PetscBool free_used_adj; 9041b96c3477SStefano Zampini PetscErrorCode ierr; 9042b96c3477SStefano Zampini 9043b96c3477SStefano Zampini PetscFunctionBegin; 904443371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Schurs[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 9045b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 9046b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 904708122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 9048b96c3477SStefano Zampini used_xadj = NULL; 9049b96c3477SStefano Zampini used_adjncy = NULL; 9050b96c3477SStefano Zampini } else { 905108122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 905208122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 905308122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 905408122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 9055b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 9056b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 9057b96c3477SStefano Zampini } else { 90582fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 9059b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 9060b96c3477SStefano Zampini PetscInt nvtxs; 9061b96c3477SStefano Zampini 90622fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 90632fffb893SStefano Zampini if (flg_row) { 9064b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 9065580bdb30SBarry Smith ierr = PetscArraycpy(used_xadj,xadj,nvtxs+1);CHKERRQ(ierr); 9066580bdb30SBarry Smith ierr = PetscArraycpy(used_adjncy,adjncy,xadj[nvtxs]);CHKERRQ(ierr); 9067b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 90682fffb893SStefano Zampini } else { 90692fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 90702fffb893SStefano Zampini used_xadj = NULL; 90712fffb893SStefano Zampini used_adjncy = NULL; 90722fffb893SStefano Zampini } 90732fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 9074b96c3477SStefano Zampini } 9075b96c3477SStefano Zampini } 9076d5574798SStefano Zampini 9077d5574798SStefano Zampini /* setup sub_schurs data */ 90782f37b69bSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->pA_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 9079df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 9080df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 9081a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 908291af6908SStefano 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); 9083a64f4aa4SStefano Zampini } else { 908472b8c272SStefano Zampini Mat change = NULL; 90859d54b7f4SStefano Zampini Vec scaling = NULL; 9086111315fdSstefano_zampini IS change_primal = NULL, iP; 9087111315fdSstefano_zampini PetscInt benign_n; 9088111315fdSstefano_zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 90897ebab0bbSStefano Zampini PetscBool need_change = PETSC_FALSE; 9090111315fdSstefano_zampini PetscBool discrete_harmonic = PETSC_FALSE; 9091a3df083aSStefano Zampini 90925feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 90935feab87aSStefano Zampini PetscInt n_vertices; 90945feab87aSStefano Zampini 90955feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 90962034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 90975feab87aSStefano Zampini } 9098a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 9099a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 9100ca92afb2SStefano Zampini } else { 9101a3df083aSStefano Zampini benign_n = 0; 9102ca92afb2SStefano Zampini } 9103b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 9104b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 9105b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 910672b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 910722db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 9108b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 910922db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 9110b7ab4a40SStefano Zampini } 9111b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 9112b7ab4a40SStefano 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 */ 9113b7ab4a40SStefano Zampini if (need_change) { 911488c03ad3SStefano Zampini PC_IS *pcisf; 911588c03ad3SStefano Zampini PC_BDDC *pcbddcf; 911688c03ad3SStefano Zampini PC pcf; 911788c03ad3SStefano Zampini 9118e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 911988c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 912088c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 912188c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 9122b9be95fcSstefano_zampini 912388c03ad3SStefano Zampini /* hacks */ 912488c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 912572b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 912672b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 912772b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 912872b8c272SStefano Zampini pcisf->n = pcis->n; 912972b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 913088c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 913188c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 913288c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 913388c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 913488c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 913588c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 913672b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 913788c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 9138b9be95fcSstefano_zampini 9139b9be95fcSstefano_zampini /* setup constraints so that we can get information on primal vertices and change of basis (in local numbering) */ 914088c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 914172b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 914272b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 914372b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 914472b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 9145b9be95fcSstefano_zampini 914688c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 914772b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 914888c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 914988c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 915088c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 915188c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 915288c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 915388c03ad3SStefano Zampini pcf->ops->destroy = NULL; 9154b9be95fcSstefano_zampini pcf->ops->reset = NULL; 915588c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 915688c03ad3SStefano Zampini } 91579d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 9158111315fdSstefano_zampini 9159111315fdSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 9160111315fdSstefano_zampini if (iP) { 9161111315fdSstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)iP),sub_schurs->prefix,"BDDC sub_schurs options","PC");CHKERRQ(ierr); 9162111315fdSstefano_zampini ierr = PetscOptionsBool("-sub_schurs_discrete_harmonic",NULL,NULL,discrete_harmonic,&discrete_harmonic,NULL);CHKERRQ(ierr); 9163111315fdSstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 9164111315fdSstefano_zampini } 9165111315fdSstefano_zampini if (discrete_harmonic) { 9166111315fdSstefano_zampini Mat A; 9167111315fdSstefano_zampini ierr = MatDuplicate(pcbddc->local_mat,MAT_COPY_VALUES,&A);CHKERRQ(ierr); 9168111315fdSstefano_zampini ierr = MatZeroRowsColumnsIS(A,iP,1.0,NULL,NULL);CHKERRQ(ierr); 9169111315fdSstefano_zampini ierr = PetscObjectCompose((PetscObject)A,"__KSPFETIDP_iP",(PetscObject)iP);CHKERRQ(ierr); 9170111315fdSstefano_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); 9171111315fdSstefano_zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 9172111315fdSstefano_zampini } else { 917391af6908SStefano 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); 9174111315fdSstefano_zampini } 917572b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 917672b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 9177ca92afb2SStefano Zampini } 9178d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 9179b96c3477SStefano Zampini 9180b96c3477SStefano Zampini /* free adjacency */ 9181b96c3477SStefano Zampini if (free_used_adj) { 9182b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 9183b96c3477SStefano Zampini } 918443371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Schurs[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 9185b96c3477SStefano Zampini PetscFunctionReturn(0); 9186b96c3477SStefano Zampini } 9187b96c3477SStefano Zampini 918808122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 9189b96c3477SStefano Zampini { 9190b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 9191b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 9192b96c3477SStefano Zampini PCBDDCGraph graph; 9193b96c3477SStefano Zampini PetscErrorCode ierr; 9194b96c3477SStefano Zampini 9195b96c3477SStefano Zampini PetscFunctionBegin; 9196b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 919708122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 91983301b35fSStefano Zampini IS verticesIS,verticescomm; 91993301b35fSStefano Zampini PetscInt vsize,*idxs; 9200b96c3477SStefano Zampini 9201b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 92023301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 92033301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 92043301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 92053301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 9206c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 9207b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 9208be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 9209441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 92103301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 9211b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 9212b96c3477SStefano Zampini } else { 9213b96c3477SStefano Zampini graph = pcbddc->mat_graph; 9214b96c3477SStefano Zampini } 9215e4d548c7SStefano Zampini /* print some info */ 92165c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 9217e4d548c7SStefano Zampini IS vertices; 9218e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 9219c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 9220e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 9221e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 9222e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 9223e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 92246080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%D)\n",PetscGlobalRank,(int)nv,pcbddc->use_vertices);CHKERRQ(ierr); 92256080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%D)\n",PetscGlobalRank,(int)nedges,pcbddc->use_edges);CHKERRQ(ierr); 92266080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%D)\n",PetscGlobalRank,(int)nfaces,pcbddc->use_faces);CHKERRQ(ierr); 9227e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 9228e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 9229c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 9230e4d548c7SStefano Zampini } 9231b96c3477SStefano Zampini 9232b96c3477SStefano Zampini /* sub_schurs init */ 9233b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 9234b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 9235b334f244SStefano Zampini } 923688113c35SStefano 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); 9237a64f4aa4SStefano Zampini 9238b96c3477SStefano Zampini /* free graph struct */ 923908122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 9240b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 9241b96c3477SStefano Zampini } 9242b96c3477SStefano Zampini PetscFunctionReturn(0); 9243b96c3477SStefano Zampini } 9244fa34dd3eSStefano Zampini 9245fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 9246fa34dd3eSStefano Zampini { 9247fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 9248fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 9249fa34dd3eSStefano Zampini PetscErrorCode ierr; 9250fa34dd3eSStefano Zampini 9251fa34dd3eSStefano Zampini PetscFunctionBegin; 9252fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 9253fa34dd3eSStefano Zampini IS zerodiag = NULL; 92544f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 9255fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 92564f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 925775c01103SStefano Zampini PetscReal norm; 9258fa34dd3eSStefano Zampini PetscInt i; 9259fa34dd3eSStefano Zampini 9260fa34dd3eSStefano Zampini /* B0 and B0_B */ 9261fa34dd3eSStefano Zampini if (zerodiag) { 9262fa34dd3eSStefano Zampini IS dummy; 9263fa34dd3eSStefano Zampini 92644f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 92657dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 9266fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 9267fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 9268fa34dd3eSStefano Zampini } 9269fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 9270fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 9271fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 9272fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9273fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9274fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9275fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9276fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 9277fa34dd3eSStefano Zampini /* S_j */ 92782f37b69bSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->pA_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 9279fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 9280fa34dd3eSStefano Zampini 9281fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 9282fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 9283fa34dd3eSStefano Zampini /* continuous in primal space */ 9284fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 9285fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9286fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9287fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 92884f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 92894f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 9290fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 9291fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 9292fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 9293fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 9294fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9295fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9296fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 9297fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 9298fa34dd3eSStefano Zampini 9299fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 9300fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 9301fa34dd3eSStefano Zampini /* local with Schur */ 9302fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 9303fa34dd3eSStefano Zampini if (zerodiag) { 9304fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 93054f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 9306fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 9307fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 9308fa34dd3eSStefano Zampini } 9309fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 9310fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9311fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9312fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 9313fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 9314fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 9315fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 9316fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 9317fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 9318fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9319fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9320fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9321fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9322fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 9323fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 9324fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 9325fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 9326fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 9327fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 9328fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 9329fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9330fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9331fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 9332fa34dd3eSStefano Zampini if (zerodiag) { 9333fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 9334fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 93354f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 9336fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 9337fa34dd3eSStefano Zampini } 9338fa34dd3eSStefano Zampini /* BDDC */ 9339fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 9340fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 9341fa34dd3eSStefano Zampini 9342fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 9343fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 9344fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 93456080607fSStefano Zampini ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm);CHKERRQ(ierr); 93464f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 93476080607fSStefano 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); 9348fa34dd3eSStefano Zampini } 93494f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 9350fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 9351fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 9352fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 9353fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 9354fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 9355fa34dd3eSStefano Zampini } 9356fa34dd3eSStefano Zampini PetscFunctionReturn(0); 9357fa34dd3eSStefano Zampini } 93581e0482f5SStefano Zampini 93591e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 93601e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 93611e0482f5SStefano Zampini { 93621e0482f5SStefano Zampini Mat At; 93631e0482f5SStefano Zampini IS rows; 93641e0482f5SStefano Zampini PetscInt rst,ren; 93651e0482f5SStefano Zampini PetscErrorCode ierr; 93661e0482f5SStefano Zampini PetscLayout rmap; 93671e0482f5SStefano Zampini 93681e0482f5SStefano Zampini PetscFunctionBegin; 93691e0482f5SStefano Zampini rst = ren = 0; 93701e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 93711e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 93721e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 93731e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 93741e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 93751e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 93761e0482f5SStefano Zampini } 9377e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 93787dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 93791e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 93801e0482f5SStefano Zampini 93811e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 93821e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 93831e0482f5SStefano Zampini IS from,to; 93841e0482f5SStefano Zampini Vec gvec; 93851e0482f5SStefano Zampini PetscInt lsize; 93861e0482f5SStefano Zampini 93871e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 93881e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 93891e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 93901e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 93911e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 93921e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 93931e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 93941e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 93951e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 93961e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 93971e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 93981e0482f5SStefano Zampini b->A = a->A; 93991e0482f5SStefano Zampini b->B = a->B; 94001e0482f5SStefano Zampini 94011e0482f5SStefano Zampini b->donotstash = a->donotstash; 94021e0482f5SStefano Zampini b->roworiented = a->roworiented; 94031e0482f5SStefano Zampini b->rowindices = 0; 94041e0482f5SStefano Zampini b->rowvalues = 0; 94051e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 94061e0482f5SStefano Zampini 94071e0482f5SStefano Zampini (*B)->rmap = rmap; 94081e0482f5SStefano Zampini (*B)->factortype = A->factortype; 94091e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 94101e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 94111e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 94121e0482f5SStefano Zampini 94131e0482f5SStefano Zampini if (a->colmap) { 94141e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 94151e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 94161e0482f5SStefano Zampini #else 94171e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 94181e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 9419580bdb30SBarry Smith ierr = PetscArraycpy(b->colmap,a->colmap,At->cmap->N);CHKERRQ(ierr); 94201e0482f5SStefano Zampini #endif 94211e0482f5SStefano Zampini } else b->colmap = 0; 94221e0482f5SStefano Zampini if (a->garray) { 94231e0482f5SStefano Zampini PetscInt len; 94241e0482f5SStefano Zampini len = a->B->cmap->n; 94251e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 94261e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 9427580bdb30SBarry Smith if (len) { ierr = PetscArraycpy(b->garray,a->garray,len);CHKERRQ(ierr); } 94281e0482f5SStefano Zampini } else b->garray = 0; 94291e0482f5SStefano Zampini 94301e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 94311e0482f5SStefano Zampini b->lvec = a->lvec; 94321e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 94331e0482f5SStefano Zampini 94341e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 94351e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 94361e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 94371e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 94381e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 94399448b7f1SJunchao Zhang ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 94401e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 94411e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 94421e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 94431e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 94441e0482f5SStefano Zampini } 94451e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 94461e0482f5SStefano Zampini PetscFunctionReturn(0); 94471e0482f5SStefano Zampini } 9448