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 PetscScalar *uwork,*data,*U, ds = 0.; 18a13144ffSStefano Zampini PetscReal *sing; 19a13144ffSStefano Zampini PetscBLASInt bM,bN,lwork,lierr,di = 1; 20a13144ffSStefano Zampini PetscInt ulw,i,nr,nc,n; 21a13144ffSStefano Zampini PetscErrorCode ierr; 22abee2b68SSebastian Grimberg #if defined(PETSC_USE_COMPLEX) 23abee2b68SSebastian Grimberg PetscReal *rwork2; 24abee2b68SSebastian Grimberg #endif 25a13144ffSStefano Zampini 26a13144ffSStefano Zampini PetscFunctionBegin; 27a13144ffSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 28a13144ffSStefano Zampini if (!nr || !nc) PetscFunctionReturn(0); 29a13144ffSStefano Zampini 30a13144ffSStefano Zampini /* workspace */ 31a13144ffSStefano Zampini if (!work) { 32a13144ffSStefano Zampini ulw = PetscMax(PetscMax(1,5*PetscMin(nr,nc)),3*PetscMin(nr,nc)+PetscMax(nr,nc)); 33f913dca9SStefano Zampini ierr = PetscMalloc1(ulw,&uwork);CHKERRQ(ierr); 34a13144ffSStefano Zampini } else { 35a13144ffSStefano Zampini ulw = lw; 36a13144ffSStefano Zampini uwork = work; 37a13144ffSStefano Zampini } 38a13144ffSStefano Zampini n = PetscMin(nr,nc); 39a13144ffSStefano Zampini if (!rwork) { 40a13144ffSStefano Zampini ierr = PetscMalloc1(n,&sing);CHKERRQ(ierr); 41a13144ffSStefano Zampini } else { 42a13144ffSStefano Zampini sing = rwork; 43a13144ffSStefano Zampini } 44a13144ffSStefano Zampini 45a13144ffSStefano Zampini /* SVD */ 46a13144ffSStefano Zampini ierr = PetscMalloc1(nr*nr,&U);CHKERRQ(ierr); 47a13144ffSStefano Zampini ierr = PetscBLASIntCast(nr,&bM);CHKERRQ(ierr); 48a13144ffSStefano Zampini ierr = PetscBLASIntCast(nc,&bN);CHKERRQ(ierr); 49a13144ffSStefano Zampini ierr = PetscBLASIntCast(ulw,&lwork);CHKERRQ(ierr); 50a13144ffSStefano Zampini ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); 51a13144ffSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 52abee2b68SSebastian Grimberg #if !defined(PETSC_USE_COMPLEX) 53a13144ffSStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,&lierr)); 54abee2b68SSebastian Grimberg #else 55abee2b68SSebastian Grimberg ierr = PetscMalloc1(5*n,&rwork2);CHKERRQ(ierr); 56abee2b68SSebastian Grimberg PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,rwork2,&lierr)); 57abee2b68SSebastian Grimberg ierr = PetscFree(rwork2);CHKERRQ(ierr); 58abee2b68SSebastian Grimberg #endif 59a13144ffSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 60a13144ffSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 61a13144ffSStefano Zampini ierr = MatDenseRestoreArray(A,&data);CHKERRQ(ierr); 62a13144ffSStefano Zampini for (i=0;i<n;i++) if (sing[i] < PETSC_SMALL) break; 63a13144ffSStefano Zampini if (!rwork) { 64a13144ffSStefano Zampini ierr = PetscFree(sing);CHKERRQ(ierr); 65a13144ffSStefano Zampini } 66a13144ffSStefano Zampini if (!work) { 67a13144ffSStefano Zampini ierr = PetscFree(uwork);CHKERRQ(ierr); 68a13144ffSStefano Zampini } 69a13144ffSStefano Zampini /* create B */ 70f498cd09SStefano Zampini if (!range) { 71a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 72a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 73580bdb30SBarry Smith ierr = PetscArraycpy(data,U+nr*i,(nr-i)*nr);CHKERRQ(ierr); 74f498cd09SStefano Zampini } else { 75f498cd09SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,i,NULL,B);CHKERRQ(ierr); 76f498cd09SStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 77580bdb30SBarry Smith ierr = PetscArraycpy(data,U,i*nr);CHKERRQ(ierr); 78f498cd09SStefano Zampini } 79a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 80a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 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 PetscInt *emarks; 179213b8bfaSStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,global,singular,setprimal; 180a13144ffSStefano Zampini PetscErrorCode ierr; 181a13144ffSStefano Zampini 182a13144ffSStefano Zampini PetscFunctionBegin; 183213b8bfaSStefano Zampini /* If the discrete gradient is defined for a subset of dofs and global is true, 184213b8bfaSStefano Zampini it assumes G is given in global ordering for all the dofs. 185213b8bfaSStefano Zampini Otherwise, the ordering is global for the Nedelec field */ 186213b8bfaSStefano Zampini order = pcbddc->nedorder; 187213b8bfaSStefano Zampini conforming = pcbddc->conforming; 188213b8bfaSStefano Zampini field = pcbddc->nedfield; 189213b8bfaSStefano Zampini global = pcbddc->nedglobal; 190213b8bfaSStefano Zampini setprimal = PETSC_FALSE; 191a13144ffSStefano Zampini print = PETSC_FALSE; 192213b8bfaSStefano Zampini singular = PETSC_FALSE; 193a13144ffSStefano Zampini 194213b8bfaSStefano Zampini /* Command line customization */ 195213b8bfaSStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC Nedelec options","PC");CHKERRQ(ierr); 196213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_field_primal","All edge dofs set as primals: Toselli's algorithm C",NULL,setprimal,&setprimal,NULL);CHKERRQ(ierr); 197213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_singular","Infer nullspace from discrete gradient",NULL,singular,&singular,NULL);CHKERRQ(ierr); 198213b8bfaSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_nedelec_order","Test variable order code (to be removed)",NULL,order,&order,NULL);CHKERRQ(ierr); 199213b8bfaSStefano Zampini /* print debug info TODO: to be removed */ 200213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_print","Print debug info",NULL,print,&print,NULL);CHKERRQ(ierr); 201213b8bfaSStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 202213b8bfaSStefano Zampini 203213b8bfaSStefano Zampini /* Return if there are no edges in the decomposition and the problem is not singular */ 2041e0482f5SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&al2g,NULL);CHKERRQ(ierr); 2051e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(al2g,&n);CHKERRQ(ierr); 206213b8bfaSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 207213b8bfaSStefano Zampini if (!singular) { 208a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 209a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 210c2151214SStefano Zampini for (i=0;i<n;i++) { 211a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 212a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 213a13144ffSStefano Zampini break; 214a13144ffSStefano Zampini } 215a13144ffSStefano Zampini } 216a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 217a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 218a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 219213b8bfaSStefano Zampini } 220a13144ffSStefano Zampini 221213b8bfaSStefano Zampini /* Get Nedelec field */ 2226080607fSStefano 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); 223213b8bfaSStefano Zampini if (pcbddc->n_ISForDofsLocal && field >= 0) { 224c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 225c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 226c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 227213b8bfaSStefano Zampini } else if (!pcbddc->n_ISForDofsLocal && field != PETSC_DECIDE) { 228213b8bfaSStefano Zampini ne = n; 229213b8bfaSStefano Zampini nedfieldlocal = NULL; 230213b8bfaSStefano Zampini global = PETSC_TRUE; 231213b8bfaSStefano Zampini } else if (field == PETSC_DECIDE) { 232213b8bfaSStefano Zampini PetscInt rst,ren,*idx; 233213b8bfaSStefano Zampini 234580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,n);CHKERRQ(ierr); 235580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,pc->pmat->rmap->n);CHKERRQ(ierr); 236213b8bfaSStefano Zampini ierr = MatGetOwnershipRange(pcbddc->discretegradient,&rst,&ren);CHKERRQ(ierr); 237213b8bfaSStefano Zampini for (i=rst;i<ren;i++) { 238213b8bfaSStefano Zampini PetscInt nc; 239213b8bfaSStefano Zampini 240213b8bfaSStefano Zampini ierr = MatGetRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 241213b8bfaSStefano Zampini if (nc > 1) matis->sf_rootdata[i-rst] = 1; 242213b8bfaSStefano Zampini ierr = MatRestoreRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 243213b8bfaSStefano Zampini } 244213b8bfaSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 245213b8bfaSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 246213b8bfaSStefano Zampini ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr); 247213b8bfaSStefano Zampini for (i=0,ne=0;i<n;i++) if (matis->sf_leafdata[i]) idx[ne++] = i; 248213b8bfaSStefano Zampini ierr = ISCreateGeneral(comm,ne,idx,PETSC_OWN_POINTER,&nedfieldlocal);CHKERRQ(ierr); 249213b8bfaSStefano Zampini } else { 250213b8bfaSStefano Zampini SETERRQ(comm,PETSC_ERR_USER,"When multiple fields are present, the Nedelec field has to be specified"); 251213b8bfaSStefano Zampini } 252213b8bfaSStefano Zampini 253213b8bfaSStefano Zampini /* Sanity checks */ 254213b8bfaSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 255213b8bfaSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 2566080607fSStefano 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); 257213b8bfaSStefano Zampini 258213b8bfaSStefano Zampini /* Just set primal dofs and return */ 2591e0482f5SStefano Zampini if (setprimal) { 260eee23b56SStefano Zampini IS enedfieldlocal; 261eee23b56SStefano Zampini PetscInt *eidxs; 262eee23b56SStefano Zampini 263eee23b56SStefano Zampini ierr = PetscMalloc1(ne,&eidxs);CHKERRQ(ierr); 264eee23b56SStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 265213b8bfaSStefano Zampini if (nedfieldlocal) { 266213b8bfaSStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 267eee23b56SStefano Zampini for (i=0,cum=0;i<ne;i++) { 268eee23b56SStefano Zampini if (PetscRealPart(vals[idxs[i]]) > 2.) { 269eee23b56SStefano Zampini eidxs[cum++] = idxs[i]; 270eee23b56SStefano Zampini } 271eee23b56SStefano Zampini } 272eee23b56SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 273213b8bfaSStefano Zampini } else { 274213b8bfaSStefano Zampini for (i=0,cum=0;i<ne;i++) { 275213b8bfaSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 276213b8bfaSStefano Zampini eidxs[cum++] = i; 277213b8bfaSStefano Zampini } 278213b8bfaSStefano Zampini } 279213b8bfaSStefano Zampini } 280213b8bfaSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 281eee23b56SStefano Zampini ierr = ISCreateGeneral(comm,cum,eidxs,PETSC_COPY_VALUES,&enedfieldlocal);CHKERRQ(ierr); 282eee23b56SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,enedfieldlocal);CHKERRQ(ierr); 283eee23b56SStefano Zampini ierr = PetscFree(eidxs);CHKERRQ(ierr); 2841e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 285eee23b56SStefano Zampini ierr = ISDestroy(&enedfieldlocal);CHKERRQ(ierr); 2861e0482f5SStefano Zampini PetscFunctionReturn(0); 2871e0482f5SStefano Zampini } 288a13144ffSStefano Zampini 289213b8bfaSStefano Zampini /* Compute some l2g maps */ 290213b8bfaSStefano Zampini if (nedfieldlocal) { 291c2151214SStefano Zampini IS is; 292c2151214SStefano Zampini 293c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 294c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 2951e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering for the whole dofs*/ 2961e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(al2g,nedfieldlocal,&is);CHKERRQ(ierr); 2971e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&al2g);CHKERRQ(ierr); 2981e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering (for Nedelec only) */ 2991e0482f5SStefano Zampini if (global) { 3001e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3011e0482f5SStefano Zampini el2g = al2g; 3021e0482f5SStefano Zampini } else { 3031e0482f5SStefano Zampini IS gis; 3041e0482f5SStefano Zampini 3051e0482f5SStefano Zampini ierr = ISRenumber(is,NULL,NULL,&gis);CHKERRQ(ierr); 3061e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gis,&el2g);CHKERRQ(ierr); 3071e0482f5SStefano Zampini ierr = ISDestroy(&gis);CHKERRQ(ierr); 3081e0482f5SStefano Zampini } 309c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 310c2151214SStefano Zampini } else { 3111e0482f5SStefano Zampini /* restore default */ 3121e0482f5SStefano Zampini pcbddc->nedfield = -1; 3131e0482f5SStefano Zampini /* one ref for the destruction of al2g, one for el2g */ 3141e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3151e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3161e0482f5SStefano Zampini el2g = al2g; 317c2151214SStefano Zampini fl2g = NULL; 318c2151214SStefano Zampini } 319a13144ffSStefano Zampini 320213b8bfaSStefano Zampini /* Start communication to drop connections for interior edges (for cc analysis only) */ 321580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,n);CHKERRQ(ierr); 322580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,pc->pmat->rmap->n);CHKERRQ(ierr); 323c2151214SStefano Zampini if (nedfieldlocal) { 324c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 325c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 326c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 327c2151214SStefano Zampini } else { 328c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 329c2151214SStefano Zampini } 330c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 331c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 332213b8bfaSStefano Zampini 333213b8bfaSStefano Zampini if (!singular) { /* drop connections with interior edges to avoid unneeded communications and memory movements */ 334213b8bfaSStefano Zampini ierr = MatDuplicate(pcbddc->discretegradient,MAT_COPY_VALUES,&G);CHKERRQ(ierr); 335213b8bfaSStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 3361e0482f5SStefano Zampini if (global) { 3371e0482f5SStefano Zampini PetscInt rst; 3381e0482f5SStefano Zampini 339c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 340c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 341c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 342c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 343c2151214SStefano Zampini } 344c2151214SStefano Zampini } 345a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 346c2151214SStefano Zampini ierr = MatZeroRows(G,cum,matis->sf_rootdata,0.,NULL,NULL);CHKERRQ(ierr); 3471e0482f5SStefano Zampini } else { 3481e0482f5SStefano Zampini PetscInt *tbz; 3491e0482f5SStefano Zampini 3501e0482f5SStefano Zampini ierr = PetscMalloc1(ne,&tbz);CHKERRQ(ierr); 3511e0482f5SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3521e0482f5SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3531e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3541e0482f5SStefano Zampini for (i=0,cum=0;i<ne;i++) 3551e0482f5SStefano Zampini if (matis->sf_leafdata[idxs[i]] == 1) 3561e0482f5SStefano Zampini tbz[cum++] = i; 3571e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3581e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApply(el2g,cum,tbz,tbz);CHKERRQ(ierr); 3591e0482f5SStefano Zampini ierr = MatZeroRows(G,cum,tbz,0.,NULL,NULL);CHKERRQ(ierr); 3601e0482f5SStefano Zampini ierr = PetscFree(tbz);CHKERRQ(ierr); 3611e0482f5SStefano Zampini } 362213b8bfaSStefano Zampini } else { /* we need the entire G to infer the nullspace */ 363213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->discretegradient);CHKERRQ(ierr); 364213b8bfaSStefano Zampini G = pcbddc->discretegradient; 365213b8bfaSStefano Zampini } 366a13144ffSStefano Zampini 367a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 368a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 369a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 3707dae84e0SHong Zhang ierr = MatCreateSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 371a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 372a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 373a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 374a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 375a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 376a13144ffSStefano Zampini 377213b8bfaSStefano Zampini /* SF for nodal dofs communications */ 378c2151214SStefano Zampini ierr = MatGetLocalSize(G,NULL,&Lv);CHKERRQ(ierr); 379a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 380a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 381a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 382a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 383a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 384a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 385a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 386213b8bfaSStefano Zampini i = singular ? 2 : 1; 387213b8bfaSStefano Zampini ierr = PetscMalloc2(i*nv,&sfvleaves,i*Lv,&sfvroots);CHKERRQ(ierr); 388a13144ffSStefano Zampini 3891e0482f5SStefano Zampini /* Destroy temporary G created in MATIS format and modified G */ 390213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 391a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 392213b8bfaSStefano Zampini ierr = MatDestroy(&G);CHKERRQ(ierr); 393a13144ffSStefano Zampini 394213b8bfaSStefano Zampini if (print) { 395213b8bfaSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 396213b8bfaSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 397213b8bfaSStefano Zampini } 398213b8bfaSStefano Zampini 399213b8bfaSStefano Zampini /* Save lG for values insertion in change of basis */ 4000569b399SStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGinit);CHKERRQ(ierr); 4010569b399SStefano Zampini 402a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 4034e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 4044e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 405a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 406a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 407a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 4087d871cd7SStefano Zampini ierr = PetscBTCreate(ne,&btbd);CHKERRQ(ierr); 409c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 410a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 411a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 412a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 413c2151214SStefano Zampini IS is; 414c2151214SStefano Zampini 415c2151214SStefano Zampini if (fl2g) { 416c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 417c2151214SStefano Zampini } else { 418c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 419c2151214SStefano Zampini } 420c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 421c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 422a13144ffSStefano Zampini for (i=0;i<cum;i++) { 423a13144ffSStefano Zampini if (idxs[i] >= 0) { 424a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 4257d871cd7SStefano Zampini ierr = PetscBTSet(btbd,idxs[i]);CHKERRQ(ierr); 426a13144ffSStefano Zampini } 427a13144ffSStefano Zampini } 428c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 429c2151214SStefano Zampini if (fl2g) { 430c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 431c2151214SStefano Zampini } 432a13144ffSStefano Zampini } 433a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 434c2151214SStefano Zampini IS is; 435c2151214SStefano Zampini 436c2151214SStefano Zampini if (fl2g) { 437c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 438c2151214SStefano Zampini } else { 439c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 440c2151214SStefano Zampini } 441c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 442c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 443a13144ffSStefano Zampini for (i=0;i<cum;i++) { 444a13144ffSStefano Zampini if (idxs[i] >= 0) { 445a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 446a13144ffSStefano Zampini } 447a13144ffSStefano Zampini } 448c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 449c2151214SStefano Zampini if (fl2g) { 450c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 451a13144ffSStefano Zampini } 452c2151214SStefano Zampini } 453c2151214SStefano Zampini 454213b8bfaSStefano Zampini /* Count neighs per dof */ 455b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(el2g,NULL,&ecount,&eneighs);CHKERRQ(ierr); 456b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(vl2g,NULL,&vcount,&vneighs);CHKERRQ(ierr); 457637e8532SStefano Zampini 4587d871cd7SStefano Zampini /* need to remove coarse faces' dofs and coarse edges' dirichlet dofs 4597d871cd7SStefano Zampini for proper detection of coarse edges' endpoints */ 46062b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 46162b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 462b63b1311SStefano Zampini if ((ecount[i] > 2 && !PetscBTLookup(btbd,i)) || (ecount[i] == 2 && PetscBTLookup(btb,i))) { 46362b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 46462b0c6f7SStefano Zampini } 46562b0c6f7SStefano Zampini } 466637e8532SStefano Zampini ierr = PetscMalloc1(ne,&marks);CHKERRQ(ierr); 46762b0c6f7SStefano Zampini if (!conforming) { 46862b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 46962b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 47062b0c6f7SStefano Zampini } 4714e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 472dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 47362b0c6f7SStefano Zampini cum = 0; 474a13144ffSStefano Zampini for (i=0;i<ne;i++) { 475dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 47662b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 477a13144ffSStefano Zampini marks[cum++] = i; 478dec27d64SStefano Zampini continue; 479dec27d64SStefano Zampini } 480dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 48162b0c6f7SStefano Zampini if (!conforming) { 48262b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 483a13144ffSStefano Zampini marks[cum++] = i; 484a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 485a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 486a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 487a13144ffSStefano Zampini } 48862b0c6f7SStefano Zampini } else { 48962b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 49062b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 49162b0c6f7SStefano Zampini - at most 2 endpoints 49262b0c6f7SStefano Zampini - order-1 interior nodal dofs 49362b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 49462b0c6f7SStefano Zampini */ 49562b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 49662b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 49762b0c6f7SStefano Zampini PetscInt v = jj[j],k; 49862b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 49962b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 50062b0c6f7SStefano Zampini if (nconn > order) ends++; 50162b0c6f7SStefano Zampini else if (nconn == order) ints++; 50262b0c6f7SStefano Zampini else undef++; 50362b0c6f7SStefano Zampini } 50462b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 50562b0c6f7SStefano Zampini marks[cum++] = i; 50662b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 50762b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 50862b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 50962b0c6f7SStefano Zampini } 51062b0c6f7SStefano Zampini } 51162b0c6f7SStefano Zampini } 512a13144ffSStefano Zampini } 513dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 514dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 515dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 516dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 517a13144ffSStefano Zampini } 518dec27d64SStefano Zampini } 51962b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 520dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 5214e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 52262b0c6f7SStefano Zampini if (!conforming) { 52362b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 52462b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 52562b0c6f7SStefano Zampini } 5264e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 527637e8532SStefano Zampini 528b03ebc13SStefano Zampini /* identify splitpoints and corner candidates */ 5294e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 530a13144ffSStefano Zampini if (print) { 5314e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 5324e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 5334e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 534a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 535a13144ffSStefano Zampini } 536a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 537dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 538a13144ffSStefano Zampini for (i=0;i<nv;i++) { 539637e8532SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i], vc = vcount[i]; 5407d871cd7SStefano Zampini PetscBool sneighs = PETSC_TRUE, bdir = PETSC_FALSE; 541b03ebc13SStefano Zampini if (!order) { /* variable order */ 542dec27d64SStefano Zampini PetscReal vorder = 0.; 543dec27d64SStefano Zampini 544dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 545dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 5466080607fSStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%D)",vorder,test); 547dec27d64SStefano Zampini ord = 1; 548dec27d64SStefano Zampini } 549cf9c20a2SJed Brown if (PetscUnlikelyDebug(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); 550637e8532SStefano Zampini for (j=ii[i];j<ii[i+1] && sneighs;j++) { 5517d871cd7SStefano Zampini if (PetscBTLookup(btbd,jj[j])) { 5527d871cd7SStefano Zampini bdir = PETSC_TRUE; 5537d871cd7SStefano Zampini break; 5547d871cd7SStefano Zampini } 555637e8532SStefano Zampini if (vc != ecount[jj[j]]) { 556637e8532SStefano Zampini sneighs = PETSC_FALSE; 557637e8532SStefano Zampini } else { 558637e8532SStefano Zampini PetscInt k,*vn = vneighs[i], *en = eneighs[jj[j]]; 559637e8532SStefano Zampini for (k=0;k<vc;k++) { 560637e8532SStefano Zampini if (vn[k] != en[k]) { 561637e8532SStefano Zampini sneighs = PETSC_FALSE; 562637e8532SStefano Zampini break; 563637e8532SStefano Zampini } 564637e8532SStefano Zampini } 565637e8532SStefano Zampini } 566637e8532SStefano Zampini } 5677d871cd7SStefano Zampini if (!sneighs || test >= 3*ord || bdir) { /* splitpoints */ 5686080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %D (%D %D %D)\n",i,!sneighs,test >= 3*ord,bdir); 569a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 570dec27d64SStefano Zampini } else if (test == ord) { 571b03ebc13SStefano Zampini if (order == 1 || (!order && ii[i+1]-ii[i] == 1)) { 5726080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %D\n",i); 573a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 574a13144ffSStefano Zampini } else { 5756080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %D\n",i); 576a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 577a13144ffSStefano Zampini } 578a13144ffSStefano Zampini } 579a13144ffSStefano Zampini } 580b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(el2g,NULL,&ecount,&eneighs);CHKERRQ(ierr); 581b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(vl2g,NULL,&vcount,&vneighs);CHKERRQ(ierr); 5827d871cd7SStefano Zampini ierr = PetscBTDestroy(&btbd);CHKERRQ(ierr); 583b03ebc13SStefano Zampini 584b03ebc13SStefano Zampini /* a candidate is valid if it is connected to another candidate via a non-primal edge dof */ 585b03ebc13SStefano Zampini if (order != 1) { 586b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSPECTING CANDIDATES\n"); 587b03ebc13SStefano Zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 588b03ebc13SStefano Zampini for (i=0;i<nv;i++) { 589b03ebc13SStefano Zampini if (PetscBTLookup(btvcand,i)) { 590b03ebc13SStefano Zampini PetscBool found = PETSC_FALSE; 591b03ebc13SStefano Zampini for (j=ii[i];j<ii[i+1] && !found;j++) { 592b03ebc13SStefano Zampini PetscInt k,e = jj[j]; 593b03ebc13SStefano Zampini if (PetscBTLookup(bte,e)) continue; 594b03ebc13SStefano Zampini for (k=iit[e];k<iit[e+1];k++) { 595b03ebc13SStefano Zampini PetscInt v = jjt[k]; 596b03ebc13SStefano Zampini if (v != i && PetscBTLookup(btvcand,v)) { 597b03ebc13SStefano Zampini found = PETSC_TRUE; 598b03ebc13SStefano Zampini break; 599b03ebc13SStefano Zampini } 600b03ebc13SStefano Zampini } 601b03ebc13SStefano Zampini } 602b03ebc13SStefano Zampini if (!found) { 6036080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %D CLEARED\n",i); 604b03ebc13SStefano Zampini ierr = PetscBTClear(btvcand,i);CHKERRQ(ierr); 605b03ebc13SStefano Zampini } else { 6066080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %D ACCEPTED\n",i); 607b03ebc13SStefano Zampini } 608b03ebc13SStefano Zampini } 609b03ebc13SStefano Zampini } 610b03ebc13SStefano Zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 611b03ebc13SStefano Zampini } 612dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 613a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 614b03ebc13SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 615a13144ffSStefano Zampini 616a13144ffSStefano Zampini /* Get the local G^T explicitly */ 6170569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 618a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 6194e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 620a13144ffSStefano Zampini 6214e64d54eSstefano_zampini /* Mark interior nodal dofs */ 622a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6234e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 624a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 625a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 6264e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 627a13144ffSStefano Zampini } 628a13144ffSStefano Zampini } 629a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 630a13144ffSStefano Zampini 631a13144ffSStefano Zampini /* communicate corners and splitpoints */ 632a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 633580bdb30SBarry Smith ierr = PetscArrayzero(sfvleaves,nv);CHKERRQ(ierr); 634580bdb30SBarry Smith ierr = PetscArrayzero(sfvroots,Lv);CHKERRQ(ierr); 635a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 636a13144ffSStefano Zampini 637a13144ffSStefano Zampini if (print) { 638a13144ffSStefano Zampini IS tbz; 639a13144ffSStefano Zampini 640a13144ffSStefano Zampini cum = 0; 641a13144ffSStefano Zampini for (i=0;i<nv;i++) 642a13144ffSStefano Zampini if (sfvleaves[i]) 643a13144ffSStefano Zampini vmarks[cum++] = i; 644a13144ffSStefano Zampini 645a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 646a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 647a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 648a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 649a13144ffSStefano Zampini } 650a13144ffSStefano Zampini 651a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 652a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 653a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 654a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 655a13144ffSStefano Zampini 6564e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 6574e64d54eSstefano_zampini and interior nodal dofs */ 658a13144ffSStefano Zampini cum = 0; 659a13144ffSStefano Zampini for (i=0;i<nv;i++) { 660a13144ffSStefano Zampini if (sfvleaves[i]) { 661a13144ffSStefano Zampini vmarks[cum++] = i; 662a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 663a13144ffSStefano Zampini } 6644e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 665a13144ffSStefano Zampini } 6664e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 667a13144ffSStefano Zampini if (print) { 668a13144ffSStefano Zampini IS tbz; 669a13144ffSStefano Zampini 670a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 6714e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 672a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 673a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 674a13144ffSStefano Zampini } 675a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 676a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 677a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 678a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 679a13144ffSStefano Zampini 680a13144ffSStefano Zampini /* Recompute G */ 681a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 682a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 683a13144ffSStefano Zampini if (print) { 684a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 685a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 686a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 687a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 688a13144ffSStefano Zampini } 689a13144ffSStefano Zampini 690a13144ffSStefano Zampini /* Get primal dofs (if any) */ 691a13144ffSStefano Zampini cum = 0; 692a13144ffSStefano Zampini for (i=0;i<ne;i++) { 693a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 694a13144ffSStefano Zampini } 695c2151214SStefano Zampini if (fl2g) { 696c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 697c2151214SStefano Zampini } 698a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 699a13144ffSStefano Zampini if (print) { 700a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 701a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 702a13144ffSStefano Zampini } 703a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 704c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 705a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 706a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 707a13144ffSStefano Zampini 708a13144ffSStefano Zampini /* Compute edge connectivity */ 709a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 7104222ddf1SHong Zhang 7114222ddf1SHong Zhang /* Symbolic conn = lG*lGt */ 7124222ddf1SHong Zhang ierr = MatProductCreate(lG,lGt,NULL,&conn);CHKERRQ(ierr); 7134222ddf1SHong Zhang ierr = MatProductSetType(conn,MATPRODUCT_AB);CHKERRQ(ierr); 7144222ddf1SHong Zhang ierr = MatProductSetAlgorithm(conn,"default");CHKERRQ(ierr); 7154222ddf1SHong Zhang ierr = MatProductSetFill(conn,PETSC_DEFAULT);CHKERRQ(ierr); 7164222ddf1SHong Zhang ierr = PetscObjectSetOptionsPrefix((PetscObject)conn,"econn_");CHKERRQ(ierr); 7174222ddf1SHong Zhang ierr = MatProductSetFromOptions(conn);CHKERRQ(ierr); 7184222ddf1SHong Zhang ierr = MatProductSymbolic(conn);CHKERRQ(ierr); 7194222ddf1SHong Zhang 720a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 721c2151214SStefano Zampini if (fl2g) { 722c2151214SStefano Zampini PetscBT btf; 723c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 724c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 725c2151214SStefano Zampini 726c2151214SStefano Zampini /* create CSR for all local dofs */ 727c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 728c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 7296080607fSStefano 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); 730c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 731c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 732c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 733c2151214SStefano Zampini rest = PETSC_TRUE; 734c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 735c2151214SStefano Zampini } else { 736c2151214SStefano Zampini free = PETSC_TRUE; 737c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 738c2151214SStefano Zampini iiu[0] = 0; 739c2151214SStefano Zampini for (i=0;i<n;i++) { 740c2151214SStefano Zampini iiu[i+1] = i+1; 741c2151214SStefano Zampini jju[i] = -1; 742d904f53bSStefano Zampini } 743c2151214SStefano Zampini } 744c2151214SStefano Zampini 745c2151214SStefano Zampini /* import sizes of CSR */ 746c2151214SStefano Zampini iia[0] = 0; 747c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 748c2151214SStefano Zampini 749c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 750c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 751c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 752c2151214SStefano Zampini for (i=0;i<ne;i++) { 753c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 754c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 755c2151214SStefano Zampini } 756c2151214SStefano Zampini 757c2151214SStefano Zampini /* iia in CSR */ 758c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 759c2151214SStefano Zampini 760c2151214SStefano Zampini /* jja in CSR */ 761c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 762c2151214SStefano Zampini for (i=0;i<n;i++) 763c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 764c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 765c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 766c2151214SStefano Zampini 767c2151214SStefano Zampini /* map edge dofs connectivity */ 7681e0482f5SStefano Zampini if (jj) { 769c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 770c2151214SStefano Zampini for (i=0;i<ne;i++) { 771c2151214SStefano Zampini PetscInt e = idxs[i]; 772c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 773c2151214SStefano Zampini } 7741e0482f5SStefano Zampini } 775c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 776c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 777c2151214SStefano Zampini if (rest) { 778c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 779c2151214SStefano Zampini } 780c2151214SStefano Zampini if (free) { 781c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 782c2151214SStefano Zampini } 783c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 784c2151214SStefano Zampini } else { 785c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 786c2151214SStefano Zampini } 787c2151214SStefano Zampini 788a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 789a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 790213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 791a13144ffSStefano Zampini 792a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 793c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 794a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 795a13144ffSStefano Zampini 796c2151214SStefano Zampini if (fl2g) { 797c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 798c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 799c2151214SStefano Zampini for (i=0;i<nee;i++) { 800c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 801c2151214SStefano Zampini } 802c2151214SStefano Zampini } else { 803c2151214SStefano Zampini eedges = alleedges; 804c2151214SStefano Zampini primals = allprimals; 805c2151214SStefano Zampini } 806c2151214SStefano Zampini 807a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 808580bdb30SBarry Smith ierr = PetscArrayzero(marks,ne);CHKERRQ(ierr); 809c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 810c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 811c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 812c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 813c2151214SStefano Zampini if (print) { 814c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 815c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 816c2151214SStefano Zampini } 817c2151214SStefano Zampini 818c2151214SStefano Zampini maxsize = 0; 819a13144ffSStefano Zampini for (i=0;i<nee;i++) { 820a13144ffSStefano Zampini PetscInt size,mark = i+1; 821a13144ffSStefano Zampini 822a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 823a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 824a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 825a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 826a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 827a13144ffSStefano Zampini } 828a13144ffSStefano Zampini 829a13144ffSStefano Zampini /* Find coarse edge endpoints */ 830a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 831a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 832a13144ffSStefano Zampini for (i=0;i<nee;i++) { 833a13144ffSStefano Zampini PetscInt mark = i+1,size; 834a13144ffSStefano Zampini 835a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8361e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8376080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 838a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 839a13144ffSStefano Zampini if (print) { 8406080607fSStefano Zampini ierr = PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %D\n",i);CHKERRQ(ierr); 8416080607fSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 842a13144ffSStefano Zampini } 843a13144ffSStefano Zampini for (j=0;j<size;j++) { 844a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 8456080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %D\n",ee); 846a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 8476080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %D\n",jj[k]); 848a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 8496080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %D\n",jj[k]); 850a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 851a13144ffSStefano Zampini PetscInt k2; 852a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 853a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 8546080607fSStefano 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])); 855c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 856c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 857c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 858a13144ffSStefano Zampini corner = PETSC_TRUE; 859a13144ffSStefano Zampini break; 860a13144ffSStefano Zampini } 861a13144ffSStefano Zampini } 862a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 8636080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %D\n",jj[k]); 864a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 865a13144ffSStefano Zampini } else { 866a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 867a13144ffSStefano Zampini } 868a13144ffSStefano Zampini } 869a13144ffSStefano Zampini } 870a13144ffSStefano Zampini } 871a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 872a13144ffSStefano Zampini } 873a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 874a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 875c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 876a13144ffSStefano Zampini 877a13144ffSStefano Zampini /* Reset marked primal dofs */ 878a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 879a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 880a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 881a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 882a13144ffSStefano Zampini 8830569b399SStefano Zampini /* Now use the initial lG */ 8840569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 8850569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 8860569b399SStefano Zampini lG = lGinit; 8870569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 8880569b399SStefano Zampini 889a13144ffSStefano Zampini /* Compute extended cols indices */ 890b03ebc13SStefano Zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 891b03ebc13SStefano Zampini ierr = PetscBTCreate(nee,&bter);CHKERRQ(ierr); 892a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 893a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 894a13144ffSStefano Zampini i *= maxsize; 895b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 896a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 897a13144ffSStefano Zampini eerr = PETSC_FALSE; 898a13144ffSStefano Zampini for (i=0;i<nee;i++) { 899b03ebc13SStefano Zampini PetscInt size,found = 0; 900a13144ffSStefano Zampini 901a13144ffSStefano Zampini cum = 0; 902a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 9031e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 9046080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 905a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 906b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 907a13144ffSStefano Zampini for (j=0;j<size;j++) { 908a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 909b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 910b03ebc13SStefano Zampini PetscInt vv = jj[k]; 911b03ebc13SStefano Zampini if (!PetscBTLookup(btv,vv)) extrow[cum++] = vv; 912b03ebc13SStefano Zampini else if (!PetscBTLookupSet(btvc,vv)) found++; 913b03ebc13SStefano Zampini } 914a13144ffSStefano Zampini } 915a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 916a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 917a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 918a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 919a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 920a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 921a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 922b03ebc13SStefano Zampini if (cum != size -1 || found != 2) { 923b03ebc13SStefano Zampini ierr = PetscBTSet(bter,i);CHKERRQ(ierr); 924a13144ffSStefano Zampini if (print) { 925a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 926a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 927a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 928a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 929a13144ffSStefano Zampini } 930a13144ffSStefano Zampini eerr = PETSC_TRUE; 931a13144ffSStefano Zampini } 932a13144ffSStefano Zampini } 9334e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 934a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 935a13144ffSStefano Zampini if (done) { 936a13144ffSStefano Zampini PetscInt *newprimals; 937a13144ffSStefano Zampini 938a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 939a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 940a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 941580bdb30SBarry Smith ierr = PetscArraycpy(newprimals,idxs,cum);CHKERRQ(ierr); 942a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 9430569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 9446080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"DOING SECOND PASS (eerr %D)\n",eerr); 945a13144ffSStefano Zampini for (i=0;i<nee;i++) { 946b03ebc13SStefano Zampini PetscBool has_candidates = PETSC_FALSE; 947b03ebc13SStefano Zampini if (PetscBTLookup(bter,i)) { 948a13144ffSStefano Zampini PetscInt size,mark = i+1; 949a13144ffSStefano Zampini 950a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 951a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 952c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 953a13144ffSStefano Zampini for (j=0;j<size;j++) { 954a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 9556080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"Inspecting edge dof %D [%D %D)\n",ee,ii[ee],ii[ee+1]); 956a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 957a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 958a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 959a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 960b03ebc13SStefano Zampini has_candidates = PETSC_TRUE; 9616080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Candidate set to vertex %D\n",vv); 962a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 963a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 964a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 965a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 966a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 9676080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected edge dof set to primal %D\n",ee2); 968a13144ffSStefano Zampini newprimals[cum++] = ee2; 969a13144ffSStefano Zampini /* finally set the new corners */ 970a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 9716080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected nodal dof set to vertex %D\n",jj[k3]); 972a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 973a13144ffSStefano Zampini } 974a13144ffSStefano Zampini } 975a13144ffSStefano Zampini } 976b03ebc13SStefano Zampini } else { 9776080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Not a candidate vertex %D\n",jj[k]); 978a13144ffSStefano Zampini } 979a13144ffSStefano Zampini } 980a13144ffSStefano Zampini } 981b03ebc13SStefano Zampini if (!has_candidates) { /* circular edge */ 982b03ebc13SStefano Zampini PetscInt k, ee = idxs[0],*tmarks; 983b03ebc13SStefano Zampini 984b03ebc13SStefano Zampini ierr = PetscCalloc1(ne,&tmarks);CHKERRQ(ierr); 9856080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Circular edge %D\n",i); 986b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 987b03ebc13SStefano Zampini PetscInt k2; 9886080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Set to corner %D\n",jj[k]); 989b03ebc13SStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 990b03ebc13SStefano Zampini for (k2=iit[jj[k]];k2<iit[jj[k]+1];k2++) tmarks[jjt[k2]]++; 991b03ebc13SStefano Zampini } 992b03ebc13SStefano Zampini for (j=0;j<size;j++) { 993b03ebc13SStefano Zampini if (tmarks[idxs[j]] > 1) { 9946080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Edge dof set to primal %D\n",idxs[j]); 995b03ebc13SStefano Zampini newprimals[cum++] = idxs[j]; 996b03ebc13SStefano Zampini } 997b03ebc13SStefano Zampini } 998b03ebc13SStefano Zampini ierr = PetscFree(tmarks);CHKERRQ(ierr); 999b03ebc13SStefano Zampini } 1000a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1001a13144ffSStefano Zampini } 1002a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 1003a13144ffSStefano Zampini } 1004b03ebc13SStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 10050569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 1006a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 1007c2151214SStefano Zampini if (fl2g) { 1008c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 1009c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1010c2151214SStefano Zampini for (i=0;i<nee;i++) { 1011c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1012c2151214SStefano Zampini } 1013c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1014c2151214SStefano Zampini } 1015c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1016a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 1017a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 1018a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 1019a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1020a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 1021213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 1022c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1023c2151214SStefano Zampini if (fl2g) { 1024c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 1025c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 1026c2151214SStefano Zampini for (i=0;i<nee;i++) { 1027c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 1028c2151214SStefano Zampini } 1029c2151214SStefano Zampini } else { 1030c2151214SStefano Zampini eedges = alleedges; 1031c2151214SStefano Zampini primals = allprimals; 1032c2151214SStefano Zampini } 1033b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 1034a13144ffSStefano Zampini 1035a13144ffSStefano Zampini /* Mark again */ 1036580bdb30SBarry Smith ierr = PetscArrayzero(marks,ne);CHKERRQ(ierr); 1037a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1038a13144ffSStefano Zampini PetscInt size,mark = i+1; 1039a13144ffSStefano Zampini 1040a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1041a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1042a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 1043a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1044a13144ffSStefano Zampini } 1045a13144ffSStefano Zampini if (print) { 1046a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 1047a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 1048a13144ffSStefano Zampini } 1049a13144ffSStefano Zampini 1050a13144ffSStefano Zampini /* Recompute extended cols */ 1051a13144ffSStefano Zampini eerr = PETSC_FALSE; 1052a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1053a13144ffSStefano Zampini PetscInt size; 1054a13144ffSStefano Zampini 1055a13144ffSStefano Zampini cum = 0; 1056a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 10571e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 10586080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 1059a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1060a13144ffSStefano Zampini for (j=0;j<size;j++) { 1061a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 10621e0482f5SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 1063a13144ffSStefano Zampini } 1064a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1065a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 1066a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 1067a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 1068a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 1069a13144ffSStefano Zampini if (cum != size -1) { 1070a13144ffSStefano Zampini if (print) { 1071a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 1072a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 1073a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 1074a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 1075a13144ffSStefano Zampini } 1076a13144ffSStefano Zampini eerr = PETSC_TRUE; 1077a13144ffSStefano Zampini } 1078a13144ffSStefano Zampini } 1079a13144ffSStefano Zampini } 1080a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1081a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 1082b03ebc13SStefano Zampini ierr = PetscBTDestroy(&bter);CHKERRQ(ierr); 10837d871cd7SStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 1084a13144ffSStefano Zampini /* an error should not occur at this point */ 1085a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 1086a13144ffSStefano Zampini 10874e64d54eSstefano_zampini /* Check the number of endpoints */ 10880569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1089b03ebc13SStefano Zampini ierr = PetscMalloc1(2*nee,&corners);CHKERRQ(ierr); 1090b03ebc13SStefano Zampini ierr = PetscMalloc1(nee,&cedges);CHKERRQ(ierr); 10914e64d54eSstefano_zampini for (i=0;i<nee;i++) { 1092b03ebc13SStefano Zampini PetscInt size, found = 0, gc[2]; 10934e64d54eSstefano_zampini 1094b03ebc13SStefano Zampini /* init with defaults */ 1095b03ebc13SStefano Zampini cedges[i] = corners[i*2] = corners[i*2+1] = -1; 10964e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 10971e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 10986080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 10994e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1100b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 11014e64d54eSstefano_zampini for (j=0;j<size;j++) { 11024e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 11034e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 11044e64d54eSstefano_zampini PetscInt vv = jj[k]; 11054e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 11066080607fSStefano Zampini if (found == 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found more then two corners for edge %D",i); 1107b03ebc13SStefano Zampini corners[i*2+found++] = vv; 11084e64d54eSstefano_zampini } 11094e64d54eSstefano_zampini } 11104e64d54eSstefano_zampini } 1111b03ebc13SStefano Zampini if (found != 2) { 1112b03ebc13SStefano Zampini PetscInt e; 1113b03ebc13SStefano Zampini if (fl2g) { 1114b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,1,idxs,&e);CHKERRQ(ierr); 1115b03ebc13SStefano Zampini } else { 1116b03ebc13SStefano Zampini e = idxs[0]; 1117b03ebc13SStefano Zampini } 11186080607fSStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %D corners for edge %D (astart %D, estart %D)",found,i,e,idxs[0]); 1119b03ebc13SStefano Zampini } 1120eee23b56SStefano Zampini 1121eee23b56SStefano Zampini /* get primal dof index on this coarse edge */ 1122b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,2,corners+2*i,gc);CHKERRQ(ierr); 1123b03ebc13SStefano Zampini if (gc[0] > gc[1]) { 1124b03ebc13SStefano Zampini PetscInt swap = corners[2*i]; 1125b03ebc13SStefano Zampini corners[2*i] = corners[2*i+1]; 1126b03ebc13SStefano Zampini corners[2*i+1] = swap; 1127b03ebc13SStefano Zampini } 1128eee23b56SStefano Zampini cedges[i] = idxs[size-1]; 11294e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 11306080607fSStefano 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]); 11314e64d54eSstefano_zampini } 11320569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 11334e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 11344e64d54eSstefano_zampini 113576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1136a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 1137a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 1138a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 1139a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1140a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1141a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 1142a13144ffSStefano Zampini 1143a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1144580bdb30SBarry Smith ierr = PetscArrayzero(emarks,nee+1);CHKERRQ(ierr); 1145a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 1146a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 1147a13144ffSStefano Zampini if (emax < emarks[j]) { 1148a13144ffSStefano Zampini emax = emarks[j]; 1149a13144ffSStefano Zampini eemax = j; 1150a13144ffSStefano Zampini } 1151a13144ffSStefano Zampini } 1152a13144ffSStefano Zampini /* not relevant for edges */ 1153a13144ffSStefano Zampini if (!eemax) continue; 1154a13144ffSStefano Zampini 1155a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 1156a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 11576080607fSStefano 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]); 1158a13144ffSStefano Zampini } 1159a13144ffSStefano Zampini } 1160a13144ffSStefano Zampini } 1161a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 1162a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 116376bd3646SJed Brown } 1164a13144ffSStefano Zampini 1165a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 1166a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1167a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 1168a13144ffSStefano Zampini extmem *= maxsize; 1169a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 1170a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 1171a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 1172a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1173a13144ffSStefano Zampini PetscInt mark = 0,size,start; 1174213b8bfaSStefano Zampini 1175a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1176a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 1177a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 1178a13144ffSStefano Zampini mark = marks[jj[j]]; 1179a13144ffSStefano Zampini 1180a13144ffSStefano Zampini /* not relevant */ 1181a13144ffSStefano Zampini if (!mark) continue; 1182a13144ffSStefano Zampini 1183a13144ffSStefano Zampini /* import extended row */ 1184a13144ffSStefano Zampini mark--; 1185a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 1186a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 11876080607fSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %D > %D",extrowcum[mark] + size,extmem); 1188580bdb30SBarry Smith ierr = PetscArraycpy(extrow+start,jj+ii[i],size);CHKERRQ(ierr); 1189a13144ffSStefano Zampini extrowcum[mark] += size; 1190a13144ffSStefano Zampini } 1191a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1192213b8bfaSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1193213b8bfaSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 1194213b8bfaSStefano Zampini 1195213b8bfaSStefano Zampini /* Compress extrows */ 1196a13144ffSStefano Zampini cum = 0; 1197a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1198a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 1199a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 1200a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 1201a13144ffSStefano Zampini cum = PetscMax(cum,size); 1202a13144ffSStefano Zampini } 1203a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 1204a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 1205a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 1206a13144ffSStefano Zampini 1207a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 1208a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 1209a13144ffSStefano Zampini 1210a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 1211a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1212c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 1213c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 1214a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 1215a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 1216a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 12171e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(T,al2g,al2g);CHKERRQ(ierr); 1218a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 1219a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1220213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&al2g);CHKERRQ(ierr); 1221a13144ffSStefano Zampini 1222a13144ffSStefano Zampini /* Defaults to identity */ 1223c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 1224a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 1225a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 1226a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 1227a13144ffSStefano Zampini 12281e0482f5SStefano Zampini /* Create discrete gradient for the coarser level if needed */ 12291e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 12301e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 12311e0482f5SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 12321e0482f5SStefano Zampini ISLocalToGlobalMapping cel2g,cvl2g; 12331e0482f5SStefano Zampini IS wis,gwis; 12341e0482f5SStefano Zampini PetscInt cnv,cne; 12351e0482f5SStefano Zampini 12361e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,nee,cedges,PETSC_COPY_VALUES,&wis);CHKERRQ(ierr); 12371e0482f5SStefano Zampini if (fl2g) { 12381e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(fl2g,wis,&pcbddc->nedclocal);CHKERRQ(ierr); 12391e0482f5SStefano Zampini } else { 12401e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)wis);CHKERRQ(ierr); 12411e0482f5SStefano Zampini pcbddc->nedclocal = wis; 12421e0482f5SStefano Zampini } 12431e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,wis,&gwis);CHKERRQ(ierr); 12441e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12451e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cne,&wis);CHKERRQ(ierr); 12461e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cel2g);CHKERRQ(ierr); 12471e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12481e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12491e0482f5SStefano Zampini 12501e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,2*nee,corners,PETSC_USE_POINTER,&wis);CHKERRQ(ierr); 12511e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(vl2g,wis,&gwis);CHKERRQ(ierr); 12521e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12531e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cnv,&wis);CHKERRQ(ierr); 12541e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cvl2g);CHKERRQ(ierr); 12551e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12561e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12571e0482f5SStefano Zampini 12581e0482f5SStefano Zampini ierr = MatCreate(comm,&pcbddc->nedcG);CHKERRQ(ierr); 12591e0482f5SStefano Zampini ierr = MatSetSizes(pcbddc->nedcG,PETSC_DECIDE,PETSC_DECIDE,cne,cnv);CHKERRQ(ierr); 12601e0482f5SStefano Zampini ierr = MatSetType(pcbddc->nedcG,MATAIJ);CHKERRQ(ierr); 12611e0482f5SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->nedcG,2,NULL);CHKERRQ(ierr); 12621e0482f5SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->nedcG,2,NULL,2,NULL);CHKERRQ(ierr); 12631e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->nedcG,cel2g,cvl2g);CHKERRQ(ierr); 12641e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cel2g);CHKERRQ(ierr); 12651e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cvl2g);CHKERRQ(ierr); 12661e0482f5SStefano Zampini } 1267213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 12681e0482f5SStefano Zampini 12691e0482f5SStefano Zampini #if defined(PRINT_GDET) 12701e0482f5SStefano Zampini inc = 0; 12711e0482f5SStefano Zampini lev = pcbddc->current_level; 12721e0482f5SStefano Zampini #endif 1273213b8bfaSStefano Zampini 1274213b8bfaSStefano Zampini /* Insert values in the change of basis matrix */ 1275a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1276a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 12771e0482f5SStefano Zampini IS cornersis = NULL; 12781e0482f5SStefano Zampini PetscScalar cvals[2]; 1279a13144ffSStefano Zampini 12801e0482f5SStefano Zampini if (pcbddc->nedcG) { 12811e0482f5SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners+2*i,PETSC_USE_POINTER,&cornersis);CHKERRQ(ierr); 12821e0482f5SStefano Zampini } 12831e0482f5SStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],cornersis,&Gins,&GKins,cvals,work,rwork);CHKERRQ(ierr); 1284a13144ffSStefano Zampini if (Gins && GKins) { 12851683a169SBarry Smith const PetscScalar *data; 1286a13144ffSStefano Zampini const PetscInt *rows,*cols; 1287a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 1288a13144ffSStefano Zampini 1289a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 1290a13144ffSStefano Zampini /* H1 */ 1291a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 1292a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 12931683a169SBarry Smith ierr = MatDenseGetArrayRead(Gins,&data);CHKERRQ(ierr); 1294a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 12951683a169SBarry Smith ierr = MatDenseRestoreArrayRead(Gins,&data);CHKERRQ(ierr); 1296a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 1297a13144ffSStefano Zampini /* complement */ 1298a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 12996080607fSStefano Zampini if (!ncc) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Constant function has not been generated for coarse edge %D",i); 13006080607fSStefano 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); 13016080607fSStefano 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); 13021683a169SBarry Smith ierr = MatDenseGetArrayRead(GKins,&data);CHKERRQ(ierr); 1303a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 13041683a169SBarry Smith ierr = MatDenseRestoreArrayRead(GKins,&data);CHKERRQ(ierr); 13051e0482f5SStefano Zampini 13061e0482f5SStefano Zampini /* coarse discrete gradient */ 13071e0482f5SStefano Zampini if (pcbddc->nedcG) { 13081e0482f5SStefano Zampini PetscInt cols[2]; 13091e0482f5SStefano Zampini 13101e0482f5SStefano Zampini cols[0] = 2*i; 13111e0482f5SStefano Zampini cols[1] = 2*i+1; 13121e0482f5SStefano Zampini ierr = MatSetValuesLocal(pcbddc->nedcG,1,&i,2,cols,cvals,INSERT_VALUES);CHKERRQ(ierr); 13131e0482f5SStefano Zampini } 1314a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1315a13144ffSStefano Zampini } 1316a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1317a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 13181e0482f5SStefano Zampini ierr = ISDestroy(&cornersis);CHKERRQ(ierr); 1319a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1320a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1321a13144ffSStefano Zampini } 1322213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 1323a13144ffSStefano Zampini 1324a13144ffSStefano Zampini /* Start assembling */ 1325a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13261e0482f5SStefano Zampini if (pcbddc->nedcG) { 13271e0482f5SStefano Zampini ierr = MatAssemblyBegin(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13281e0482f5SStefano Zampini } 1329a13144ffSStefano Zampini 1330a13144ffSStefano Zampini /* Free */ 1331c2151214SStefano Zampini if (fl2g) { 1332c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1333c2151214SStefano Zampini for (i=0;i<nee;i++) { 1334c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1335c2151214SStefano Zampini } 1336c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1337c2151214SStefano Zampini } 1338eee23b56SStefano Zampini 1339eee23b56SStefano Zampini /* hack mat_graph with primal dofs on the coarse edges */ 1340eee23b56SStefano Zampini { 1341eee23b56SStefano Zampini PCBDDCGraph graph = pcbddc->mat_graph; 1342eee23b56SStefano Zampini PetscInt *oqueue = graph->queue; 1343eee23b56SStefano Zampini PetscInt *ocptr = graph->cptr; 1344eee23b56SStefano Zampini PetscInt ncc,*idxs; 1345eee23b56SStefano Zampini 1346eee23b56SStefano Zampini /* find first primal edge */ 1347eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1348eee23b56SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1349eee23b56SStefano Zampini } else { 1350eee23b56SStefano Zampini if (fl2g) { 1351eee23b56SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,nee,cedges,cedges);CHKERRQ(ierr); 1352eee23b56SStefano Zampini } 1353eee23b56SStefano Zampini idxs = cedges; 1354eee23b56SStefano Zampini } 1355eee23b56SStefano Zampini cum = 0; 1356eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1357eee23b56SStefano Zampini 1358eee23b56SStefano Zampini /* adapt connected components */ 1359eee23b56SStefano Zampini ierr = PetscMalloc2(graph->nvtxs+1,&graph->cptr,ocptr[graph->ncc],&graph->queue);CHKERRQ(ierr); 1360eee23b56SStefano Zampini graph->cptr[0] = 0; 1361eee23b56SStefano Zampini for (i=0,ncc=0;i<graph->ncc;i++) { 1362eee23b56SStefano Zampini PetscInt lc = ocptr[i+1]-ocptr[i]; 1363eee23b56SStefano Zampini if (cum != nee && oqueue[ocptr[i+1]-1] == cedges[cum]) { /* this cc has a primal dof */ 1364eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc]+1; 1365eee23b56SStefano Zampini graph->queue[graph->cptr[ncc]] = cedges[cum]; 1366eee23b56SStefano Zampini ncc++; 1367eee23b56SStefano Zampini lc--; 1368eee23b56SStefano Zampini cum++; 1369eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1370eee23b56SStefano Zampini } 1371eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc] + lc; 1372eee23b56SStefano Zampini for (j=0;j<lc;j++) graph->queue[graph->cptr[ncc]+j] = oqueue[ocptr[i]+j]; 1373eee23b56SStefano Zampini ncc++; 1374eee23b56SStefano Zampini } 1375eee23b56SStefano Zampini graph->ncc = ncc; 1376eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1377eee23b56SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1378eee23b56SStefano Zampini } 1379eee23b56SStefano Zampini ierr = PetscFree2(ocptr,oqueue);CHKERRQ(ierr); 1380eee23b56SStefano Zampini } 1381213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1382c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1383c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1384213b8bfaSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1385eee23b56SStefano Zampini 1386c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1387a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1388a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1389b03ebc13SStefano Zampini ierr = PetscFree(corners);CHKERRQ(ierr); 1390b03ebc13SStefano Zampini ierr = PetscFree(cedges);CHKERRQ(ierr); 1391a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1392a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1393a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1394a13144ffSStefano Zampini 1395a13144ffSStefano Zampini /* Complete assembling */ 1396a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13971e0482f5SStefano Zampini if (pcbddc->nedcG) { 13981e0482f5SStefano Zampini ierr = MatAssemblyEnd(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13991e0482f5SStefano Zampini #if 0 14001e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->nedcG,"coarse_G");CHKERRQ(ierr); 14011e0482f5SStefano Zampini ierr = MatView(pcbddc->nedcG,NULL);CHKERRQ(ierr); 14021e0482f5SStefano Zampini #endif 14031e0482f5SStefano Zampini } 1404a13144ffSStefano Zampini 1405a13144ffSStefano Zampini /* set change of basis */ 1406213b8bfaSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,singular);CHKERRQ(ierr); 1407a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1408a13144ffSStefano Zampini 1409a13144ffSStefano Zampini PetscFunctionReturn(0); 1410a13144ffSStefano Zampini } 1411a13144ffSStefano Zampini 1412d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1413d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1414d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1415d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1416d8203eabSStefano Zampini { 1417d8203eabSStefano Zampini PetscErrorCode ierr; 1418d8203eabSStefano Zampini PetscInt i; 1419d8203eabSStefano Zampini 1420d8203eabSStefano Zampini PetscFunctionBegin; 1421d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1422d8203eabSStefano Zampini PetscInt first,last; 1423d8203eabSStefano Zampini 1424d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 142586fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1426d8203eabSStefano Zampini if (i>=first && i < last) { 1427d8203eabSStefano Zampini PetscScalar *data; 1428d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1429d8203eabSStefano Zampini if (!has_const) { 1430d8203eabSStefano Zampini data[i-first] = 1.; 1431d8203eabSStefano Zampini } else { 143286fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 143386fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1434d8203eabSStefano Zampini } 1435d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1436d8203eabSStefano Zampini } 1437d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1438d8203eabSStefano Zampini } 1439d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1440d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1441d8203eabSStefano Zampini PetscInt first,last; 14428860a134SJunchao Zhang ierr = VecLockReadPop(quad_vecs[i]);CHKERRQ(ierr); 1443d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1444d8203eabSStefano Zampini if (i>=first && i < last) { 1445d8203eabSStefano Zampini PetscScalar *data; 1446d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1447d8203eabSStefano Zampini if (!has_const) { 1448d8203eabSStefano Zampini data[i-first] = 0.; 1449d8203eabSStefano Zampini } else { 145086fa73c5SStefano Zampini data[2*i-first] = 0.; 145186fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1452d8203eabSStefano Zampini } 1453d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1454d8203eabSStefano Zampini } 1455d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 14568860a134SJunchao Zhang ierr = VecLockReadPush(quad_vecs[i]);CHKERRQ(ierr); 1457d8203eabSStefano Zampini } 1458d8203eabSStefano Zampini PetscFunctionReturn(0); 1459d8203eabSStefano Zampini } 1460d8203eabSStefano Zampini 14618ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1462669cc0f4SStefano Zampini { 1463a198735bSStefano Zampini Mat loc_divudotp; 1464fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 14658ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1466669cc0f4SStefano Zampini PetscScalar *vals; 1467669cc0f4SStefano Zampini const PetscScalar *array; 14680f04eeffSStefano Zampini PetscInt i,maxneighs = 0,maxsize,*gidxs; 1469a040e873SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 14701ae86dd6SStefano Zampini PetscMPIInt rank; 1471a198735bSStefano Zampini PetscErrorCode ierr; 1472669cc0f4SStefano Zampini 1473669cc0f4SStefano Zampini PetscFunctionBegin; 1474a040e873SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 14750f04eeffSStefano Zampini for (i=0;i<n_neigh;i++) maxneighs = PetscMax(graph->count[shared[i][0]]+1,maxneighs); 14760f04eeffSStefano Zampini ierr = MPIU_Allreduce(MPI_IN_PLACE,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 14778037d520SStefano Zampini if (!maxneighs) { 14788037d520SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 14798037d520SStefano Zampini *nnsp = NULL; 14808037d520SStefano Zampini PetscFunctionReturn(0); 1481669cc0f4SStefano Zampini } 1482669cc0f4SStefano Zampini maxsize = 0; 1483a040e873SStefano Zampini for (i=0;i<n_neigh;i++) maxsize = PetscMax(n_shared[i],maxsize); 14840f27d399SStefano Zampini ierr = PetscMalloc2(maxsize,&gidxs,maxsize,&vals);CHKERRQ(ierr); 1485669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1486669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 14878ae0ca82SStefano Zampini if (!transpose) { 14888ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 14898ae0ca82SStefano Zampini } else { 14908ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 14918ae0ca82SStefano Zampini } 1492669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 14931ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1494d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1495669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 14968860a134SJunchao Zhang ierr = VecLockReadPop(quad_vecs[i]);CHKERRQ(ierr); 1497669cc0f4SStefano Zampini } 1498d8203eabSStefano Zampini 1499669cc0f4SStefano Zampini /* compute local quad vec */ 1500a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 15018ae0ca82SStefano Zampini if (!transpose) { 1502a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 15038ae0ca82SStefano Zampini } else { 15048ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 15058ae0ca82SStefano Zampini } 1506669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 15078ae0ca82SStefano Zampini if (!transpose) { 1508a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 15098ae0ca82SStefano Zampini } else { 15108ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 15118ae0ca82SStefano Zampini } 1512fa23a32eSStefano Zampini if (vl2l) { 1513187c917aSStefano Zampini Mat lA; 1514187c917aSStefano Zampini VecScatter sc; 1515187c917aSStefano Zampini 1516187c917aSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1517187c917aSStefano Zampini ierr = MatCreateVecs(lA,&vins,NULL);CHKERRQ(ierr); 15189448b7f1SJunchao Zhang ierr = VecScatterCreate(v,NULL,vins,vl2l,&sc);CHKERRQ(ierr); 1519187c917aSStefano Zampini ierr = VecScatterBegin(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1520187c917aSStefano Zampini ierr = VecScatterEnd(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1521187c917aSStefano Zampini ierr = VecScatterDestroy(&sc);CHKERRQ(ierr); 1522fa23a32eSStefano Zampini } else { 1523fa23a32eSStefano Zampini vins = v; 1524fa23a32eSStefano Zampini } 1525fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1526669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 15279a962809SStefano Zampini 15281ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 1529ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRMPI(ierr); 15300f04eeffSStefano Zampini for (i=1;i<n_neigh;i++) { 1531669cc0f4SStefano Zampini const PetscInt *idxs; 1532669cc0f4SStefano Zampini PetscInt idx,nn,j; 1533669cc0f4SStefano Zampini 1534a040e873SStefano Zampini idxs = shared[i]; 1535a040e873SStefano Zampini nn = n_shared[i]; 1536669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 15371ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1538669cc0f4SStefano Zampini idx = -(idx+1); 15390f04eeffSStefano Zampini if (idx < 0 || idx >= maxneighs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid index %D not in [0,%D)",idx,maxneighs); 15400f27d399SStefano Zampini ierr = ISLocalToGlobalMappingApply(map,nn,idxs,gidxs);CHKERRQ(ierr); 15410f27d399SStefano Zampini ierr = VecSetValues(quad_vecs[idx],nn,gidxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1542669cc0f4SStefano Zampini } 1543a040e873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1544fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1545fa23a32eSStefano Zampini if (vl2l) { 1546187c917aSStefano Zampini ierr = VecDestroy(&vins);CHKERRQ(ierr); 1547fa23a32eSStefano Zampini } 1548669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 15490f27d399SStefano Zampini ierr = PetscFree2(gidxs,vals);CHKERRQ(ierr); 1550669cc0f4SStefano Zampini 1551669cc0f4SStefano Zampini /* assemble near null space */ 1552669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1553669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1554669cc0f4SStefano Zampini } 1555669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1556669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 15573272d46bSStefano Zampini ierr = VecViewFromOptions(quad_vecs[i],NULL,"-pc_bddc_quad_vecs_view");CHKERRQ(ierr); 15588860a134SJunchao Zhang ierr = VecLockReadPush(quad_vecs[i]);CHKERRQ(ierr); 1559669cc0f4SStefano Zampini } 1560669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1561669cc0f4SStefano Zampini PetscFunctionReturn(0); 1562669cc0f4SStefano Zampini } 1563669cc0f4SStefano Zampini 15647620a527SStefano Zampini PetscErrorCode PCBDDCAddPrimalVerticesLocalIS(PC pc, IS primalv) 15657620a527SStefano Zampini { 15667620a527SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15677620a527SStefano Zampini PetscErrorCode ierr; 15687620a527SStefano Zampini 15697620a527SStefano Zampini PetscFunctionBegin; 15707620a527SStefano Zampini if (primalv) { 15717620a527SStefano Zampini if (pcbddc->user_primal_vertices_local) { 15727620a527SStefano Zampini IS list[2], newp; 15737620a527SStefano Zampini 15747620a527SStefano Zampini list[0] = primalv; 15757620a527SStefano Zampini list[1] = pcbddc->user_primal_vertices_local; 15767620a527SStefano Zampini ierr = ISConcatenate(PetscObjectComm((PetscObject)pc),2,list,&newp);CHKERRQ(ierr); 15777620a527SStefano Zampini ierr = ISSortRemoveDups(newp);CHKERRQ(ierr); 15787620a527SStefano Zampini ierr = ISDestroy(&list[1]);CHKERRQ(ierr); 15797620a527SStefano Zampini pcbddc->user_primal_vertices_local = newp; 15807620a527SStefano Zampini } else { 15817620a527SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 15827620a527SStefano Zampini } 15837620a527SStefano Zampini } 15847620a527SStefano Zampini PetscFunctionReturn(0); 15857620a527SStefano Zampini } 1586669cc0f4SStefano Zampini 15871c7a958bSStefano Zampini static PetscErrorCode func_coords_private(PetscInt dim, PetscReal t, const PetscReal X[], PetscInt Nf, PetscScalar *out, void *ctx) 15881c7a958bSStefano Zampini { 15891c7a958bSStefano Zampini PetscInt f, *comp = (PetscInt *)ctx; 15901c7a958bSStefano Zampini 15911c7a958bSStefano Zampini PetscFunctionBegin; 15921c7a958bSStefano Zampini for (f=0;f<Nf;f++) out[f] = X[*comp]; 15931c7a958bSStefano Zampini PetscFunctionReturn(0); 15941c7a958bSStefano Zampini } 1595674ae819SStefano Zampini 15961f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 15971f4df5f7SStefano Zampini { 15981f4df5f7SStefano Zampini PetscErrorCode ierr; 15991f4df5f7SStefano Zampini Vec local,global; 16001f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16011f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 16025c5e10d6SStefano Zampini PetscBool monolithic = PETSC_FALSE; 16031f4df5f7SStefano Zampini 16041f4df5f7SStefano Zampini PetscFunctionBegin; 16055c5e10d6SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC topology options","PC");CHKERRQ(ierr); 16065c5e10d6SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_monolithic","Discard any information on dofs splitting",NULL,monolithic,&monolithic,NULL);CHKERRQ(ierr); 16075c5e10d6SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 16081f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 160921ef3d20SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 16101f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 1611b470e4b4SRichard Tran Mills ierr = VecBindToCPU(global,PETSC_TRUE);CHKERRQ(ierr); 1612b470e4b4SRichard Tran Mills ierr = VecBindToCPU(local,PETSC_TRUE);CHKERRQ(ierr); 16136a8fc67bSStefano Zampini if (monolithic) { /* just get block size to properly compute vertices */ 16146a8fc67bSStefano Zampini if (pcbddc->vertex_size == 1) { 16156a8fc67bSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->vertex_size);CHKERRQ(ierr); 16166a8fc67bSStefano Zampini } 16176a8fc67bSStefano Zampini goto boundary; 16186a8fc67bSStefano Zampini } 16195c5e10d6SStefano Zampini 16201f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 16211f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 16221f4df5f7SStefano Zampini PetscInt i; 16230c85b387SStefano Zampini 16241f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16251f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 16260c85b387SStefano Zampini PetscInt bs; 16270c85b387SStefano Zampini 16281f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16290c85b387SStefano Zampini ierr = ISGetBlockSize(pcbddc->ISForDofs[i],&bs);CHKERRQ(ierr); 16300c85b387SStefano Zampini ierr = ISSetBlockSize(pcbddc->ISForDofsLocal[i],bs);CHKERRQ(ierr); 16311f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 16321f4df5f7SStefano Zampini } 16331f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 16341f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 16351f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 16361f4df5f7SStefano Zampini } 16371f4df5f7SStefano Zampini } else { 163821ef3d20SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present */ 163921ef3d20SStefano Zampini DM dm; 164021ef3d20SStefano Zampini 164121ef3d20SStefano Zampini ierr = MatGetDM(pc->pmat, &dm);CHKERRQ(ierr); 16424f819b78SStefano Zampini if (!dm) { 16434f819b78SStefano Zampini ierr = PCGetDM(pc, &dm);CHKERRQ(ierr); 164421ef3d20SStefano Zampini } 164521ef3d20SStefano Zampini if (dm) { 164621ef3d20SStefano Zampini IS *fields; 164721ef3d20SStefano Zampini PetscInt nf,i; 16480c85b387SStefano Zampini 164921ef3d20SStefano Zampini ierr = DMCreateFieldDecomposition(dm,&nf,NULL,&fields,NULL);CHKERRQ(ierr); 165021ef3d20SStefano Zampini ierr = PetscMalloc1(nf,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 165121ef3d20SStefano Zampini for (i=0;i<nf;i++) { 16520c85b387SStefano Zampini PetscInt bs; 16530c85b387SStefano Zampini 165421ef3d20SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,fields[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16550c85b387SStefano Zampini ierr = ISGetBlockSize(fields[i],&bs);CHKERRQ(ierr); 16560c85b387SStefano Zampini ierr = ISSetBlockSize(pcbddc->ISForDofsLocal[i],bs);CHKERRQ(ierr); 165721ef3d20SStefano Zampini ierr = ISDestroy(&fields[i]);CHKERRQ(ierr); 165821ef3d20SStefano Zampini } 165921ef3d20SStefano Zampini ierr = PetscFree(fields);CHKERRQ(ierr); 166021ef3d20SStefano Zampini pcbddc->n_ISForDofsLocal = nf; 166121ef3d20SStefano Zampini } else { /* See if MATIS has fields attached by the conversion from MatNest */ 166221ef3d20SStefano Zampini PetscContainer c; 166321ef3d20SStefano Zampini 166421ef3d20SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc->pmat,"_convert_nest_lfields",(PetscObject*)&c);CHKERRQ(ierr); 166521ef3d20SStefano Zampini if (c) { 166621ef3d20SStefano Zampini MatISLocalFields lf; 166721ef3d20SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&lf);CHKERRQ(ierr); 166821ef3d20SStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,lf->nr,lf->rf);CHKERRQ(ierr); 166921ef3d20SStefano Zampini } else { /* fallback, create the default fields if bs > 1 */ 16701f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1671986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 167221ef3d20SStefano Zampini if (i > 1) { 1673986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 16741f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16751f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16761f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16771f4df5f7SStefano Zampini } 16781f4df5f7SStefano Zampini } 167921ef3d20SStefano Zampini } 168021ef3d20SStefano Zampini } 16817a0e7b2cSstefano_zampini } else { 16827a0e7b2cSstefano_zampini PetscInt i; 16837a0e7b2cSstefano_zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16847a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16857a0e7b2cSstefano_zampini } 16861f4df5f7SStefano Zampini } 1687986cdee1SStefano Zampini } 16881f4df5f7SStefano Zampini 16895c5e10d6SStefano Zampini boundary: 16901f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 16911f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16927a0e7b2cSstefano_zampini } else if (pcbddc->DirichletBoundariesLocal) { 16937a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16941f4df5f7SStefano Zampini } 16951f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 16961f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16977a0e7b2cSstefano_zampini } else if (pcbddc->NeumannBoundariesLocal) { 16987a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16991f4df5f7SStefano Zampini } 17001f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 17011f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 17021f4df5f7SStefano Zampini } 17031f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 17041f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 17057620a527SStefano Zampini /* detect local disconnected subdomains if requested (use matis->A) */ 17067620a527SStefano Zampini if (pcbddc->detect_disconnected) { 17077620a527SStefano Zampini IS primalv = NULL; 17087620a527SStefano Zampini PetscInt i; 17098361f951SStefano Zampini PetscBool filter = pcbddc->detect_disconnected_filter; 17107a0e7b2cSstefano_zampini 17117620a527SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 17127620a527SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 17137620a527SStefano Zampini } 17147620a527SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 17158361f951SStefano Zampini ierr = PCBDDCDetectDisconnectedComponents(pc,filter,&pcbddc->n_local_subs,&pcbddc->local_subs,&primalv);CHKERRQ(ierr); 17167620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 17177620a527SStefano Zampini ierr = ISDestroy(&primalv);CHKERRQ(ierr); 17187620a527SStefano Zampini } 17197620a527SStefano Zampini /* early stage corner detection */ 17207620a527SStefano Zampini { 17217620a527SStefano Zampini DM dm; 17227620a527SStefano Zampini 17237620a527SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 17244f819b78SStefano Zampini if (!dm) { 17254f819b78SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 17264f819b78SStefano Zampini } 17277620a527SStefano Zampini if (dm) { 17287620a527SStefano Zampini PetscBool isda; 17297620a527SStefano Zampini 17307620a527SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&isda);CHKERRQ(ierr); 17317620a527SStefano Zampini if (isda) { 17327620a527SStefano Zampini ISLocalToGlobalMapping l2l; 17337620a527SStefano Zampini IS corners; 17347620a527SStefano Zampini Mat lA; 17354f819b78SStefano Zampini PetscBool gl,lo; 17367620a527SStefano Zampini 17374f819b78SStefano Zampini { 17384f819b78SStefano Zampini Vec cvec; 17394f819b78SStefano Zampini const PetscScalar *coords; 17404f819b78SStefano Zampini PetscInt dof,n,cdim; 17414f819b78SStefano Zampini PetscBool memc = PETSC_TRUE; 17424f819b78SStefano Zampini 17434f819b78SStefano Zampini ierr = DMDAGetInfo(dm,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dof,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 17444f819b78SStefano Zampini ierr = DMGetCoordinates(dm,&cvec);CHKERRQ(ierr); 17454f819b78SStefano Zampini ierr = VecGetLocalSize(cvec,&n);CHKERRQ(ierr); 17464f819b78SStefano Zampini ierr = VecGetBlockSize(cvec,&cdim);CHKERRQ(ierr); 17474f819b78SStefano Zampini n /= cdim; 17484f819b78SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->coords);CHKERRQ(ierr); 17494f819b78SStefano Zampini ierr = PetscMalloc1(dof*n*cdim,&pcbddc->mat_graph->coords);CHKERRQ(ierr); 17504f819b78SStefano Zampini ierr = VecGetArrayRead(cvec,&coords);CHKERRQ(ierr); 17514f819b78SStefano Zampini #if defined(PETSC_USE_COMPLEX) 17524f819b78SStefano Zampini memc = PETSC_FALSE; 17534f819b78SStefano Zampini #endif 17544f819b78SStefano Zampini if (dof != 1) memc = PETSC_FALSE; 17554f819b78SStefano Zampini if (memc) { 1756580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->mat_graph->coords,coords,cdim*n*dof);CHKERRQ(ierr); 17574f819b78SStefano Zampini } else { /* BDDC graph does not use any blocked information, we need to replicate the data */ 17584f819b78SStefano Zampini PetscReal *bcoords = pcbddc->mat_graph->coords; 17594f819b78SStefano Zampini PetscInt i, b, d; 17604f819b78SStefano Zampini 17614f819b78SStefano Zampini for (i=0;i<n;i++) { 17624f819b78SStefano Zampini for (b=0;b<dof;b++) { 17634f819b78SStefano Zampini for (d=0;d<cdim;d++) { 17644f819b78SStefano Zampini bcoords[i*dof*cdim + b*cdim + d] = PetscRealPart(coords[i*cdim+d]); 17654f819b78SStefano Zampini } 17664f819b78SStefano Zampini } 17674f819b78SStefano Zampini } 17684f819b78SStefano Zampini } 17694f819b78SStefano Zampini ierr = VecRestoreArrayRead(cvec,&coords);CHKERRQ(ierr); 17704f819b78SStefano Zampini pcbddc->mat_graph->cdim = cdim; 17714f819b78SStefano Zampini pcbddc->mat_graph->cnloc = dof*n; 17724f819b78SStefano Zampini pcbddc->mat_graph->cloc = PETSC_FALSE; 17734f819b78SStefano Zampini } 1774d4a6ed37SStefano Zampini ierr = DMDAGetSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17757620a527SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17767620a527SStefano Zampini ierr = MatGetLocalToGlobalMapping(lA,&l2l,NULL);CHKERRQ(ierr); 17777620a527SStefano Zampini ierr = MatISRestoreLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17784f819b78SStefano Zampini lo = (PetscBool)(l2l && corners); 17794f819b78SStefano Zampini ierr = MPIU_Allreduce(&lo,&gl,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 17804f819b78SStefano Zampini if (gl) { /* From PETSc's DMDA */ 17817620a527SStefano Zampini const PetscInt *idx; 178272ed36d8SStefano Zampini PetscInt dof,bs,*idxout,n; 17837620a527SStefano Zampini 178472ed36d8SStefano Zampini ierr = DMDAGetInfo(dm,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dof,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 17857620a527SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(l2l,&bs);CHKERRQ(ierr); 17867620a527SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 17877620a527SStefano Zampini ierr = ISGetIndices(corners,&idx);CHKERRQ(ierr); 178872ed36d8SStefano Zampini if (bs == dof) { 17897620a527SStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 17907620a527SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(l2l,n,idx,idxout);CHKERRQ(ierr); 179172ed36d8SStefano Zampini } else { /* the original DMDA local-to-local map have been modified */ 179272ed36d8SStefano Zampini PetscInt i,d; 179372ed36d8SStefano Zampini 179472ed36d8SStefano Zampini ierr = PetscMalloc1(dof*n,&idxout);CHKERRQ(ierr); 179572ed36d8SStefano Zampini for (i=0;i<n;i++) for (d=0;d<dof;d++) idxout[dof*i+d] = dof*idx[i]+d; 179672ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingApply(l2l,dof*n,idxout,idxout);CHKERRQ(ierr); 179772ed36d8SStefano Zampini 179872ed36d8SStefano Zampini bs = 1; 179972ed36d8SStefano Zampini n *= dof; 180072ed36d8SStefano Zampini } 18017620a527SStefano Zampini ierr = ISRestoreIndices(corners,&idx);CHKERRQ(ierr); 1802d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 18037620a527SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)pc),bs,n,idxout,PETSC_OWN_POINTER,&corners);CHKERRQ(ierr); 18047620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,corners);CHKERRQ(ierr); 18057620a527SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 18061c7a958bSStefano Zampini pcbddc->corner_selected = PETSC_TRUE; 18074f819b78SStefano Zampini pcbddc->corner_selection = PETSC_TRUE; 18084f819b78SStefano Zampini } 18094f819b78SStefano Zampini if (corners) { 1810d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 18117620a527SStefano Zampini } 18127620a527SStefano Zampini } 18137620a527SStefano Zampini } 18147620a527SStefano Zampini } 18151c7a958bSStefano Zampini if (pcbddc->corner_selection && !pcbddc->mat_graph->cdim) { 18161c7a958bSStefano Zampini DM dm; 18171c7a958bSStefano Zampini 18181c7a958bSStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 18194f819b78SStefano Zampini if (!dm) { 18204f819b78SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 18211c7a958bSStefano Zampini } 18224f819b78SStefano Zampini if (dm) { /* this can get very expensive, I need to find a faster alternative */ 18231c7a958bSStefano Zampini Vec vcoords; 18241c7a958bSStefano Zampini PetscSection section; 18251c7a958bSStefano Zampini PetscReal *coords; 18261c7a958bSStefano Zampini PetscInt d,cdim,nl,nf,**ctxs; 18271c7a958bSStefano Zampini PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal *, PetscInt, PetscScalar *, void *); 18281c7a958bSStefano Zampini 18291c7a958bSStefano Zampini ierr = DMGetCoordinateDim(dm,&cdim);CHKERRQ(ierr); 183092fd8e1eSJed Brown ierr = DMGetLocalSection(dm,§ion);CHKERRQ(ierr); 18311c7a958bSStefano Zampini ierr = PetscSectionGetNumFields(section,&nf);CHKERRQ(ierr); 18321c7a958bSStefano Zampini ierr = DMCreateGlobalVector(dm,&vcoords);CHKERRQ(ierr); 18331c7a958bSStefano Zampini ierr = VecGetLocalSize(vcoords,&nl);CHKERRQ(ierr); 18341c7a958bSStefano Zampini ierr = PetscMalloc1(nl*cdim,&coords);CHKERRQ(ierr); 18351c7a958bSStefano Zampini ierr = PetscMalloc2(nf,&funcs,nf,&ctxs);CHKERRQ(ierr); 18361c7a958bSStefano Zampini ierr = PetscMalloc1(nf,&ctxs[0]);CHKERRQ(ierr); 18371c7a958bSStefano Zampini for (d=0;d<nf;d++) funcs[d] = func_coords_private; 18381c7a958bSStefano Zampini for (d=1;d<nf;d++) ctxs[d] = ctxs[d-1] + 1; 18391c7a958bSStefano Zampini for (d=0;d<cdim;d++) { 18401c7a958bSStefano Zampini PetscInt i; 18411c7a958bSStefano Zampini const PetscScalar *v; 18421c7a958bSStefano Zampini 18431c7a958bSStefano Zampini for (i=0;i<nf;i++) ctxs[i][0] = d; 18441c7a958bSStefano Zampini ierr = DMProjectFunction(dm,0.0,funcs,(void**)ctxs,INSERT_VALUES,vcoords);CHKERRQ(ierr); 18451c7a958bSStefano Zampini ierr = VecGetArrayRead(vcoords,&v);CHKERRQ(ierr); 18461c7a958bSStefano Zampini for (i=0;i<nl;i++) coords[i*cdim+d] = PetscRealPart(v[i]); 18471c7a958bSStefano Zampini ierr = VecRestoreArrayRead(vcoords,&v);CHKERRQ(ierr); 18481c7a958bSStefano Zampini } 18491c7a958bSStefano Zampini ierr = VecDestroy(&vcoords);CHKERRQ(ierr); 18501c7a958bSStefano Zampini ierr = PCSetCoordinates(pc,cdim,nl,coords);CHKERRQ(ierr); 18511c7a958bSStefano Zampini ierr = PetscFree(coords);CHKERRQ(ierr); 18521c7a958bSStefano Zampini ierr = PetscFree(ctxs[0]);CHKERRQ(ierr); 18531c7a958bSStefano Zampini ierr = PetscFree2(funcs,ctxs);CHKERRQ(ierr); 18541c7a958bSStefano Zampini } 18551c7a958bSStefano Zampini } 18567a0e7b2cSstefano_zampini PetscFunctionReturn(0); 18577a0e7b2cSstefano_zampini } 18587a0e7b2cSstefano_zampini 18597a0e7b2cSstefano_zampini PetscErrorCode PCBDDCConsistencyCheckIS(PC pc, MPI_Op mop, IS *is) 18607a0e7b2cSstefano_zampini { 18617a0e7b2cSstefano_zampini Mat_IS *matis = (Mat_IS*)(pc->pmat->data); 18627a0e7b2cSstefano_zampini PetscErrorCode ierr; 18637a0e7b2cSstefano_zampini IS nis; 18647a0e7b2cSstefano_zampini const PetscInt *idxs; 18657a0e7b2cSstefano_zampini PetscInt i,nd,n = matis->A->rmap->n,*nidxs,nnd; 18667a0e7b2cSstefano_zampini PetscBool *ld; 18677a0e7b2cSstefano_zampini 18687a0e7b2cSstefano_zampini PetscFunctionBegin; 18697a0e7b2cSstefano_zampini if (mop != MPI_LAND && mop != MPI_LOR) SETERRQ(PetscObjectComm((PetscObject)(pc)),PETSC_ERR_SUP,"Supported are MPI_LAND and MPI_LOR"); 18707a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18717a0e7b2cSstefano_zampini /* init rootdata with true */ 18727a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_rootdata; 18737a0e7b2cSstefano_zampini for (i=0;i<pc->pmat->rmap->n;i++) ld[i] = PETSC_TRUE; 18747a0e7b2cSstefano_zampini } else { 1875580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_rootdata,pc->pmat->rmap->n);CHKERRQ(ierr); 18767a0e7b2cSstefano_zampini } 1877580bdb30SBarry Smith ierr = PetscArrayzero(matis->sf_leafdata,n);CHKERRQ(ierr); 18787a0e7b2cSstefano_zampini ierr = ISGetLocalSize(*is,&nd);CHKERRQ(ierr); 18797a0e7b2cSstefano_zampini ierr = ISGetIndices(*is,&idxs);CHKERRQ(ierr); 18807a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_leafdata; 18817a0e7b2cSstefano_zampini for (i=0;i<nd;i++) 18827a0e7b2cSstefano_zampini if (-1 < idxs[i] && idxs[i] < n) 18837a0e7b2cSstefano_zampini ld[idxs[i]] = PETSC_TRUE; 18847a0e7b2cSstefano_zampini ierr = ISRestoreIndices(*is,&idxs);CHKERRQ(ierr); 18857a0e7b2cSstefano_zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18867a0e7b2cSstefano_zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18877a0e7b2cSstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18887a0e7b2cSstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18897a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18907a0e7b2cSstefano_zampini ierr = PetscMalloc1(nd,&nidxs);CHKERRQ(ierr); 18917a0e7b2cSstefano_zampini } else { 18927a0e7b2cSstefano_zampini ierr = PetscMalloc1(n,&nidxs);CHKERRQ(ierr); 18937a0e7b2cSstefano_zampini } 18947a0e7b2cSstefano_zampini for (i=0,nnd=0;i<n;i++) 18957a0e7b2cSstefano_zampini if (ld[i]) 18967a0e7b2cSstefano_zampini nidxs[nnd++] = i; 18977a0e7b2cSstefano_zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(*is)),nnd,nidxs,PETSC_OWN_POINTER,&nis);CHKERRQ(ierr); 18987a0e7b2cSstefano_zampini ierr = ISDestroy(is);CHKERRQ(ierr); 18997a0e7b2cSstefano_zampini *is = nis; 19001f4df5f7SStefano Zampini PetscFunctionReturn(0); 19011f4df5f7SStefano Zampini } 19021f4df5f7SStefano Zampini 19033e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 19043e589ea0SStefano Zampini { 19053e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 19063e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 19073e589ea0SStefano Zampini PetscErrorCode ierr; 19083e589ea0SStefano Zampini 19093e589ea0SStefano Zampini PetscFunctionBegin; 19103e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 19113e589ea0SStefano Zampini PetscFunctionReturn(0); 19123e589ea0SStefano Zampini } 19133e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 19143e589ea0SStefano Zampini Vec swap; 19153e589ea0SStefano Zampini 19163e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 19173e589ea0SStefano Zampini swap = pcbddc->work_change; 19183e589ea0SStefano Zampini pcbddc->work_change = r; 19193e589ea0SStefano Zampini r = swap; 19203e589ea0SStefano Zampini } 19213e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19223e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1923*55c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 19243e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 1925*55c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][0],pc,0,0,0);CHKERRQ(ierr); 1926c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 19273e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 19283e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19293e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 19303e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1931f913dca9SStefano Zampini pcbddc->work_change = r; 19323e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 19333e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 19343e589ea0SStefano Zampini } 19353e589ea0SStefano Zampini PetscFunctionReturn(0); 19363e589ea0SStefano Zampini } 19373e589ea0SStefano Zampini 1938a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1939a3df083aSStefano Zampini { 1940a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1941a3df083aSStefano Zampini PetscErrorCode ierr; 1942a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1943a3df083aSStefano Zampini 1944a3df083aSStefano Zampini PetscFunctionBegin; 1945a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1946a3df083aSStefano Zampini if (transpose) { 1947a3df083aSStefano Zampini apply_right = ctx->apply_left; 1948a3df083aSStefano Zampini apply_left = ctx->apply_right; 1949a3df083aSStefano Zampini } else { 1950a3df083aSStefano Zampini apply_right = ctx->apply_right; 1951a3df083aSStefano Zampini apply_left = ctx->apply_left; 1952a3df083aSStefano Zampini } 1953a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1954a3df083aSStefano Zampini if (apply_right) { 1955a3df083aSStefano Zampini const PetscScalar *ax; 1956a3df083aSStefano Zampini PetscInt nl,i; 1957a3df083aSStefano Zampini 1958a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1959a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1960580bdb30SBarry Smith ierr = PetscArraycpy(ctx->work,ax,nl);CHKERRQ(ierr); 1961a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1962a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1963a3df083aSStefano Zampini PetscScalar sum,val; 1964a3df083aSStefano Zampini const PetscInt *idxs; 1965a3df083aSStefano Zampini PetscInt nz,j; 1966a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1967a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1968a3df083aSStefano Zampini sum = 0.; 1969a3df083aSStefano Zampini if (ctx->apply_p0) { 1970a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1971a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1972a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1973a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1974a3df083aSStefano Zampini } 1975a3df083aSStefano Zampini } else { 1976a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1977a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1978a3df083aSStefano Zampini } 1979a3df083aSStefano Zampini } 1980a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1981a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1982a3df083aSStefano Zampini } 1983a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1984a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1985a3df083aSStefano Zampini } 1986a3df083aSStefano Zampini if (transpose) { 1987a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1988a3df083aSStefano Zampini } else { 1989a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1990a3df083aSStefano Zampini } 1991a3df083aSStefano Zampini if (reset_x) { 1992a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1993a3df083aSStefano Zampini } 1994a3df083aSStefano Zampini if (apply_left) { 1995a3df083aSStefano Zampini PetscScalar *ay; 1996a3df083aSStefano Zampini PetscInt i; 1997a3df083aSStefano Zampini 1998a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1999a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 2000a3df083aSStefano Zampini PetscScalar sum,val; 2001a3df083aSStefano Zampini const PetscInt *idxs; 2002a3df083aSStefano Zampini PetscInt nz,j; 2003a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2004a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 2005a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 2006a3df083aSStefano Zampini if (ctx->apply_p0) { 2007a3df083aSStefano Zampini sum = 0.; 2008a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 2009a3df083aSStefano Zampini sum += ay[idxs[j]]; 2010a3df083aSStefano Zampini ay[idxs[j]] += val; 2011a3df083aSStefano Zampini } 2012a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 2013a3df083aSStefano Zampini } else { 2014a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 2015a3df083aSStefano Zampini ay[idxs[j]] += val; 2016a3df083aSStefano Zampini } 2017a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 2018a3df083aSStefano Zampini } 2019a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 2020a3df083aSStefano Zampini } 2021a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 2022a3df083aSStefano Zampini } 2023a3df083aSStefano Zampini PetscFunctionReturn(0); 2024a3df083aSStefano Zampini } 2025a3df083aSStefano Zampini 2026a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_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_TRUE);CHKERRQ(ierr); 2032a3df083aSStefano Zampini PetscFunctionReturn(0); 2033a3df083aSStefano Zampini } 2034a3df083aSStefano Zampini 2035a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 2036a3df083aSStefano Zampini { 2037a3df083aSStefano Zampini PetscErrorCode ierr; 2038a3df083aSStefano Zampini 2039a3df083aSStefano Zampini PetscFunctionBegin; 2040a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 2041a3df083aSStefano Zampini PetscFunctionReturn(0); 2042a3df083aSStefano Zampini } 2043a3df083aSStefano Zampini 2044a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 2045a3df083aSStefano Zampini { 2046a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2047a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2048a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 2049a3df083aSStefano Zampini PetscErrorCode ierr; 2050a3df083aSStefano Zampini 2051a3df083aSStefano Zampini PetscFunctionBegin; 2052a3df083aSStefano Zampini if (!restore) { 20531dd7afcfSStefano Zampini Mat A_IB,A_BI; 2054a3df083aSStefano Zampini PetscScalar *work; 2055b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 2056a3df083aSStefano Zampini 20579a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 20589a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 2059a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 2060a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 2061a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2062a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 2063a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 2064a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 2065a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 2066a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 2067a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 2068a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 2069a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 2070a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 2071059032f7SStefano Zampini if (reuse) { 2072a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 20731dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 2074059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 2075059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 2076059032f7SStefano Zampini PetscInt i; 2077059032f7SStefano Zampini 2078059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 2079059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2080059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2081059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2082059032f7SStefano Zampini } 2083059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 20841dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 2085059032f7SStefano Zampini } 2086a3df083aSStefano Zampini ctx->A = pcis->A_IB; 2087a3df083aSStefano Zampini ctx->work = work; 2088a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 2089a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2090a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2091a3df083aSStefano Zampini pcis->A_IB = A_IB; 2092a3df083aSStefano Zampini 2093a3df083aSStefano Zampini /* A_BI as A_IB^T */ 2094a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 2095a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 2096a3df083aSStefano Zampini pcis->A_BI = A_BI; 2097a3df083aSStefano Zampini } else { 20981dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 20991dd7afcfSStefano Zampini PetscFunctionReturn(0); 21001dd7afcfSStefano Zampini } 2101a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 2102a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 2103a3df083aSStefano Zampini pcis->A_IB = ctx->A; 21041dd7afcfSStefano Zampini ctx->A = NULL; 21051dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 21061dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 21071dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 21081dd7afcfSStefano Zampini if (ctx->free) { 2109059032f7SStefano Zampini PetscInt i; 21101dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 2111059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2112059032f7SStefano Zampini } 2113059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2114059032f7SStefano Zampini } 2115a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 2116a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 2117a3df083aSStefano Zampini } 2118a3df083aSStefano Zampini PetscFunctionReturn(0); 2119a3df083aSStefano Zampini } 2120a3df083aSStefano Zampini 2121a3df083aSStefano Zampini /* used just in bddc debug mode */ 2122a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 2123a3df083aSStefano Zampini { 2124a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2125a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2126a3df083aSStefano Zampini Mat An; 2127a3df083aSStefano Zampini PetscErrorCode ierr; 2128a3df083aSStefano Zampini 2129a3df083aSStefano Zampini PetscFunctionBegin; 2130a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 2131a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 2132a3df083aSStefano Zampini if (is1) { 21337dae84e0SHong Zhang ierr = MatCreateSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 2134a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 2135a3df083aSStefano Zampini } else { 2136a3df083aSStefano Zampini *B = An; 2137a3df083aSStefano Zampini } 2138a3df083aSStefano Zampini PetscFunctionReturn(0); 2139a3df083aSStefano Zampini } 2140a3df083aSStefano Zampini 21411cf9b237SStefano Zampini /* TODO: add reuse flag */ 21421cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 21431cf9b237SStefano Zampini { 21441cf9b237SStefano Zampini Mat Bt; 21451cf9b237SStefano Zampini PetscScalar *a,*bdata; 21461cf9b237SStefano Zampini const PetscInt *ii,*ij; 21471cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 21481cf9b237SStefano Zampini PetscBool flg_row; 21491cf9b237SStefano Zampini PetscErrorCode ierr; 21501cf9b237SStefano Zampini 21511cf9b237SStefano Zampini PetscFunctionBegin; 21521cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 21531cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 21541cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 21551cf9b237SStefano Zampini nnz = n; 21561cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 21571cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 21581cf9b237SStefano Zampini } 21591cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 21601cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 21611cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 21621cf9b237SStefano Zampini nnz = 0; 21631cf9b237SStefano Zampini bii[0] = 0; 21641cf9b237SStefano Zampini for (i=0;i<n;i++) { 21651cf9b237SStefano Zampini PetscInt j; 21661cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 21671cf9b237SStefano Zampini PetscScalar entry = a[j]; 21683272d46bSStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || (n == m && ij[j] == i)) { 21691cf9b237SStefano Zampini bij[nnz] = ij[j]; 21701cf9b237SStefano Zampini bdata[nnz] = entry; 21711cf9b237SStefano Zampini nnz++; 21721cf9b237SStefano Zampini } 21731cf9b237SStefano Zampini } 21741cf9b237SStefano Zampini bii[i+1] = nnz; 21751cf9b237SStefano Zampini } 21761cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 21771cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 21781cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 21791cf9b237SStefano Zampini { 21801cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 21811cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 21821cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 21831cf9b237SStefano Zampini } 21843272d46bSStefano Zampini if (*B == A) { 21853272d46bSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 21863272d46bSStefano Zampini } 21871cf9b237SStefano Zampini *B = Bt; 21881cf9b237SStefano Zampini PetscFunctionReturn(0); 21891cf9b237SStefano Zampini } 21901cf9b237SStefano Zampini 21918361f951SStefano Zampini PetscErrorCode PCBDDCDetectDisconnectedComponents(PC pc, PetscBool filter, PetscInt *ncc, IS* cc[], IS* primalv) 21924f1b2e48SStefano Zampini { 2193c80a6c00SStefano Zampini Mat B = NULL; 2194c80a6c00SStefano Zampini DM dm; 21954f1b2e48SStefano Zampini IS is_dummy,*cc_n; 21964f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 21974f1b2e48SStefano Zampini PCBDDCGraph graph; 2198c80a6c00SStefano Zampini PetscInt *xadj_filtered = NULL,*adjncy_filtered = NULL; 21994f1b2e48SStefano Zampini PetscInt i,n; 22004f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 2201c80a6c00SStefano Zampini PetscBool isplex = PETSC_FALSE; 22024f1b2e48SStefano Zampini PetscErrorCode ierr; 22034f1b2e48SStefano Zampini 22044f1b2e48SStefano Zampini PetscFunctionBegin; 2205a2eca866SStefano Zampini if (ncc) *ncc = 0; 2206a2eca866SStefano Zampini if (cc) *cc = NULL; 2207a2eca866SStefano Zampini if (primalv) *primalv = NULL; 2208c80a6c00SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 2209c80a6c00SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 22104f819b78SStefano Zampini if (!dm) { 22114f819b78SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 2212c80a6c00SStefano Zampini } 2213c80a6c00SStefano Zampini if (dm) { 2214c80a6c00SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&isplex);CHKERRQ(ierr); 2215c80a6c00SStefano Zampini } 22168361f951SStefano Zampini if (filter) isplex = PETSC_FALSE; 22178361f951SStefano Zampini 2218c80a6c00SStefano Zampini if (isplex) { /* this code has been modified from plexpartition.c */ 2219c80a6c00SStefano Zampini PetscInt p, pStart, pEnd, a, adjSize, idx, size, nroots; 2220c80a6c00SStefano Zampini PetscInt *adj = NULL; 2221c80a6c00SStefano Zampini IS cellNumbering; 2222c80a6c00SStefano Zampini const PetscInt *cellNum; 2223c80a6c00SStefano Zampini PetscBool useCone, useClosure; 2224c80a6c00SStefano Zampini PetscSection section; 2225c80a6c00SStefano Zampini PetscSegBuffer adjBuffer; 2226c80a6c00SStefano Zampini PetscSF sfPoint; 2227c80a6c00SStefano Zampini PetscErrorCode ierr; 2228c80a6c00SStefano Zampini 2229c80a6c00SStefano Zampini PetscFunctionBegin; 2230c80a6c00SStefano Zampini ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 2231c80a6c00SStefano Zampini ierr = DMGetPointSF(dm, &sfPoint);CHKERRQ(ierr); 2232c80a6c00SStefano Zampini ierr = PetscSFGetGraph(sfPoint, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 2233c80a6c00SStefano Zampini /* Build adjacency graph via a section/segbuffer */ 2234c80a6c00SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), §ion);CHKERRQ(ierr); 2235c80a6c00SStefano Zampini ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 2236c80a6c00SStefano Zampini ierr = PetscSegBufferCreate(sizeof(PetscInt),1000,&adjBuffer);CHKERRQ(ierr); 2237c80a6c00SStefano Zampini /* Always use FVM adjacency to create partitioner graph */ 2238b0441da4SMatthew G. Knepley ierr = DMGetBasicAdjacency(dm, &useCone, &useClosure);CHKERRQ(ierr); 2239b0441da4SMatthew G. Knepley ierr = DMSetBasicAdjacency(dm, PETSC_TRUE, PETSC_FALSE);CHKERRQ(ierr); 2240956e2312SStefano Zampini ierr = DMPlexGetCellNumbering(dm, &cellNumbering);CHKERRQ(ierr); 2241c80a6c00SStefano Zampini ierr = ISGetIndices(cellNumbering, &cellNum);CHKERRQ(ierr); 2242c80a6c00SStefano Zampini for (n = 0, p = pStart; p < pEnd; p++) { 2243c80a6c00SStefano Zampini /* Skip non-owned cells in parallel (ParMetis expects no overlap) */ 2244c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2245c80a6c00SStefano Zampini adjSize = PETSC_DETERMINE; 2246c80a6c00SStefano Zampini ierr = DMPlexGetAdjacency(dm, p, &adjSize, &adj);CHKERRQ(ierr); 2247c80a6c00SStefano Zampini for (a = 0; a < adjSize; ++a) { 2248c80a6c00SStefano Zampini const PetscInt point = adj[a]; 22495cef3d0dSStefano Zampini if (pStart <= point && point < pEnd) { 2250c80a6c00SStefano Zampini PetscInt *PETSC_RESTRICT pBuf; 2251c80a6c00SStefano Zampini ierr = PetscSectionAddDof(section, p, 1);CHKERRQ(ierr); 2252c80a6c00SStefano Zampini ierr = PetscSegBufferGetInts(adjBuffer, 1, &pBuf);CHKERRQ(ierr); 2253c80a6c00SStefano Zampini *pBuf = point; 2254c80a6c00SStefano Zampini } 2255c80a6c00SStefano Zampini } 2256c80a6c00SStefano Zampini n++; 2257c80a6c00SStefano Zampini } 2258b0441da4SMatthew G. Knepley ierr = DMSetBasicAdjacency(dm, useCone, useClosure);CHKERRQ(ierr); 2259c80a6c00SStefano Zampini /* Derive CSR graph from section/segbuffer */ 2260c80a6c00SStefano Zampini ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 2261c80a6c00SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 2262c80a6c00SStefano Zampini ierr = PetscMalloc1(n+1, &xadj);CHKERRQ(ierr); 2263c80a6c00SStefano Zampini for (idx = 0, p = pStart; p < pEnd; p++) { 2264c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2265c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(section, p, &(xadj[idx++]));CHKERRQ(ierr); 2266c80a6c00SStefano Zampini } 2267c80a6c00SStefano Zampini xadj[n] = size; 2268c80a6c00SStefano Zampini ierr = PetscSegBufferExtractAlloc(adjBuffer, &adjncy);CHKERRQ(ierr); 2269c80a6c00SStefano Zampini /* Clean up */ 2270c80a6c00SStefano Zampini ierr = PetscSegBufferDestroy(&adjBuffer);CHKERRQ(ierr); 2271c80a6c00SStefano Zampini ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 2272c80a6c00SStefano Zampini ierr = PetscFree(adj);CHKERRQ(ierr); 2273c80a6c00SStefano Zampini graph->xadj = xadj; 2274c80a6c00SStefano Zampini graph->adjncy = adjncy; 2275c80a6c00SStefano Zampini } else { 2276c80a6c00SStefano Zampini Mat A; 22778361f951SStefano Zampini PetscBool isseqaij, flg_row; 2278c80a6c00SStefano Zampini 2279c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 228063c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 2281a2eca866SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 228263c961adSStefano Zampini PetscFunctionReturn(0); 228363c961adSStefano Zampini } 22847ebab0bbSStefano Zampini ierr = PetscObjectBaseTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 22854f1b2e48SStefano Zampini if (!isseqaij && filter) { 22861cf9b237SStefano Zampini PetscBool isseqdense; 22871cf9b237SStefano Zampini 22881cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 22891cf9b237SStefano Zampini if (!isseqdense) { 22904f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 22911cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 22921cf9b237SStefano Zampini PetscScalar *array; 22931cf9b237SStefano Zampini PetscReal chop=1.e-6; 22941cf9b237SStefano Zampini 22951cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 22961cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 22971cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 22981cf9b237SStefano Zampini for (i=0;i<n;i++) { 22991cf9b237SStefano Zampini PetscInt j; 23001cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 23011cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 23021cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 23031cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 23041cf9b237SStefano Zampini } 23051cf9b237SStefano Zampini } 23061cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 23079d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 23081cf9b237SStefano Zampini } 23094f1b2e48SStefano Zampini } else { 2310c80a6c00SStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 23114f1b2e48SStefano Zampini B = A; 23124f1b2e48SStefano Zampini } 23134f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 23144f1b2e48SStefano Zampini 23154f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 23164f1b2e48SStefano Zampini if (filter) { 23174f1b2e48SStefano Zampini PetscScalar *data; 23184f1b2e48SStefano Zampini PetscInt j,cum; 23194f1b2e48SStefano Zampini 23204f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 23214f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 23224f1b2e48SStefano Zampini cum = 0; 23234f1b2e48SStefano Zampini for (i=0;i<n;i++) { 23244f1b2e48SStefano Zampini PetscInt t; 23254f1b2e48SStefano Zampini 23264f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 23274f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 23284f1b2e48SStefano Zampini continue; 23294f1b2e48SStefano Zampini } 23304f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 23314f1b2e48SStefano Zampini } 23324f1b2e48SStefano Zampini t = xadj_filtered[i]; 23334f1b2e48SStefano Zampini xadj_filtered[i] = cum; 23344f1b2e48SStefano Zampini cum += t; 23354f1b2e48SStefano Zampini } 23364f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 23374f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 23384f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 23394f1b2e48SStefano Zampini } else { 23404f1b2e48SStefano Zampini graph->xadj = xadj; 23414f1b2e48SStefano Zampini graph->adjncy = adjncy; 23424f1b2e48SStefano Zampini } 2343c80a6c00SStefano Zampini } 2344c80a6c00SStefano Zampini /* compute local connected components using PCBDDCGraph */ 2345c80a6c00SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 2346c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 2347c80a6c00SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2348c80a6c00SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 2349c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 23504f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 23514f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 2352c80a6c00SStefano Zampini 23534f1b2e48SStefano Zampini /* partial clean up */ 23544f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 2355c80a6c00SStefano Zampini if (B) { 2356c80a6c00SStefano Zampini PetscBool flg_row; 23574f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 23584f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 23594f1b2e48SStefano Zampini } 2360c80a6c00SStefano Zampini if (isplex) { 2361c80a6c00SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 2362c80a6c00SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 2363c80a6c00SStefano Zampini } 23644f1b2e48SStefano Zampini 23654f1b2e48SStefano Zampini /* get back data */ 2366c80a6c00SStefano Zampini if (isplex) { 2367c80a6c00SStefano Zampini if (ncc) *ncc = graph->ncc; 2368c80a6c00SStefano Zampini if (cc || primalv) { 2369c80a6c00SStefano Zampini Mat A; 2370c80a6c00SStefano Zampini PetscBT btv,btvt; 2371c80a6c00SStefano Zampini PetscSection subSection; 2372c80a6c00SStefano Zampini PetscInt *ids,cum,cump,*cids,*pids; 2373c80a6c00SStefano Zampini 2374c80a6c00SStefano Zampini ierr = DMPlexGetSubdomainSection(dm,&subSection);CHKERRQ(ierr); 2375c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 2376c80a6c00SStefano Zampini ierr = PetscMalloc3(A->rmap->n,&ids,graph->ncc+1,&cids,A->rmap->n,&pids);CHKERRQ(ierr); 2377c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btv);CHKERRQ(ierr); 2378c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btvt);CHKERRQ(ierr); 2379c80a6c00SStefano Zampini 2380c80a6c00SStefano Zampini cids[0] = 0; 2381c80a6c00SStefano Zampini for (i = 0, cump = 0, cum = 0; i < graph->ncc; i++) { 2382c80a6c00SStefano Zampini PetscInt j; 2383c80a6c00SStefano Zampini 2384c80a6c00SStefano Zampini ierr = PetscBTMemzero(A->rmap->n,btvt);CHKERRQ(ierr); 2385c80a6c00SStefano Zampini for (j = graph->cptr[i]; j < graph->cptr[i+1]; j++) { 2386c80a6c00SStefano Zampini PetscInt k, size, *closure = NULL, cell = graph->queue[j]; 2387c80a6c00SStefano Zampini 2388c80a6c00SStefano Zampini ierr = DMPlexGetTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2389c80a6c00SStefano Zampini for (k = 0; k < 2*size; k += 2) { 239020c3699dSStefano Zampini PetscInt s, pp, p = closure[k], off, dof, cdof; 2391c80a6c00SStefano Zampini 2392c80a6c00SStefano Zampini ierr = PetscSectionGetConstraintDof(subSection,p,&cdof);CHKERRQ(ierr); 2393c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(subSection,p,&off);CHKERRQ(ierr); 2394c80a6c00SStefano Zampini ierr = PetscSectionGetDof(subSection,p,&dof);CHKERRQ(ierr); 2395c80a6c00SStefano Zampini for (s = 0; s < dof-cdof; s++) { 2396c80a6c00SStefano Zampini if (PetscBTLookupSet(btvt,off+s)) continue; 2397c80a6c00SStefano Zampini if (!PetscBTLookup(btv,off+s)) { 2398c80a6c00SStefano Zampini ids[cum++] = off+s; 2399c80a6c00SStefano Zampini } else { /* cross-vertex */ 2400c80a6c00SStefano Zampini pids[cump++] = off+s; 2401c80a6c00SStefano Zampini } 2402c80a6c00SStefano Zampini } 240320c3699dSStefano Zampini ierr = DMPlexGetTreeParent(dm,p,&pp,NULL);CHKERRQ(ierr); 240420c3699dSStefano Zampini if (pp != p) { 240520c3699dSStefano Zampini ierr = PetscSectionGetConstraintDof(subSection,pp,&cdof);CHKERRQ(ierr); 240620c3699dSStefano Zampini ierr = PetscSectionGetOffset(subSection,pp,&off);CHKERRQ(ierr); 240720c3699dSStefano Zampini ierr = PetscSectionGetDof(subSection,pp,&dof);CHKERRQ(ierr); 240820c3699dSStefano Zampini for (s = 0; s < dof-cdof; s++) { 240920c3699dSStefano Zampini if (PetscBTLookupSet(btvt,off+s)) continue; 241020c3699dSStefano Zampini if (!PetscBTLookup(btv,off+s)) { 241120c3699dSStefano Zampini ids[cum++] = off+s; 241220c3699dSStefano Zampini } else { /* cross-vertex */ 241320c3699dSStefano Zampini pids[cump++] = off+s; 241420c3699dSStefano Zampini } 241520c3699dSStefano Zampini } 241620c3699dSStefano Zampini } 2417c80a6c00SStefano Zampini } 2418c80a6c00SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2419c80a6c00SStefano Zampini } 2420c80a6c00SStefano Zampini cids[i+1] = cum; 2421c80a6c00SStefano Zampini /* mark dofs as already assigned */ 2422c80a6c00SStefano Zampini for (j = cids[i]; j < cids[i+1]; j++) { 2423c80a6c00SStefano Zampini ierr = PetscBTSet(btv,ids[j]);CHKERRQ(ierr); 2424c80a6c00SStefano Zampini } 2425c80a6c00SStefano Zampini } 2426c80a6c00SStefano Zampini if (cc) { 2427c80a6c00SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 2428c80a6c00SStefano Zampini for (i = 0; i < graph->ncc; i++) { 2429c80a6c00SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cids[i+1]-cids[i],ids+cids[i],PETSC_COPY_VALUES,&cc_n[i]);CHKERRQ(ierr); 2430c80a6c00SStefano Zampini } 2431c80a6c00SStefano Zampini *cc = cc_n; 2432c80a6c00SStefano Zampini } 2433c80a6c00SStefano Zampini if (primalv) { 2434c80a6c00SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),cump,pids,PETSC_COPY_VALUES,primalv);CHKERRQ(ierr); 2435c80a6c00SStefano Zampini } 2436c80a6c00SStefano Zampini ierr = PetscFree3(ids,cids,pids);CHKERRQ(ierr); 2437c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 2438c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btvt);CHKERRQ(ierr); 2439c80a6c00SStefano Zampini } 2440c80a6c00SStefano Zampini } else { 24411cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 24421cf9b237SStefano Zampini if (cc) { 24434f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 24444f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 24454f1b2e48SStefano 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); 24464f1b2e48SStefano Zampini } 24474f1b2e48SStefano Zampini *cc = cc_n; 24481cf9b237SStefano Zampini } 2449c80a6c00SStefano Zampini } 24504f1b2e48SStefano Zampini /* clean up graph */ 24510a545947SLisandro Dalcin graph->xadj = NULL; 24520a545947SLisandro Dalcin graph->adjncy = NULL; 24534f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 24544f1b2e48SStefano Zampini PetscFunctionReturn(0); 24554f1b2e48SStefano Zampini } 24564f1b2e48SStefano Zampini 24575408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 24585408967cSStefano Zampini { 24595408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 24605408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2461dee84bffSStefano Zampini IS dirIS = NULL; 24624f1b2e48SStefano Zampini PetscInt i; 24635408967cSStefano Zampini PetscErrorCode ierr; 24645408967cSStefano Zampini 24655408967cSStefano Zampini PetscFunctionBegin; 2466dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 24675408967cSStefano Zampini if (zerodiag) { 24685408967cSStefano Zampini Mat A; 24695408967cSStefano Zampini Vec vec3_N; 24705408967cSStefano Zampini PetscScalar *vals; 24715408967cSStefano Zampini const PetscInt *idxs; 2472d12d3064SStefano Zampini PetscInt nz,*count; 24735408967cSStefano Zampini 24745408967cSStefano Zampini /* p0 */ 24755408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 24765408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 24775408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 24785408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 24794f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 24805408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24815408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 24825408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 24835408967cSStefano Zampini /* v_I */ 24845408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 24855408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 24865408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24875408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 24885408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24895408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 24905408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24915408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24925408967cSStefano Zampini if (dirIS) { 24935408967cSStefano Zampini PetscInt n; 24945408967cSStefano Zampini 24955408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 24965408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 24975408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 24985408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24995408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 25005408967cSStefano Zampini } 25015408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 25025408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 25035408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 25045408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2505669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 25065408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 25075408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 25089a962809SStefano 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])); 25095408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 25105408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2511d12d3064SStefano Zampini 2512d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2513d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2514d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2515d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2516d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2517d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 25186080607fSStefano 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]); 2519d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2520d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 25215408967cSStefano Zampini } 2522dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 25235408967cSStefano Zampini 25245408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 25255408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 25264f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 25275408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 25284f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 25295408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2530f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2531f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 25326080607fSStefano 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); 2533f2a566d8SStefano Zampini } 25345408967cSStefano Zampini PetscFunctionReturn(0); 25355408967cSStefano Zampini } 25365408967cSStefano Zampini 25373b03f7bbSStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, PetscBool reuse, IS *zerodiaglocal) 2538339f8db1SStefano Zampini { 2539339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 25403b03f7bbSStefano Zampini IS pressures = NULL,zerodiag = NULL,*bzerodiag = NULL,zerodiag_save,*zerodiag_subs; 25413b03f7bbSStefano Zampini PetscInt nz,n,benign_n,bsp = 1; 25424edc6404Sstefano_zampini PetscInt *interior_dofs,n_interior_dofs,nneu; 25434edc6404Sstefano_zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag,checkb; 2544339f8db1SStefano Zampini PetscErrorCode ierr; 2545339f8db1SStefano Zampini 2546339f8db1SStefano Zampini PetscFunctionBegin; 25473b03f7bbSStefano Zampini if (reuse) goto project_b0; 25489f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 25499f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2550a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2551a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2552a3df083aSStefano Zampini } 2553a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 25543b03f7bbSStefano Zampini has_null_pressures = PETSC_TRUE; 25553b03f7bbSStefano Zampini have_null = PETSC_TRUE; 25563b03f7bbSStefano Zampini /* if a local information on dofs is present, gets pressure dofs from command line (uses the last field is not provided) 25573b03f7bbSStefano Zampini Without local information, it uses only the zerodiagonal dofs (ok if the pressure block is all zero and it is a scalar field) 25584f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 25594f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 25601ae86dd6SStefano Zampini since the local Schur complements are already SPD 25614f1b2e48SStefano Zampini */ 256240fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 25637fbe2174Sstefano_zampini IS iP = NULL; 25643b03f7bbSStefano Zampini PetscInt p,*pp; 25653b03f7bbSStefano Zampini PetscBool flg; 25664f1b2e48SStefano Zampini 25673b03f7bbSStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pp);CHKERRQ(ierr); 25683b03f7bbSStefano Zampini n = pcbddc->n_ISForDofsLocal; 256928b8efb1Sstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC benign options","PC");CHKERRQ(ierr); 25703b03f7bbSStefano Zampini ierr = PetscOptionsIntArray("-pc_bddc_pressure_field","Field id for pressures",NULL,pp,&n,&flg);CHKERRQ(ierr); 257128b8efb1Sstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 25723b03f7bbSStefano Zampini if (!flg) { 25733b03f7bbSStefano Zampini n = 1; 25743b03f7bbSStefano Zampini pp[0] = pcbddc->n_ISForDofsLocal-1; 25753b03f7bbSStefano Zampini } 25763b03f7bbSStefano Zampini 25773b03f7bbSStefano Zampini bsp = 0; 25783b03f7bbSStefano Zampini for (p=0;p<n;p++) { 25793b03f7bbSStefano Zampini PetscInt bs; 25803b03f7bbSStefano Zampini 25813b03f7bbSStefano 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]); 25823b03f7bbSStefano Zampini ierr = ISGetBlockSize(pcbddc->ISForDofsLocal[pp[p]],&bs);CHKERRQ(ierr); 25833b03f7bbSStefano Zampini bsp += bs; 25843b03f7bbSStefano Zampini } 25853b03f7bbSStefano Zampini ierr = PetscMalloc1(bsp,&bzerodiag);CHKERRQ(ierr); 25863b03f7bbSStefano Zampini bsp = 0; 25873b03f7bbSStefano Zampini for (p=0;p<n;p++) { 25883b03f7bbSStefano Zampini const PetscInt *idxs; 25893b03f7bbSStefano Zampini PetscInt b,bs,npl,*bidxs; 25903b03f7bbSStefano Zampini 25913b03f7bbSStefano Zampini ierr = ISGetBlockSize(pcbddc->ISForDofsLocal[pp[p]],&bs);CHKERRQ(ierr); 25923b03f7bbSStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[pp[p]],&npl);CHKERRQ(ierr); 25933b03f7bbSStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[pp[p]],&idxs);CHKERRQ(ierr); 25943b03f7bbSStefano Zampini ierr = PetscMalloc1(npl/bs,&bidxs);CHKERRQ(ierr); 25953b03f7bbSStefano Zampini for (b=0;b<bs;b++) { 25963b03f7bbSStefano Zampini PetscInt i; 25973b03f7bbSStefano Zampini 25983b03f7bbSStefano Zampini for (i=0;i<npl/bs;i++) bidxs[i] = idxs[bs*i+b]; 25993b03f7bbSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl/bs,bidxs,PETSC_COPY_VALUES,&bzerodiag[bsp]);CHKERRQ(ierr); 26003b03f7bbSStefano Zampini bsp++; 26013b03f7bbSStefano Zampini } 26023b03f7bbSStefano Zampini ierr = PetscFree(bidxs);CHKERRQ(ierr); 26033b03f7bbSStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[pp[p]],&idxs);CHKERRQ(ierr); 26043b03f7bbSStefano Zampini } 26053b03f7bbSStefano Zampini ierr = ISConcatenate(PETSC_COMM_SELF,bsp,bzerodiag,&pressures);CHKERRQ(ierr); 26063b03f7bbSStefano Zampini 26077fbe2174Sstefano_zampini /* remove zeroed out pressures if we are setting up a BDDC solver for a saddle-point FETI-DP */ 26087fbe2174Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP",(PetscObject*)&iP);CHKERRQ(ierr); 26097fbe2174Sstefano_zampini if (iP) { 26107fbe2174Sstefano_zampini IS newpressures; 26117fbe2174Sstefano_zampini 26127fbe2174Sstefano_zampini ierr = ISDifference(pressures,iP,&newpressures);CHKERRQ(ierr); 26137fbe2174Sstefano_zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 26147fbe2174Sstefano_zampini pressures = newpressures; 26157fbe2174Sstefano_zampini } 261640fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 261740fa8d13SStefano Zampini if (!sorted) { 261840fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 261940fa8d13SStefano Zampini } 26203b03f7bbSStefano Zampini ierr = PetscFree(pp);CHKERRQ(ierr); 262140fa8d13SStefano Zampini } 26223b03f7bbSStefano Zampini 262397d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 262497d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 262527b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 262697d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2627339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2628339f8db1SStefano Zampini if (!sorted) { 2629339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2630339f8db1SStefano Zampini } 26314edc6404Sstefano_zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 26324edc6404Sstefano_zampini zerodiag_save = zerodiag; 2633339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 26344f1b2e48SStefano Zampini if (!nz) { 26354f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 26364f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 263740fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 263840fa8d13SStefano Zampini } 26394f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 26403b03f7bbSStefano Zampini 26414f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 26424f1b2e48SStefano Zampini zerodiag_subs = NULL; 26433b03f7bbSStefano Zampini benign_n = 0; 26441f4df5f7SStefano Zampini n_interior_dofs = 0; 26451f4df5f7SStefano Zampini interior_dofs = NULL; 26464edc6404Sstefano_zampini nneu = 0; 26474edc6404Sstefano_zampini if (pcbddc->NeumannBoundariesLocal) { 26484edc6404Sstefano_zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nneu);CHKERRQ(ierr); 26494edc6404Sstefano_zampini } 26503369cb78Sstefano_zampini checkb = (PetscBool)(!pcbddc->NeumannBoundariesLocal || pcbddc->current_level); 26514edc6404Sstefano_zampini if (checkb) { /* need to compute interior nodes */ 26521f4df5f7SStefano Zampini PetscInt n,i,j; 26531f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 26541f4df5f7SStefano Zampini PetscInt *iwork; 26551f4df5f7SStefano Zampini 26561f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 26571f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 26581f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 26591f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 266090648384SStefano Zampini for (i=1;i<n_neigh;i++) 26611f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 26621f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 26631f4df5f7SStefano Zampini for (i=0;i<n;i++) 26641f4df5f7SStefano Zampini if (!iwork[i]) 26651f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 26661f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 26671f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 26681f4df5f7SStefano Zampini } 26694f1b2e48SStefano Zampini if (has_null_pressures) { 26704f1b2e48SStefano Zampini IS *subs; 26714edc6404Sstefano_zampini PetscInt nsubs,i,j,nl; 26721f4df5f7SStefano Zampini const PetscInt *idxs; 26731f4df5f7SStefano Zampini PetscScalar *array; 26741f4df5f7SStefano Zampini Vec *work; 26751f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 26764f1b2e48SStefano Zampini 26774f1b2e48SStefano Zampini subs = pcbddc->local_subs; 26784f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 26791f4df5f7SStefano 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) */ 26804edc6404Sstefano_zampini if (checkb) { 26811f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 26821f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 26831f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 26841f4df5f7SStefano Zampini /* work[0] = 1_p */ 26851f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 26861f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 26871f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 26881f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 26891f4df5f7SStefano Zampini /* work[0] = 1_v */ 26901f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 26911f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 26921f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 26931f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 26941f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 26951f4df5f7SStefano Zampini } 26963b03f7bbSStefano Zampini 26973b03f7bbSStefano Zampini if (nsubs > 1 || bsp > 1) { 26983b03f7bbSStefano Zampini IS *is; 26993b03f7bbSStefano Zampini PetscInt b,totb; 27003b03f7bbSStefano Zampini 27013b03f7bbSStefano Zampini totb = bsp; 27023b03f7bbSStefano Zampini is = bsp > 1 ? bzerodiag : &zerodiag; 27033b03f7bbSStefano Zampini nsubs = PetscMax(nsubs,1); 27043b03f7bbSStefano Zampini ierr = PetscCalloc1(nsubs*totb,&zerodiag_subs);CHKERRQ(ierr); 27053b03f7bbSStefano Zampini for (b=0;b<totb;b++) { 27064f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 27074f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 27084f1b2e48SStefano Zampini IS t_zerodiag_subs; 27094f1b2e48SStefano Zampini PetscInt nl; 27104f1b2e48SStefano Zampini 27113b03f7bbSStefano Zampini if (subs) { 27124f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 27133b03f7bbSStefano Zampini } else { 27143b03f7bbSStefano Zampini IS tis; 27153b03f7bbSStefano Zampini 27163b03f7bbSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&nl,NULL);CHKERRQ(ierr); 27173b03f7bbSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,nl,0,1,&tis);CHKERRQ(ierr); 27183b03f7bbSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(tis,&l2g);CHKERRQ(ierr); 27193b03f7bbSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 27203b03f7bbSStefano Zampini } 27213b03f7bbSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,is[b],&t_zerodiag_subs);CHKERRQ(ierr); 27224f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 27234f1b2e48SStefano Zampini if (nl) { 27244f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 27254f1b2e48SStefano Zampini 27264edc6404Sstefano_zampini if (checkb) { 27271f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 27281f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 27291f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 27301f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 27311f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 27321f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 27331f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 27341f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 27351f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 27361f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 27371f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 27381f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 27391f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 27401f4df5f7SStefano Zampini valid = PETSC_FALSE; 27411f4df5f7SStefano Zampini break; 27421f4df5f7SStefano Zampini } 27431f4df5f7SStefano Zampini } 27441f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 27451f4df5f7SStefano Zampini } 27466632bad2Sstefano_zampini if (valid && nneu) { 27476632bad2Sstefano_zampini const PetscInt *idxs; 27481f4df5f7SStefano Zampini PetscInt nzb; 27491f4df5f7SStefano Zampini 27506632bad2Sstefano_zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 27516632bad2Sstefano_zampini ierr = ISGlobalToLocalMappingApply(l2g,IS_GTOLM_DROP,nneu,idxs,&nzb,NULL);CHKERRQ(ierr); 27526632bad2Sstefano_zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 27531f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 27541f4df5f7SStefano Zampini } 27551f4df5f7SStefano Zampini if (valid && pressures) { 27563b03f7bbSStefano Zampini IS t_pressure_subs,tmp; 27573b03f7bbSStefano Zampini PetscInt i1,i2; 27583b03f7bbSStefano Zampini 27594f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 27603b03f7bbSStefano Zampini ierr = ISEmbed(t_zerodiag_subs,t_pressure_subs,PETSC_TRUE,&tmp);CHKERRQ(ierr); 27613b03f7bbSStefano Zampini ierr = ISGetLocalSize(tmp,&i1);CHKERRQ(ierr); 27623b03f7bbSStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&i2);CHKERRQ(ierr); 27633b03f7bbSStefano Zampini if (i2 != i1) valid = PETSC_FALSE; 27644f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 27653b03f7bbSStefano Zampini ierr = ISDestroy(&tmp);CHKERRQ(ierr); 27664f1b2e48SStefano Zampini } 27674f1b2e48SStefano Zampini if (valid) { 27683b03f7bbSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[benign_n]);CHKERRQ(ierr); 27693b03f7bbSStefano Zampini benign_n++; 27703b03f7bbSStefano Zampini } else recompute_zerodiag = PETSC_TRUE; 27714f1b2e48SStefano Zampini } 27724f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 27734f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 27744f1b2e48SStefano Zampini } 27753b03f7bbSStefano Zampini } 27764f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 27774f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 27781f4df5f7SStefano Zampini 27796632bad2Sstefano_zampini if (nneu) valid = PETSC_FALSE; 27801f4df5f7SStefano Zampini if (valid && pressures) { 27814f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 27824f1b2e48SStefano Zampini } 27834edc6404Sstefano_zampini if (valid && checkb) { 27841f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 27851f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 27861f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 27871f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 27881f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 27891f4df5f7SStefano Zampini valid = PETSC_FALSE; 27901f4df5f7SStefano Zampini break; 27911f4df5f7SStefano Zampini } 27921f4df5f7SStefano Zampini } 27931f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 27941f4df5f7SStefano Zampini } 27954f1b2e48SStefano Zampini if (valid) { 27963b03f7bbSStefano Zampini benign_n = 1; 27973b03f7bbSStefano Zampini ierr = PetscMalloc1(benign_n,&zerodiag_subs);CHKERRQ(ierr); 27984f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 27994f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 28004f1b2e48SStefano Zampini } 28014f1b2e48SStefano Zampini } 28024edc6404Sstefano_zampini if (checkb) { 28031f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 28044f1b2e48SStefano Zampini } 28051f4df5f7SStefano Zampini } 28061f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 28074f1b2e48SStefano Zampini 28083b03f7bbSStefano Zampini if (!benign_n) { 2809b9b0e38cSStefano Zampini PetscInt n; 2810b9b0e38cSStefano Zampini 28114f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 28124f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2813b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 281476a58201SStefano Zampini if (n) have_null = PETSC_FALSE; 2815b9b0e38cSStefano Zampini } 28164f1b2e48SStefano Zampini 28174f1b2e48SStefano Zampini /* final check for null pressures */ 28184f1b2e48SStefano Zampini if (zerodiag && pressures) { 28193b03f7bbSStefano Zampini ierr = ISEqual(pressures,zerodiag,&have_null);CHKERRQ(ierr); 28204f1b2e48SStefano Zampini } 28214f1b2e48SStefano Zampini 28224f1b2e48SStefano Zampini if (recompute_zerodiag) { 28234f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 28243b03f7bbSStefano Zampini if (benign_n == 1) { 28254f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 28264f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 28274f1b2e48SStefano Zampini } else { 28284f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 28294f1b2e48SStefano Zampini 28304f1b2e48SStefano Zampini nzn = 0; 28313b03f7bbSStefano Zampini for (i=0;i<benign_n;i++) { 28324f1b2e48SStefano Zampini PetscInt ns; 28334f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 28344f1b2e48SStefano Zampini nzn += ns; 28354f1b2e48SStefano Zampini } 28364f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 28374f1b2e48SStefano Zampini nzn = 0; 28383b03f7bbSStefano Zampini for (i=0;i<benign_n;i++) { 28394f1b2e48SStefano Zampini PetscInt ns,*idxs; 28404f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 28414f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2842580bdb30SBarry Smith ierr = PetscArraycpy(new_idxs+nzn,idxs,ns);CHKERRQ(ierr); 28434f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 28444f1b2e48SStefano Zampini nzn += ns; 28454f1b2e48SStefano Zampini } 28464f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 28474f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 28484f1b2e48SStefano Zampini } 28494f1b2e48SStefano Zampini have_null = PETSC_FALSE; 28504f1b2e48SStefano Zampini } 28514f1b2e48SStefano Zampini 28523b03f7bbSStefano Zampini /* determines if the coarse solver will be singular or not */ 28533b03f7bbSStefano Zampini ierr = MPIU_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 28543b03f7bbSStefano Zampini 2855669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2856a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2857a198735bSStefano Zampini Mat A,loc_divudotp; 2858a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2859a198735bSStefano Zampini IS row,col,isused = NULL; 2860a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2861a198735bSStefano Zampini 28621f4df5f7SStefano Zampini if (pressures) { 28631f4df5f7SStefano Zampini isused = pressures; 28641f4df5f7SStefano Zampini } else { 28654edc6404Sstefano_zampini isused = zerodiag_save; 28661f4df5f7SStefano Zampini } 2867a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2868669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 28691ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 28701ae86dd6SStefano 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"); 2871a198735bSStefano Zampini n_isused = 0; 2872a198735bSStefano Zampini if (isused) { 2873a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2874a198735bSStefano Zampini } 2875ffc4695bSBarry Smith ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRMPI(ierr); 2876a198735bSStefano Zampini st = st-n_isused; 28771ae86dd6SStefano Zampini if (n) { 2878a198735bSStefano Zampini const PetscInt *gidxs; 2879a198735bSStefano Zampini 28807dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2881a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2882a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2883a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2884a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2885a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 28861ae86dd6SStefano Zampini } else { 2887a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2888a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2889a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2890a198735bSStefano Zampini } 2891a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2892a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2893a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2894a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2895a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2896a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2897a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2898a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2899a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2900a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2901a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2902a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2903a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2904a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 29051ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 29061ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 29071ae86dd6SStefano Zampini } 29084edc6404Sstefano_zampini ierr = ISDestroy(&zerodiag_save);CHKERRQ(ierr); 29093b03f7bbSStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 29103b03f7bbSStefano Zampini if (bzerodiag) { 29113b03f7bbSStefano Zampini PetscInt i; 2912b3afcdbeSStefano Zampini 29133b03f7bbSStefano Zampini for (i=0;i<bsp;i++) { 29143b03f7bbSStefano Zampini ierr = ISDestroy(&bzerodiag[i]);CHKERRQ(ierr); 29153b03f7bbSStefano Zampini } 29163b03f7bbSStefano Zampini ierr = PetscFree(bzerodiag);CHKERRQ(ierr); 29173b03f7bbSStefano Zampini } 29183b03f7bbSStefano Zampini pcbddc->benign_n = benign_n; 29193b03f7bbSStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 29203b03f7bbSStefano Zampini 29213b03f7bbSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 29223b03f7bbSStefano Zampini have_null = (PetscBool)(!!pcbddc->benign_n); 29233b03f7bbSStefano Zampini ierr = MPIU_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 29243b03f7bbSStefano Zampini 29253b03f7bbSStefano Zampini project_b0: 2926aa0d93e9SStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2927b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 29283b03f7bbSStefano Zampini if (pcbddc->benign_n) { 29294f1b2e48SStefano Zampini PetscInt i,s,*nnz; 29304f1b2e48SStefano Zampini 2931339f8db1SStefano Zampini /* local change of basis for pressures */ 2932339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 293397d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2934339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2935339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2936339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 2937aa0d93e9SStefano Zampini for (i=0;i<n;i++) nnz[i] = 1; /* defaults to identity */ 29384f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2939aa0d93e9SStefano Zampini const PetscInt *idxs; 29404f1b2e48SStefano Zampini PetscInt nzs,j; 29414f1b2e48SStefano Zampini 29423b03f7bbSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nzs);CHKERRQ(ierr); 29433b03f7bbSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 29444f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 29454f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 29463b03f7bbSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 29474f1b2e48SStefano Zampini } 2948339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2949e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->benign_change,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 2950339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2951aa0d93e9SStefano Zampini /* set identity by default */ 2952aa0d93e9SStefano Zampini for (i=0;i<n;i++) { 2953aa0d93e9SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,i,i,1.,INSERT_VALUES);CHKERRQ(ierr); 2954339f8db1SStefano Zampini } 29559f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 29564f1b2e48SStefano 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); 2957339f8db1SStefano Zampini /* set change on pressures */ 29584f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 29594f1b2e48SStefano Zampini PetscScalar *array; 2960aa0d93e9SStefano Zampini const PetscInt *idxs; 29614f1b2e48SStefano Zampini PetscInt nzs; 29624f1b2e48SStefano Zampini 29633b03f7bbSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[s],&nzs);CHKERRQ(ierr); 29643b03f7bbSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[s],&idxs);CHKERRQ(ierr); 29654f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2966339f8db1SStefano Zampini PetscScalar vals[2]; 2967339f8db1SStefano Zampini PetscInt cols[2]; 2968339f8db1SStefano Zampini 2969339f8db1SStefano Zampini cols[0] = idxs[i]; 29704f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2971339f8db1SStefano Zampini vals[0] = 1.; 2972b0f5fe93SStefano Zampini vals[1] = 1.; 29734f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2974339f8db1SStefano Zampini } 29754f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 29764f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 29774f1b2e48SStefano Zampini array[nzs-1] = 1.; 29784f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 29794f1b2e48SStefano Zampini /* store local idxs for p0 */ 29804f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 29813b03f7bbSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2982339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 29834f1b2e48SStefano Zampini } 2984339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2985339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 29863b03f7bbSStefano Zampini 2987a3df083aSStefano Zampini /* project if needed */ 2988a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 29891dd7afcfSStefano Zampini Mat M; 29901dd7afcfSStefano Zampini 29911dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2992339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 29931dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 29941dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2995a3df083aSStefano Zampini } 29964f1b2e48SStefano Zampini /* store global idxs for p0 */ 29974f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2998339f8db1SStefano Zampini } 2999339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 3000339f8db1SStefano Zampini PetscFunctionReturn(0); 3001339f8db1SStefano Zampini } 3002339f8db1SStefano Zampini 3003015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 3004efc2fbd9SStefano Zampini { 3005efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3006de9d7bd0SStefano Zampini PetscScalar *array; 3007efc2fbd9SStefano Zampini PetscErrorCode ierr; 3008efc2fbd9SStefano Zampini 3009efc2fbd9SStefano Zampini PetscFunctionBegin; 3010efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 3011efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 30124f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 3013efc2fbd9SStefano Zampini } 3014de9d7bd0SStefano Zampini if (get) { 3015efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 30164f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 30174f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 3018efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 3019de9d7bd0SStefano Zampini } else { 3020de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 3021de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 3022de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 3023de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 3024efc2fbd9SStefano Zampini } 3025efc2fbd9SStefano Zampini PetscFunctionReturn(0); 3026efc2fbd9SStefano Zampini } 3027efc2fbd9SStefano Zampini 3028c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 3029c263805aSStefano Zampini { 3030c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3031c263805aSStefano Zampini PetscErrorCode ierr; 3032c263805aSStefano Zampini 3033c263805aSStefano Zampini PetscFunctionBegin; 3034c263805aSStefano Zampini /* TODO: add error checking 3035c263805aSStefano Zampini - avoid nested pop (or push) calls. 3036c263805aSStefano Zampini - cannot push before pop. 30371c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 3038c263805aSStefano Zampini */ 30394f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 3040efc2fbd9SStefano Zampini PetscFunctionReturn(0); 3041efc2fbd9SStefano Zampini } 3042c263805aSStefano Zampini if (pop) { 3043a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 30444f1b2e48SStefano Zampini IS is_p0; 30454f1b2e48SStefano Zampini MatReuse reuse; 3046c263805aSStefano Zampini 3047c263805aSStefano Zampini /* extract B_0 */ 30484f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 30494f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 30504f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 30514f1b2e48SStefano Zampini } 30524f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 30537dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 3054c263805aSStefano Zampini /* remove rows and cols from local problem */ 3055c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 305697d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 30574f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 30584f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 3059a3df083aSStefano Zampini } else { 3060a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 3061a3df083aSStefano Zampini PetscScalar *vals; 3062a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 3063a3df083aSStefano Zampini 3064a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 3065a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 3066a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 30670b5adadeSStefano Zampini PetscInt *nnz; 3068a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 3069a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 3070a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 3071331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 3072331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3073331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 3074331e053bSStefano Zampini nnz[i] = n - nnz[i]; 3075331e053bSStefano Zampini } 3076331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 3077e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->benign_B0,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3078331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3079331e053bSStefano Zampini } 3080a3df083aSStefano Zampini 3081a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3082a3df083aSStefano Zampini PetscScalar *array; 3083a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 3084a3df083aSStefano Zampini 3085a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 3086a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3087a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 3088a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 3089a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 3090a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 3091a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 3092a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 3093a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 3094a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 3095a3df083aSStefano Zampini cum = 0; 3096a3df083aSStefano Zampini for (j=0;j<n;j++) { 309722db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 3098a3df083aSStefano Zampini vals[cum] = array[j]; 3099a3df083aSStefano Zampini idxs_ins[cum] = j; 3100a3df083aSStefano Zampini cum++; 3101a3df083aSStefano Zampini } 3102a3df083aSStefano Zampini } 3103a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 3104a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 3105a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 3106a3df083aSStefano Zampini } 3107a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3108a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3109a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 3110a3df083aSStefano Zampini } 3111c263805aSStefano Zampini } else { /* push */ 3112a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 31134f1b2e48SStefano Zampini PetscInt i; 31144f1b2e48SStefano Zampini 31154f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 31164f1b2e48SStefano Zampini PetscScalar *B0_vals; 31174f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 31184f1b2e48SStefano Zampini 31194f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 31204f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 31217b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 31224f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 31234f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 31244f1b2e48SStefano Zampini } 3125c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3126c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 31276080607fSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!"); 3128c263805aSStefano Zampini } 3129c263805aSStefano Zampini PetscFunctionReturn(0); 3130c263805aSStefano Zampini } 3131c263805aSStefano Zampini 313208122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 3133b1b3d7a2SStefano Zampini { 3134b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 313508122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 313608122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 313708122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 313808122e43SStefano Zampini PetscScalar *work,lwork; 313908122e43SStefano Zampini PetscScalar *St,*S,*eigv; 314008122e43SStefano Zampini PetscScalar *Sarray,*Starray; 3141bd2a564bSStefano Zampini PetscReal *eigs,thresh,lthresh,uthresh; 31421b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 3143f6f667cfSStefano Zampini PetscBool allocated_S_St; 314408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 314508122e43SStefano Zampini PetscReal *rwork; 314608122e43SStefano Zampini #endif 3147b1b3d7a2SStefano Zampini PetscErrorCode ierr; 3148b1b3d7a2SStefano Zampini 3149b1b3d7a2SStefano Zampini PetscFunctionBegin; 3150b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 3151af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 3152bd2a564bSStefano 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); 315343371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_AdaptiveSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 315406a4e24aSStefano Zampini 3155fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3156fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3157fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3158fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 31591575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3160fd14bc51SStefano Zampini } 3161fd14bc51SStefano Zampini 3162e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 31636080607fSStefano 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); 3164e496cd5dSStefano Zampini } 3165e496cd5dSStefano Zampini 316608122e43SStefano Zampini /* max size of subsets */ 316708122e43SStefano Zampini mss = 0; 316808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 316908122e43SStefano Zampini PetscInt subset_size; 3170862806e4SStefano Zampini 317108122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 317208122e43SStefano Zampini mss = PetscMax(mss,subset_size); 317308122e43SStefano Zampini } 317408122e43SStefano Zampini 317508122e43SStefano Zampini /* min/max and threshold */ 317608122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 3177f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 317808122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 3179f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 3180bd2a564bSStefano Zampini if (nmin || !sub_schurs->is_posdef) { /* XXX */ 3181f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 3182f6f667cfSStefano Zampini } 318308122e43SStefano Zampini 318408122e43SStefano Zampini /* allocate lapack workspace */ 318508122e43SStefano Zampini cum = cum2 = 0; 318608122e43SStefano Zampini maxneigs = 0; 318708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 318808122e43SStefano Zampini PetscInt n,subset_size; 3189f6f667cfSStefano Zampini 319008122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 319108122e43SStefano Zampini n = PetscMin(subset_size,nmax); 31929162d606SStefano Zampini cum += subset_size; 31939162d606SStefano Zampini cum2 += subset_size*n; 319408122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 319508122e43SStefano Zampini } 31967ebab0bbSStefano Zampini lwork = 0; 319708122e43SStefano Zampini if (mss) { 3198bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 31997ebab0bbSStefano Zampini PetscScalar sdummy = 0.; 320008122e43SStefano Zampini PetscBLASInt B_itype = 1; 32017ebab0bbSStefano Zampini PetscBLASInt B_N = mss, idummy = 0; 32027ebab0bbSStefano Zampini PetscReal rdummy = 0.,zero = 0.0; 32034c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 320408122e43SStefano Zampini 320508122e43SStefano Zampini B_lwork = -1; 32067ebab0bbSStefano Zampini /* some implementations may complain about NULL pointers, even if we are querying */ 32077ebab0bbSStefano Zampini S = &sdummy; 32087ebab0bbSStefano Zampini St = &sdummy; 32097ebab0bbSStefano Zampini eigs = &rdummy; 32107ebab0bbSStefano Zampini eigv = &sdummy; 32117ebab0bbSStefano Zampini B_iwork = &idummy; 32127ebab0bbSStefano Zampini B_ifail = &idummy; 3213d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 32147ebab0bbSStefano Zampini rwork = &rdummy; 3215d1710679SStefano Zampini #endif 32168bec7fa6SStefano Zampini thresh = 1.0; 321708122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 321808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 321908122e43SStefano 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)); 322008122e43SStefano Zampini #else 322108122e43SStefano 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)); 322208122e43SStefano Zampini #endif 322308122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 322408122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3225bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 322608122e43SStefano Zampini } 322708122e43SStefano Zampini 322808122e43SStefano Zampini nv = 0; 3229d62866d3SStefano 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) */ 3230d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 323108122e43SStefano Zampini } 32324c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 3233f6f667cfSStefano Zampini if (allocated_S_St) { 3234f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 3235f6f667cfSStefano Zampini } 3236f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 323708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 323808122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 323908122e43SStefano Zampini #endif 32409162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 32419162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 32429162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 324308122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 32449162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 3245580bdb30SBarry Smith ierr = PetscArrayzero(pcbddc->adaptive_constraints_n,nv+sub_schurs->n_subs);CHKERRQ(ierr); 324608122e43SStefano Zampini 324708122e43SStefano Zampini maxneigs = 0; 324872b8c272SStefano Zampini cum = cumarray = 0; 32499162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 32509162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 3251d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 325208122e43SStefano Zampini const PetscInt *idxs; 325308122e43SStefano Zampini 3254d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 325508122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 325608122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 325708122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 325808122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 32599162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 32609162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 326108122e43SStefano Zampini } 3262d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 326308122e43SStefano Zampini } 326408122e43SStefano Zampini 326508122e43SStefano Zampini if (mss) { /* multilevel */ 326608122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 326708122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 326808122e43SStefano Zampini } 326908122e43SStefano Zampini 3270bd2a564bSStefano Zampini lthresh = pcbddc->adaptive_threshold[0]; 3271bd2a564bSStefano Zampini uthresh = pcbddc->adaptive_threshold[1]; 327208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 327308122e43SStefano Zampini const PetscInt *idxs; 32749d54b7f4SStefano Zampini PetscReal upper,lower; 3275862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 327608122e43SStefano Zampini PetscBLASInt B_N; 3277aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 3278bd2a564bSStefano Zampini PetscBool scal = PETSC_FALSE; 327908122e43SStefano Zampini 32809d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 32819d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 3282bd2a564bSStefano Zampini lower = uthresh; 32839d54b7f4SStefano Zampini } else { 3284bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented without deluxe scaling"); 3285bd2a564bSStefano Zampini upper = 1./uthresh; 32869d54b7f4SStefano Zampini lower = 0.; 32879d54b7f4SStefano Zampini } 3288862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 3289ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 3290f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 3291bd2a564bSStefano Zampini /* this is experimental: we assume the dofs have been properly grouped to have 3292bd2a564bSStefano Zampini the diagonal blocks Schur complements either positive or negative definite (true for Stokes) */ 3293bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) { 3294bd2a564bSStefano Zampini Mat T; 3295bd2a564bSStefano Zampini 3296bd2a564bSStefano Zampini for (j=0;j<subset_size;j++) { 3297bd2a564bSStefano Zampini if (PetscRealPart(*(Sarray+cumarray+j*(subset_size+1))) < 0.0) { 3298bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Sarray+cumarray,&T);CHKERRQ(ierr); 3299bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3300bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3301bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Starray+cumarray,&T);CHKERRQ(ierr); 3302bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3303bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3304bd2a564bSStefano Zampini if (sub_schurs->change_primal_sub) { 3305bd2a564bSStefano Zampini PetscInt nz,k; 3306bd2a564bSStefano Zampini const PetscInt *idxs; 3307bd2a564bSStefano Zampini 3308bd2a564bSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nz);CHKERRQ(ierr); 3309bd2a564bSStefano Zampini ierr = ISGetIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3310bd2a564bSStefano Zampini for (k=0;k<nz;k++) { 3311bd2a564bSStefano Zampini *( Sarray + cumarray + idxs[k]*(subset_size+1)) *= -1.0; 3312bd2a564bSStefano Zampini *(Starray + cumarray + idxs[k]*(subset_size+1)) = 0.0; 3313bd2a564bSStefano Zampini } 3314bd2a564bSStefano Zampini ierr = ISRestoreIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3315bd2a564bSStefano Zampini } 3316bd2a564bSStefano Zampini scal = PETSC_TRUE; 3317bd2a564bSStefano Zampini break; 3318bd2a564bSStefano Zampini } 3319bd2a564bSStefano Zampini } 3320bd2a564bSStefano Zampini } 3321bd2a564bSStefano Zampini 3322f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 3323bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 3324aff50787SStefano Zampini PetscInt j,k; 3325580bdb30SBarry Smith if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscArraycmp() later */ 3326580bdb30SBarry Smith ierr = PetscArrayzero(S,subset_size*subset_size);CHKERRQ(ierr); 3327580bdb30SBarry Smith ierr = PetscArrayzero(St,subset_size*subset_size);CHKERRQ(ierr); 332808122e43SStefano Zampini } 332908122e43SStefano Zampini for (j=0;j<subset_size;j++) { 3330aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 3331aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 3332aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 3333aff50787SStefano Zampini } 333408122e43SStefano Zampini } 333508122e43SStefano Zampini } else { 3336580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3337580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 333808122e43SStefano Zampini } 33398bec7fa6SStefano Zampini } else { 3340f6f667cfSStefano Zampini S = Sarray + cumarray; 3341f6f667cfSStefano Zampini St = Starray + cumarray; 33428bec7fa6SStefano Zampini } 3343aff50787SStefano Zampini /* see if we can save some work */ 3344b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 3345580bdb30SBarry Smith ierr = PetscArraycmp(S,St,subset_size*subset_size,&same_data);CHKERRQ(ierr); 3346aff50787SStefano Zampini } 3347aff50787SStefano Zampini 3348b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 3349aff50787SStefano Zampini B_neigs = 0; 3350aff50787SStefano Zampini } else { 3351bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 335208122e43SStefano Zampini PetscBLASInt B_itype = 1; 3353f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 33544c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 33559552c7c7SStefano Zampini PetscInt nmin_s; 3356bd2a564bSStefano Zampini PetscBool compute_range; 3357bd2a564bSStefano Zampini 33589036ceccSStefano Zampini B_neigs = 0; 3359bd2a564bSStefano Zampini compute_range = (PetscBool)!same_data; 3360bd2a564bSStefano Zampini if (nmin >= subset_size) compute_range = PETSC_FALSE; 336108122e43SStefano Zampini 3362fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 33639036ceccSStefano Zampini PetscInt nc = 0; 3364d16cbb6bSStefano Zampini 33659036ceccSStefano Zampini if (sub_schurs->change_primal_sub) { 33669036ceccSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nc);CHKERRQ(ierr); 33679036ceccSStefano Zampini } 33686080607fSStefano 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); 3369b7ab4a40SStefano Zampini } 3370b7ab4a40SStefano Zampini 337108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3372b7ab4a40SStefano Zampini if (compute_range) { 3373d16cbb6bSStefano Zampini 3374d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 3375bd2a564bSStefano Zampini if (sub_schurs->is_posdef) { 337608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 33779d54b7f4SStefano 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)); 337808122e43SStefano Zampini #else 33799d54b7f4SStefano 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)); 338008122e43SStefano Zampini #endif 338143371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3382bd2a564bSStefano Zampini } else { /* no theory so far, but it works nicely */ 33839036ceccSStefano Zampini PetscInt recipe = 0,recipe_m = 1; 3384bd2a564bSStefano Zampini PetscReal bb[2]; 3385bd2a564bSStefano Zampini 3386bd2a564bSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe",&recipe,NULL);CHKERRQ(ierr); 3387bd2a564bSStefano Zampini switch (recipe) { 3388bd2a564bSStefano Zampini case 0: 3389bd2a564bSStefano Zampini if (scal) { bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; } 3390bd2a564bSStefano Zampini else { bb[0] = uthresh; bb[1] = PETSC_MAX_REAL; } 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 break; 3398bd2a564bSStefano Zampini case 1: 3399bd2a564bSStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh*lthresh; 3400bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3401bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 3402bd2a564bSStefano Zampini #else 3403bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 3404bd2a564bSStefano Zampini #endif 340543371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3406bd2a564bSStefano Zampini if (!scal) { 34079036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 3408bd2a564bSStefano Zampini 3409aed7e7d0SStefano Zampini bb[0] = PetscMax(lthresh*lthresh,uthresh); bb[1] = PETSC_MAX_REAL; 3410580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3411580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3412bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3413bd2a564bSStefano 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)); 3414bd2a564bSStefano Zampini #else 3415bd2a564bSStefano 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)); 3416bd2a564bSStefano Zampini #endif 341743371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3418bd2a564bSStefano Zampini B_neigs += B_neigs2; 3419bd2a564bSStefano Zampini } 3420bd2a564bSStefano Zampini break; 34219036ceccSStefano Zampini case 2: 34229036ceccSStefano Zampini if (scal) { 34239036ceccSStefano Zampini bb[0] = PETSC_MIN_REAL; 34249036ceccSStefano Zampini bb[1] = 0; 34259036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34269036ceccSStefano 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)); 34279036ceccSStefano Zampini #else 34289036ceccSStefano 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)); 34299036ceccSStefano Zampini #endif 343043371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34319036ceccSStefano Zampini } else { 34329036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 34339036ceccSStefano Zampini PetscBool import = PETSC_FALSE; 34349036ceccSStefano Zampini 34359036ceccSStefano Zampini lthresh = PetscMax(lthresh,0.0); 34369036ceccSStefano Zampini if (lthresh > 0.0) { 34379036ceccSStefano Zampini bb[0] = PETSC_MIN_REAL; 34389036ceccSStefano Zampini bb[1] = lthresh*lthresh; 34399036ceccSStefano Zampini 34409036ceccSStefano Zampini import = PETSC_TRUE; 34419036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34429036ceccSStefano 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)); 34439036ceccSStefano Zampini #else 34449036ceccSStefano 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)); 34459036ceccSStefano Zampini #endif 344643371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34479036ceccSStefano Zampini } 34489036ceccSStefano Zampini bb[0] = PetscMax(lthresh*lthresh,uthresh); 34499036ceccSStefano Zampini bb[1] = PETSC_MAX_REAL; 34509036ceccSStefano Zampini if (import) { 3451580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3452580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 34539036ceccSStefano Zampini } 34549036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34559036ceccSStefano 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)); 34569036ceccSStefano Zampini #else 34579036ceccSStefano 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)); 34589036ceccSStefano Zampini #endif 345943371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34609036ceccSStefano Zampini B_neigs += B_neigs2; 34619036ceccSStefano Zampini } 34629036ceccSStefano Zampini break; 34639036ceccSStefano Zampini case 3: 34649036ceccSStefano Zampini if (scal) { 34659036ceccSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe3_min_scal",&recipe_m,NULL);CHKERRQ(ierr); 34669036ceccSStefano Zampini } else { 34679036ceccSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe3_min",&recipe_m,NULL);CHKERRQ(ierr); 34689036ceccSStefano Zampini } 34699036ceccSStefano Zampini if (!scal) { 34709036ceccSStefano Zampini bb[0] = uthresh; 34719036ceccSStefano Zampini bb[1] = PETSC_MAX_REAL; 34729036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34739036ceccSStefano 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)); 34749036ceccSStefano Zampini #else 34759036ceccSStefano 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)); 34769036ceccSStefano Zampini #endif 347743371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34789036ceccSStefano Zampini } 34799036ceccSStefano Zampini if (recipe_m > 0 && B_N - B_neigs > 0) { 34809036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 34819036ceccSStefano Zampini 34829036ceccSStefano Zampini B_IL = 1; 34839036ceccSStefano Zampini ierr = PetscBLASIntCast(PetscMin(recipe_m,B_N - B_neigs),&B_IU);CHKERRQ(ierr); 3484580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3485580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 34869036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34879036ceccSStefano 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)); 34889036ceccSStefano Zampini #else 34899036ceccSStefano 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)); 34909036ceccSStefano Zampini #endif 349143371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 34929036ceccSStefano Zampini B_neigs += B_neigs2; 34939036ceccSStefano Zampini } 34949036ceccSStefano Zampini break; 349548cebe81SStefano Zampini case 4: 349648cebe81SStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; 349748cebe81SStefano Zampini #if defined(PETSC_USE_COMPLEX) 349848cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 349948cebe81SStefano Zampini #else 350048cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 350148cebe81SStefano Zampini #endif 350243371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 350348cebe81SStefano Zampini { 350448cebe81SStefano Zampini PetscBLASInt B_neigs2 = 0; 350548cebe81SStefano Zampini 350648cebe81SStefano Zampini bb[0] = PetscMax(lthresh+PETSC_SMALL,uthresh); bb[1] = PETSC_MAX_REAL; 3507580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3508580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 350948cebe81SStefano Zampini #if defined(PETSC_USE_COMPLEX) 351048cebe81SStefano 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)); 351148cebe81SStefano Zampini #else 351248cebe81SStefano 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)); 351348cebe81SStefano Zampini #endif 351443371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 351548cebe81SStefano Zampini B_neigs += B_neigs2; 351648cebe81SStefano Zampini } 351748cebe81SStefano Zampini break; 351880db8efeSStefano Zampini case 5: /* same as before: first compute all eigenvalues, then filter */ 351980db8efeSStefano Zampini #if defined(PETSC_USE_COMPLEX) 352080db8efeSStefano 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)); 352180db8efeSStefano Zampini #else 352280db8efeSStefano 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)); 352380db8efeSStefano Zampini #endif 352443371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 352580db8efeSStefano Zampini { 352680db8efeSStefano Zampini PetscInt e,k,ne; 352780db8efeSStefano Zampini for (e=0,ne=0;e<B_neigs;e++) { 352880db8efeSStefano Zampini if (eigs[e] < lthresh || eigs[e] > uthresh) { 352980db8efeSStefano Zampini for (k=0;k<B_N;k++) S[ne*B_N+k] = eigv[e*B_N+k]; 353080db8efeSStefano Zampini eigs[ne] = eigs[e]; 353180db8efeSStefano Zampini ne++; 353280db8efeSStefano Zampini } 353380db8efeSStefano Zampini } 3534580bdb30SBarry Smith ierr = PetscArraycpy(eigv,S,B_N*ne);CHKERRQ(ierr); 353580db8efeSStefano Zampini B_neigs = ne; 353680db8efeSStefano Zampini } 353780db8efeSStefano Zampini break; 3538bd2a564bSStefano Zampini default: 3539bd2a564bSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Unknown recipe %D",recipe); 3540bd2a564bSStefano Zampini } 3541bd2a564bSStefano Zampini } 3542bd2a564bSStefano Zampini } else if (!same_data) { /* this is just to see all the eigenvalues */ 3543d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 3544d16cbb6bSStefano Zampini B_IL = 1; 3545d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 35469d54b7f4SStefano 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)); 3547d16cbb6bSStefano Zampini #else 35489d54b7f4SStefano 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)); 3549d16cbb6bSStefano Zampini #endif 355043371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3551b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 3552b7ab4a40SStefano Zampini PetscInt k; 3553b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 3554b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 3555b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 3556b7ab4a40SStefano Zampini nmin = nmax; 3557580bdb30SBarry Smith ierr = PetscArrayzero(eigv,subset_size*nmax);CHKERRQ(ierr); 3558b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 3559b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 3560b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 3561b7ab4a40SStefano Zampini } 3562d16cbb6bSStefano Zampini } 356308122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 356408122e43SStefano Zampini if (B_ierr) { 35656c4ed002SBarry 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); 35666c4ed002SBarry 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); 35676c4ed002SBarry 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); 356808122e43SStefano Zampini } 356908122e43SStefano Zampini 357008122e43SStefano Zampini if (B_neigs > nmax) { 3571fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 35726080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %D.\n",B_neigs,nmax);CHKERRQ(ierr); 3573fd14bc51SStefano Zampini } 3574bd2a564bSStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = scal ? 0 : B_neigs-nmax; 357508122e43SStefano Zampini B_neigs = nmax; 357608122e43SStefano Zampini } 357708122e43SStefano Zampini 35789552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 35799552c7c7SStefano Zampini if (B_neigs < nmin_s) { 35809036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 358108122e43SStefano Zampini 35829d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3583bd2a564bSStefano Zampini if (scal) { 3584bd2a564bSStefano Zampini B_IU = nmin_s; 3585bd2a564bSStefano Zampini B_IL = B_neigs + 1; 3586bd2a564bSStefano Zampini } else { 3587f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 35889d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 3589bd2a564bSStefano Zampini } 35909d54b7f4SStefano Zampini } else { 35919d54b7f4SStefano Zampini B_IL = B_neigs + 1; 35929d54b7f4SStefano Zampini B_IU = nmin_s; 35939d54b7f4SStefano Zampini } 3594fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 35956080607fSStefano 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); 3596fd14bc51SStefano Zampini } 3597bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 35981ae86dd6SStefano Zampini PetscInt j,k; 359908122e43SStefano Zampini for (j=0;j<subset_size;j++) { 36001ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 36011ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 36021ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 360308122e43SStefano Zampini } 360408122e43SStefano Zampini } 360508122e43SStefano Zampini } else { 3606580bdb30SBarry Smith ierr = PetscArraycpy(S,Sarray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 3607580bdb30SBarry Smith ierr = PetscArraycpy(St,Starray+cumarray,subset_size*subset_size);CHKERRQ(ierr); 360808122e43SStefano Zampini } 360908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 361008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 36119d54b7f4SStefano 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)); 361208122e43SStefano Zampini #else 36139d54b7f4SStefano 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)); 361408122e43SStefano Zampini #endif 361543371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 361608122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 361708122e43SStefano Zampini B_neigs += B_neigs2; 361808122e43SStefano Zampini } 361908122e43SStefano Zampini if (B_ierr) { 36206c4ed002SBarry 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); 36216c4ed002SBarry 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); 36226c4ed002SBarry 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); 362308122e43SStefano Zampini } 3624fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3625ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 362608122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 362708122e43SStefano Zampini if (eigs[j] == 0.0) { 3628ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 362908122e43SStefano Zampini } else { 36309d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3631ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 36329d54b7f4SStefano Zampini } else { 36339d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 36349d54b7f4SStefano Zampini } 3635fd14bc51SStefano Zampini } 363608122e43SStefano Zampini } 363708122e43SStefano Zampini } 3638bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 3639aff50787SStefano Zampini } 36406c3e6151SStefano Zampini /* change the basis back to the original one */ 36416c3e6151SStefano Zampini if (sub_schurs->change) { 364272b8c272SStefano Zampini Mat change,phi,phit; 36436c3e6151SStefano Zampini 364403dfb2d7SStefano Zampini if (pcbddc->dbg_flag > 2) { 36456c3e6151SStefano Zampini PetscInt ii; 36466c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 36476c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 36486c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 3649684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3650684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 3651684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 3652684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3653684229deSStefano Zampini #else 36546c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 3655684229deSStefano Zampini #endif 36566c3e6151SStefano Zampini } 36576c3e6151SStefano Zampini } 36586c3e6151SStefano Zampini } 365972b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 36606c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 366172b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 36626c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 36636c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 36646c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 36656c3e6151SStefano Zampini } 36668bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 36678bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 36689162d606SStefano Zampini if (B_neigs) { 3669580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum],eigv+eigs_start*subset_size,B_neigs*subset_size);CHKERRQ(ierr); 3670fd14bc51SStefano Zampini 3671fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 36729552c7c7SStefano Zampini PetscInt ii; 36739552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 3674ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 36759552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 3676ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3677ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3678ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3679ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3680ac47001eSStefano Zampini #else 3681ac47001eSStefano 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); 3682ac47001eSStefano Zampini #endif 36839552c7c7SStefano Zampini } 36849552c7c7SStefano Zampini } 3685fd14bc51SStefano Zampini } 3686580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size);CHKERRQ(ierr); 36879162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 36889162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 36899162d606SStefano Zampini cum++; 369008122e43SStefano Zampini } 369108122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 369208122e43SStefano Zampini /* shift for next computation */ 369308122e43SStefano Zampini cumarray += subset_size*subset_size; 369408122e43SStefano Zampini } 3695fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3696fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3697fd14bc51SStefano Zampini } 369808122e43SStefano Zampini 369908122e43SStefano Zampini if (mss) { 370008122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 370108122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3702f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3703f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3704f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 370508122e43SStefano Zampini } 3706f6f667cfSStefano Zampini if (allocated_S_St) { 3707f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3708f6f667cfSStefano Zampini } 3709f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 371008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 371108122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 371208122e43SStefano Zampini #endif 371308122e43SStefano Zampini if (pcbddc->dbg_flag) { 37141b968477SStefano Zampini PetscInt maxneigs_r; 3715b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 37166080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %D\n",maxneigs_r);CHKERRQ(ierr); 371708122e43SStefano Zampini } 371843371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_AdaptiveSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 371908122e43SStefano Zampini PetscFunctionReturn(0); 372008122e43SStefano Zampini } 3721b1b3d7a2SStefano Zampini 3722c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3723c8587f34SStefano Zampini { 37248629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3725c8587f34SStefano Zampini PetscErrorCode ierr; 3726c8587f34SStefano Zampini 3727c8587f34SStefano Zampini PetscFunctionBegin; 3728f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 37295e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3730c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3731c8587f34SStefano Zampini 3732684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 37330fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3734684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3735c8587f34SStefano Zampini 37368629588bSStefano Zampini /* 37378629588bSStefano Zampini Setup local correction and local part of coarse basis. 37388629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 37398629588bSStefano Zampini */ 374047f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 37418629588bSStefano Zampini 37428629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 37438629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 37448629588bSStefano Zampini 37458629588bSStefano Zampini /* free */ 37468629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3747c8587f34SStefano Zampini PetscFunctionReturn(0); 3748c8587f34SStefano Zampini } 3749c8587f34SStefano Zampini 3750674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3751674ae819SStefano Zampini { 3752674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3753674ae819SStefano Zampini PetscErrorCode ierr; 3754674ae819SStefano Zampini 3755674ae819SStefano Zampini PetscFunctionBegin; 3756674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 375730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3758674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3759785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3760674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3761f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3762f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3763785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 376463602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 376563602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3766674ae819SStefano Zampini PetscFunctionReturn(0); 3767674ae819SStefano Zampini } 3768674ae819SStefano Zampini 3769674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3770674ae819SStefano Zampini { 3771674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 37724f1b2e48SStefano Zampini PetscInt i; 3773674ae819SStefano Zampini PetscErrorCode ierr; 3774674ae819SStefano Zampini 3775674ae819SStefano Zampini PetscFunctionBegin; 37761e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 37771e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3778a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3779b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3780674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 378116909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 37821dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3783674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3784669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3785fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 37869326c5c6Sstefano_zampini ierr = PCBDDCGraphDestroy(&pcbddc->mat_graph);CHKERRQ(ierr); 37874f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 37884f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 37894f1b2e48SStefano Zampini } 3790e68a0315Sstefano_zampini pcbddc->n_local_subs = 0; 37914f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3792e68a0315Sstefano_zampini ierr = PCBDDCSubSchursDestroy(&pcbddc->sub_schurs);CHKERRQ(ierr); 3793c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 37948af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 37951c7a958bSStefano Zampini pcbddc->corner_selected = PETSC_FALSE; 3796674ae819SStefano Zampini PetscFunctionReturn(0); 3797674ae819SStefano Zampini } 3798674ae819SStefano Zampini 3799674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3800674ae819SStefano Zampini { 3801674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3802674ae819SStefano Zampini PetscErrorCode ierr; 3803674ae819SStefano Zampini 3804674ae819SStefano Zampini PetscFunctionBegin; 3805674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 380658da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3807ca92afb2SStefano Zampini PetscScalar *array; 380806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 380906656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 381058da7f69SStefano Zampini } 3811674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3812674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 381315aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 381415aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3815674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3816674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3817674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 381806656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3819674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3820674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 38218ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3822674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3823674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3824674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 38259326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_D);CHKERRQ(ierr); 38269326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 38279326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3828f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3829727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 38300e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3831f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 383270cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 383381d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 38340369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 38351dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 38364f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 38378b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3838ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3839ca92afb2SStefano Zampini PetscInt i; 3840ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3841ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3842ca92afb2SStefano Zampini } 3843ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3844ca92afb2SStefano Zampini } 38454f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3846674ae819SStefano Zampini PetscFunctionReturn(0); 3847674ae819SStefano Zampini } 3848674ae819SStefano Zampini 3849f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 38506bfb1811SStefano Zampini { 38516bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 38526bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 38536bfb1811SStefano Zampini VecType impVecType; 38544f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 38556bfb1811SStefano Zampini PetscErrorCode ierr; 38566bfb1811SStefano Zampini 38576bfb1811SStefano Zampini PetscFunctionBegin; 38584f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3859b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 38606bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3861e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3862e7b262bdSStefano Zampini /* R nodes */ 3863e7b262bdSStefano Zampini old_size = -1; 3864e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3865e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3866e7b262bdSStefano Zampini } 3867e7b262bdSStefano Zampini if (n_R != old_size) { 3868e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3869e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 38706bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 38716bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 38726bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 38736bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3874e7b262bdSStefano Zampini } 3875e7b262bdSStefano Zampini /* local primal dofs */ 3876e7b262bdSStefano Zampini old_size = -1; 3877e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3878e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3879e7b262bdSStefano Zampini } 3880e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3881e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 388283b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3883e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 38846bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3885e7b262bdSStefano Zampini } 3886e7b262bdSStefano Zampini /* local explicit constraints */ 3887e7b262bdSStefano Zampini old_size = -1; 3888e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3889e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3890e7b262bdSStefano Zampini } 3891e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3892e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 389383b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 389483b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 389583b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 389683b7ccabSStefano Zampini } 38976bfb1811SStefano Zampini PetscFunctionReturn(0); 38986bfb1811SStefano Zampini } 38996bfb1811SStefano Zampini 390047f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 390188ebb749SStefano Zampini { 390225084f0cSStefano Zampini PetscErrorCode ierr; 390325084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 390488ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 390588ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3906d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 390725084f0cSStefano Zampini /* submatrices of local problem */ 390880677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 390906656605SStefano Zampini /* submatrices of local coarse problem */ 391006656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 391125084f0cSStefano Zampini /* working matrices */ 391206656605SStefano Zampini Mat C_CR; 391325084f0cSStefano Zampini /* additional working stuff */ 391406656605SStefano Zampini PC pc_R; 3915c58f9fdbSStefano Zampini Mat F,Brhs = NULL; 39165cbda25cSStefano Zampini Vec dummy_vec; 39177ebab0bbSStefano Zampini PetscBool isLU,isCHOL,need_benign_correction,sparserhs; 391825084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 391906656605SStefano Zampini PetscScalar *work; 392006656605SStefano Zampini PetscInt *idx_V_B; 3921ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 392206656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 392306656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 392488ebb749SStefano Zampini 392588ebb749SStefano Zampini PetscFunctionBegin; 39269a962809SStefano 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"); 392743371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CorrectionSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 3928ffd830a3SStefano Zampini 3929ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3930b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 39314f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3932b371cd4fSStefano Zampini n_B = pcis->n_B; 3933b371cd4fSStefano Zampini n_D = pcis->n - n_B; 393488ebb749SStefano Zampini n_R = pcis->n - n_vertices; 393588ebb749SStefano Zampini 393688ebb749SStefano Zampini /* vertices in boundary numbering */ 3937785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 39380e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 39396080607fSStefano Zampini if (i != n_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D",n_vertices,i); 394088ebb749SStefano Zampini 394106656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3942019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 394306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 3944ad16ce7aSStefano Zampini ierr = MatDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 394506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 3946ad16ce7aSStefano Zampini ierr = MatDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 394706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 3948ad16ce7aSStefano Zampini ierr = MatDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 394906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 3950ad16ce7aSStefano Zampini ierr = MatDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 395106656605SStefano Zampini 395206656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 395306656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 39542958b453SStefano Zampini ierr = PCSetUp(pc_R);CHKERRQ(ierr); 395506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 395606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3957ffd830a3SStefano Zampini lda_rhs = n_R; 3958a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 39597ebab0bbSStefano Zampini if (isLU || isCHOL) { 396006656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3961b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3962df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3963d62866d3SStefano Zampini MatFactorType type; 3964d62866d3SStefano Zampini 3965df4d28bfSStefano Zampini F = reuse_solver->F; 39666816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3967d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 39687ebab0bbSStefano Zampini if (type == MAT_FACTOR_LU) isLU = PETSC_TRUE; 3969ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 397022db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 39717ebab0bbSStefano Zampini } else F = NULL; 397206656605SStefano Zampini 3973c58f9fdbSStefano Zampini /* determine if we can use a sparse right-hand side */ 3974c58f9fdbSStefano Zampini sparserhs = PETSC_FALSE; 3975c58f9fdbSStefano Zampini if (F) { 3976ea799195SBarry Smith MatSolverType solver; 3977c58f9fdbSStefano Zampini 39783ca39a21SBarry Smith ierr = MatFactorGetSolverType(F,&solver);CHKERRQ(ierr); 3979c58f9fdbSStefano Zampini ierr = PetscStrcmp(solver,MATSOLVERMUMPS,&sparserhs);CHKERRQ(ierr); 3980c58f9fdbSStefano Zampini } 3981c58f9fdbSStefano Zampini 3982ffd830a3SStefano Zampini /* allocate workspace */ 3983ffd830a3SStefano Zampini n = 0; 3984ffd830a3SStefano Zampini if (n_constraints) { 3985ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3986ffd830a3SStefano Zampini } 3987ffd830a3SStefano Zampini if (n_vertices) { 3988ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3989ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3990ffd830a3SStefano Zampini } 39912a3a6641Sstefano_zampini if (!pcbddc->symmetric_primal) { 39922a3a6641Sstefano_zampini n = PetscMax(2*lda_rhs*pcbddc->local_primal_size,n); 39932a3a6641Sstefano_zampini } 3994ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3995ffd830a3SStefano Zampini 39965cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 39975cbda25cSStefano Zampini dummy_vec = NULL; 39985cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 3999c72cccf8SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&dummy_vec);CHKERRQ(ierr); 4000c72cccf8SStefano Zampini ierr = VecSetSizes(dummy_vec,lda_rhs,PETSC_DECIDE);CHKERRQ(ierr); 4001c72cccf8SStefano Zampini ierr = VecSetType(dummy_vec,((PetscObject)pcis->vec1_N)->type_name);CHKERRQ(ierr); 40025cbda25cSStefano Zampini } 40035cbda25cSStefano Zampini 40047ebab0bbSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 40057ebab0bbSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 40067ebab0bbSStefano Zampini 400788ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 400888ebb749SStefano Zampini if (n_constraints) { 4009837cedc9SStefano Zampini Mat M3,C_B; 401006656605SStefano Zampini IS is_aux; 401180677318SStefano Zampini PetscScalar *array,*array2; 401206656605SStefano Zampini 401325084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 401425084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 40157dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 40167dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 401788ebb749SStefano Zampini 401880677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 401980677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 4020c58f9fdbSStefano Zampini if (!sparserhs) { 4021580bdb30SBarry Smith ierr = PetscArrayzero(work,lda_rhs*n_constraints);CHKERRQ(ierr); 402288ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 402306656605SStefano Zampini const PetscScalar *row_cmat_values; 402406656605SStefano Zampini const PetscInt *row_cmat_indices; 402506656605SStefano Zampini PetscInt size_of_constraint,j; 402688ebb749SStefano Zampini 402706656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 402806656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 4029ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 403006656605SStefano Zampini } 403106656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 403206656605SStefano Zampini } 4033c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&Brhs);CHKERRQ(ierr); 4034c58f9fdbSStefano Zampini } else { 4035c58f9fdbSStefano Zampini Mat tC_CR; 4036c58f9fdbSStefano Zampini 4037c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 4038c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 4039c58f9fdbSStefano Zampini PetscScalar *aa; 4040c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 4041c58f9fdbSStefano Zampini PetscBool done; 4042c58f9fdbSStefano Zampini 4043c58f9fdbSStefano Zampini ierr = MatGetRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 404413903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 4045c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(C_CR,&aa);CHKERRQ(ierr); 4046c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_constraints,lda_rhs,ii,jj,aa,&tC_CR);CHKERRQ(ierr); 4047c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 404813903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 4049c58f9fdbSStefano Zampini } else { 4050c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)C_CR);CHKERRQ(ierr); 4051c58f9fdbSStefano Zampini tC_CR = C_CR; 4052c58f9fdbSStefano Zampini } 4053c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tC_CR,&Brhs);CHKERRQ(ierr); 4054c58f9fdbSStefano Zampini ierr = MatDestroy(&tC_CR);CHKERRQ(ierr); 4055c58f9fdbSStefano Zampini } 4056ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 405706656605SStefano Zampini if (F) { 4058a3df083aSStefano Zampini if (need_benign_correction) { 4059df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4060a3df083aSStefano Zampini 406172b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 4062580bdb30SBarry Smith ierr = PetscArrayzero(reuse_solver->benign_save_vals,pcbddc->benign_n);CHKERRQ(ierr); 4063a3df083aSStefano Zampini } 4064c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,local_auxmat2_R);CHKERRQ(ierr); 4065a3df083aSStefano Zampini if (need_benign_correction) { 4066a3df083aSStefano Zampini PetscScalar *marr; 4067df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4068a3df083aSStefano Zampini 4069a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 40705cbda25cSStefano Zampini if (lda_rhs != n_R) { 40715cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 40725cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 40735cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 40745cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 40755cbda25cSStefano Zampini } 40765cbda25cSStefano Zampini } else { 4077a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 4078a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 40795cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4080a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4081a3df083aSStefano Zampini } 40825cbda25cSStefano Zampini } 4083a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 4084a3df083aSStefano Zampini } 408506656605SStefano Zampini } else { 408680677318SStefano Zampini PetscScalar *marr; 408780677318SStefano Zampini 408880677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 408906656605SStefano Zampini for (i=0;i<n_constraints;i++) { 4090ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4091ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 409206656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4093c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 409406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 409506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 409606656605SStefano Zampini } 409780677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 409806656605SStefano Zampini } 4099c58f9fdbSStefano Zampini if (sparserhs) { 4100c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 4101c58f9fdbSStefano Zampini } 4102c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 410380677318SStefano Zampini if (!pcbddc->switch_static) { 410480677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 410580677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 410680677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 410780677318SStefano Zampini for (i=0;i<n_constraints;i++) { 4108ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 410980677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 411080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 411180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 411280677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 411380677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 411480677318SStefano Zampini } 411580677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 411680677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 411772b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 411880677318SStefano Zampini } else { 4119ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4120ffd830a3SStefano Zampini IS dummy; 4121ffd830a3SStefano Zampini 4122ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 41237dae84e0SHong Zhang ierr = MatCreateSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 4124ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 4125ffd830a3SStefano Zampini } else { 412680677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 412780677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 4128ffd830a3SStefano Zampini } 412925084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 413080677318SStefano Zampini } 413180677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 413280677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR})^{-1} */ 413380677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 413480677318SStefano Zampini if (isCHOL) { 413580677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 413680677318SStefano Zampini } else { 413725084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 413880677318SStefano Zampini } 4139837cedc9SStefano Zampini ierr = MatSeqDenseInvertFactors_Private(M3);CHKERRQ(ierr); 414080677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 4141837cedc9SStefano Zampini ierr = MatMatMult(M3,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 414272b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 4143837cedc9SStefano Zampini ierr = MatCopy(M3,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 4144837cedc9SStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 4145f4ddd8eeSStefano Zampini } 4146fc227af8SStefano Zampini 4147fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 414888ebb749SStefano Zampini if (n_vertices) { 41497ebab0bbSStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 41507ebab0bbSStefano Zampini PetscBool oldpin; 41517ebab0bbSStefano Zampini #endif 41527ebab0bbSStefano Zampini PetscBool isaij; 415306656605SStefano Zampini IS is_aux; 41543a50541eSStefano Zampini 4155b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 41566816873aSStefano Zampini IS tis; 41576816873aSStefano Zampini 41586816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 41596816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 41606816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 41616816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 41626816873aSStefano Zampini } else { 41633a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 41646816873aSStefano Zampini } 41657ebab0bbSStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 4166b470e4b4SRichard Tran Mills oldpin = pcbddc->local_mat->boundtocpu; 41677ebab0bbSStefano Zampini #endif 4168b470e4b4SRichard Tran Mills ierr = MatBindToCPU(pcbddc->local_mat,PETSC_TRUE);CHKERRQ(ierr); 41697dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 41707dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 41717ebab0bbSStefano Zampini ierr = PetscObjectBaseTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isaij);CHKERRQ(ierr); 41727ebab0bbSStefano Zampini if (!isaij) { /* TODO REMOVE: MatMatMult(A_VR,A_RRmA_RV) below may raise an error */ 4173c58f9fdbSStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 41747ebab0bbSStefano Zampini } 41757dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 41767ebab0bbSStefano Zampini #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 4177b470e4b4SRichard Tran Mills ierr = MatBindToCPU(pcbddc->local_mat,oldpin);CHKERRQ(ierr); 41787ebab0bbSStefano Zampini #endif 417925084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 418088ebb749SStefano Zampini } 418188ebb749SStefano Zampini 418288ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 4183f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 418406656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 418506656605SStefano Zampini if (pcbddc->coarse_phi_D) { 418606656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 418706656605SStefano Zampini } 4188f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 418906656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 419006656605SStefano Zampini PetscScalar *marray; 419106656605SStefano Zampini 419206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 419306656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 4194f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 4195f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 4196f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 4197f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 4198f4ddd8eeSStefano Zampini } 4199f4ddd8eeSStefano Zampini } 420006656605SStefano Zampini 4201f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 4202a6e023c1Sstefano_zampini PetscScalar *marr; 420388ebb749SStefano Zampini 4204a6e023c1Sstefano_zampini /* memory size */ 420506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 4206a6e023c1Sstefano_zampini if (pcbddc->switch_static || pcbddc->dbg_flag) n += n_D*pcbddc->local_primal_size; 4207a6e023c1Sstefano_zampini if (!pcbddc->symmetric_primal) n *= 2; 4208a6e023c1Sstefano_zampini ierr = PetscCalloc1(n,&marr);CHKERRQ(ierr); 4209a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 4210a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 42118eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4212a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 4213a6e023c1Sstefano_zampini marr += n_D*pcbddc->local_primal_size; 421488ebb749SStefano Zampini } 42153301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4216a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 4217a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 42188eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4219a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 422088ebb749SStefano Zampini } 422188ebb749SStefano Zampini } else { 4222c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 4223c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 42241b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4225c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 4226c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 4227c0553b1fSStefano Zampini } 422888ebb749SStefano Zampini } 422906656605SStefano Zampini } 4230019a44ceSStefano Zampini 423106656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 42324f1b2e48SStefano Zampini p0_lidx_I = NULL; 42334f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 4234d12edf2fSStefano Zampini const PetscInt *idxs; 4235d12edf2fSStefano Zampini 4236d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 42374f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 42384f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 42394f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 42404f1b2e48SStefano Zampini } 4241d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 4242d12edf2fSStefano Zampini } 4243d16cbb6bSStefano Zampini 424406656605SStefano Zampini /* vertices */ 424506656605SStefano Zampini if (n_vertices) { 4246c58f9fdbSStefano Zampini PetscBool restoreavr = PETSC_FALSE; 424716f15bc4SStefano Zampini 4248af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 424904708bb6SStefano Zampini 425016f15bc4SStefano Zampini if (n_R) { 425114393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 425206656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 42531683a169SBarry Smith const PetscScalar *x; 42541683a169SBarry Smith PetscScalar *y; 425506656605SStefano Zampini 425621eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 425714393ed6SStefano Zampini if (need_benign_correction) { 425814393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 425914393ed6SStefano Zampini IS is_p0; 426014393ed6SStefano Zampini PetscInt *idxs_p0,n; 426114393ed6SStefano Zampini 426214393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 426314393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 426414393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 42656080607fSStefano 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); 426614393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 426714393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 42687dae84e0SHong Zhang ierr = MatCreateSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 426914393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 427014393ed6SStefano Zampini } 427114393ed6SStefano Zampini 4272c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4273c58f9fdbSStefano Zampini if (!sparserhs || need_benign_correction) { 4274ffd830a3SStefano Zampini if (lda_rhs == n_R) { 4275af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 4276ffd830a3SStefano Zampini } else { 4277ca92afb2SStefano Zampini PetscScalar *av,*array; 4278ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 4279ca92afb2SStefano Zampini PetscInt n; 4280ca92afb2SStefano Zampini PetscBool flg_row; 4281ffd830a3SStefano Zampini 4282ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 4283580bdb30SBarry Smith ierr = PetscArrayzero(array,lda_rhs*n_vertices);CHKERRQ(ierr); 42849d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 4285ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4286ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 4287ca92afb2SStefano Zampini for (i=0;i<n;i++) { 4288ca92afb2SStefano Zampini PetscInt j; 4289ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 4290ffd830a3SStefano Zampini } 4291ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4292ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4293ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 4294ffd830a3SStefano Zampini } 4295a3df083aSStefano Zampini if (need_benign_correction) { 4296df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4297a3df083aSStefano Zampini PetscScalar *marr; 4298a3df083aSStefano Zampini 4299a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 430014393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 430114393ed6SStefano Zampini 430214393ed6SStefano Zampini | 0 0 0 | (V) 430314393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 430414393ed6SStefano Zampini | 0 0 -1 | (p0) 430514393ed6SStefano Zampini 430614393ed6SStefano Zampini */ 4307df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 430814393ed6SStefano Zampini const PetscScalar *vals; 430914393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 431014393ed6SStefano Zampini PetscInt n,j,nz; 431114393ed6SStefano Zampini 4312df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4313df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 431414393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 431514393ed6SStefano Zampini for (j=0;j<n;j++) { 431614393ed6SStefano Zampini PetscScalar val = vals[j]; 431714393ed6SStefano Zampini PetscInt k,col = idxs[j]; 431814393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 431914393ed6SStefano Zampini } 432014393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4321df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 432214393ed6SStefano Zampini } 432372b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 432472b8c272SStefano Zampini } 4325c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RV);CHKERRQ(ierr); 4326c58f9fdbSStefano Zampini Brhs = A_RV; 4327c58f9fdbSStefano Zampini } else { 4328c58f9fdbSStefano Zampini Mat tA_RVT,A_RVT; 4329c58f9fdbSStefano Zampini 4330c58f9fdbSStefano Zampini if (!pcbddc->symmetric_primal) { 4331fb6280fbSStefano Zampini /* A_RV already scaled by -1 */ 4332c58f9fdbSStefano Zampini ierr = MatTranspose(A_RV,MAT_INITIAL_MATRIX,&A_RVT);CHKERRQ(ierr); 4333c58f9fdbSStefano Zampini } else { 4334c58f9fdbSStefano Zampini restoreavr = PETSC_TRUE; 4335c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4336c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_VR);CHKERRQ(ierr); 4337c58f9fdbSStefano Zampini A_RVT = A_VR; 4338c58f9fdbSStefano Zampini } 4339c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 4340c58f9fdbSStefano Zampini PetscScalar *aa; 4341c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 4342c58f9fdbSStefano Zampini PetscBool done; 4343c58f9fdbSStefano Zampini 4344c58f9fdbSStefano Zampini ierr = MatGetRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 434513903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 4346c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(A_RVT,&aa);CHKERRQ(ierr); 4347c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_vertices,lda_rhs,ii,jj,aa,&tA_RVT);CHKERRQ(ierr); 4348c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 434913903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 4350c58f9fdbSStefano Zampini } else { 4351c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RVT);CHKERRQ(ierr); 4352c58f9fdbSStefano Zampini tA_RVT = A_RVT; 4353c58f9fdbSStefano Zampini } 4354c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tA_RVT,&Brhs);CHKERRQ(ierr); 4355c58f9fdbSStefano Zampini ierr = MatDestroy(&tA_RVT);CHKERRQ(ierr); 4356c58f9fdbSStefano Zampini ierr = MatDestroy(&A_RVT);CHKERRQ(ierr); 4357c58f9fdbSStefano Zampini } 435872b8c272SStefano Zampini if (F) { 435914393ed6SStefano Zampini /* need to correct the rhs */ 436072b8c272SStefano Zampini if (need_benign_correction) { 436172b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 436272b8c272SStefano Zampini PetscScalar *marr; 436372b8c272SStefano Zampini 4364c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&marr);CHKERRQ(ierr); 43655cbda25cSStefano Zampini if (lda_rhs != n_R) { 43665cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 43675cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 43685cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 43695cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 43705cbda25cSStefano Zampini } 43715cbda25cSStefano Zampini } else { 4372a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4373a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 43745cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 4375a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4376a3df083aSStefano Zampini } 43775cbda25cSStefano Zampini } 4378c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&marr);CHKERRQ(ierr); 4379a3df083aSStefano Zampini } 4380c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,A_RRmA_RV);CHKERRQ(ierr); 4381c58f9fdbSStefano Zampini if (restoreavr) { 4382c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4383c58f9fdbSStefano Zampini } 438414393ed6SStefano Zampini /* need to correct the solution */ 4385a3df083aSStefano Zampini if (need_benign_correction) { 4386df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4387a3df083aSStefano Zampini PetscScalar *marr; 4388a3df083aSStefano Zampini 4389a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 43905cbda25cSStefano Zampini if (lda_rhs != n_R) { 43915cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 43925cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 43935cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 43945cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 43955cbda25cSStefano Zampini } 43965cbda25cSStefano Zampini } else { 4397a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4398a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 43995cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4400a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4401a3df083aSStefano Zampini } 44025cbda25cSStefano Zampini } 4403a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 4404a3df083aSStefano Zampini } 440506656605SStefano Zampini } else { 4406c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&y);CHKERRQ(ierr); 440706656605SStefano Zampini for (i=0;i<n_vertices;i++) { 4408ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 4409ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 441006656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4411c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 441206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 441306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 441406656605SStefano Zampini } 4415c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&y);CHKERRQ(ierr); 441606656605SStefano Zampini } 441780677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4418c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 4419ffd830a3SStefano Zampini /* S_VV and S_CV */ 442006656605SStefano Zampini if (n_constraints) { 442106656605SStefano Zampini Mat B; 442280677318SStefano Zampini 4423580bdb30SBarry Smith ierr = PetscArrayzero(work+lda_rhs*n_vertices,n_B*n_vertices);CHKERRQ(ierr); 442480677318SStefano Zampini for (i=0;i<n_vertices;i++) { 4425ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4426ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 442780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 442880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 442980677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 443080677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 443180677318SStefano Zampini } 4432ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 44334222ddf1SHong Zhang /* Reuse dense S_C = pcbddc->local_auxmat1 * B */ 44344222ddf1SHong Zhang ierr = MatProductCreateWithMat(pcbddc->local_auxmat1,B,NULL,S_CV);CHKERRQ(ierr); 44354222ddf1SHong Zhang ierr = MatProductSetType(S_CV,MATPRODUCT_AB);CHKERRQ(ierr); 44364222ddf1SHong Zhang ierr = MatProductSetFromOptions(S_CV);CHKERRQ(ierr); 44376718818eSStefano Zampini ierr = MatProductSymbolic(S_CV);CHKERRQ(ierr); 44384222ddf1SHong Zhang ierr = MatProductNumeric(S_CV);CHKERRQ(ierr); 4439a961b312SStefano Zampini ierr = MatProductClear(S_CV);CHKERRQ(ierr); 44404222ddf1SHong Zhang 444180677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 4442ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 44434222ddf1SHong Zhang /* Reuse B = local_auxmat2_R * S_CV */ 44444222ddf1SHong Zhang ierr = MatProductCreateWithMat(local_auxmat2_R,S_CV,NULL,B);CHKERRQ(ierr); 44454222ddf1SHong Zhang ierr = MatProductSetType(B,MATPRODUCT_AB);CHKERRQ(ierr); 44464222ddf1SHong Zhang ierr = MatProductSetFromOptions(B);CHKERRQ(ierr); 44476718818eSStefano Zampini ierr = MatProductSymbolic(B);CHKERRQ(ierr); 44484222ddf1SHong Zhang ierr = MatProductNumeric(B);CHKERRQ(ierr); 44494222ddf1SHong Zhang 445006656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 4451ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 4452ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 445306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 445406656605SStefano Zampini } 4455ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4456ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 4457ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4458ad16ce7aSStefano Zampini ierr = MatDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 4459ffd830a3SStefano Zampini } 446006656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 446114393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 446214393ed6SStefano Zampini if (need_benign_correction) { 4463df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 446414393ed6SStefano Zampini PetscScalar *marr,*sums; 446514393ed6SStefano Zampini 446614393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 4467f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 4468df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 446914393ed6SStefano Zampini const PetscScalar *vals; 447014393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 447114393ed6SStefano Zampini PetscInt n,j,nz; 447214393ed6SStefano Zampini 4473df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4474df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 447514393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 447614393ed6SStefano Zampini PetscInt k; 447714393ed6SStefano Zampini sums[j] = 0.; 447814393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 447914393ed6SStefano Zampini } 448014393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 448114393ed6SStefano Zampini for (j=0;j<n;j++) { 448214393ed6SStefano Zampini PetscScalar val = vals[j]; 448314393ed6SStefano Zampini PetscInt k; 448414393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 448514393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 448614393ed6SStefano Zampini } 448714393ed6SStefano Zampini } 448814393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4489df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 449014393ed6SStefano Zampini } 449114393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 4492f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 449314393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 449414393ed6SStefano Zampini } 449580677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 449606656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 44971683a169SBarry Smith ierr = MatDenseGetArrayRead(A_VV,&x);CHKERRQ(ierr); 449806656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 449906656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 45001683a169SBarry Smith ierr = MatDenseRestoreArrayRead(A_VV,&x);CHKERRQ(ierr); 450106656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 450206656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4503d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 4504019a44ceSStefano Zampini } else { 4505d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4506d16cbb6bSStefano Zampini } 450721eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 4508d16cbb6bSStefano Zampini 450906656605SStefano Zampini /* coarse basis functions */ 451006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 451116f15bc4SStefano Zampini PetscScalar *y; 451216f15bc4SStefano Zampini 4513ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 451406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 451506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 451606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 451706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 451806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 451906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 452006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 452106656605SStefano Zampini 452206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 45234f1b2e48SStefano Zampini PetscInt j; 45244f1b2e48SStefano Zampini 452506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 452606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 452706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 452806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 452906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 45304f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 453106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 453206656605SStefano Zampini } 453306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 453406656605SStefano Zampini } 453504708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 453604708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 453706656605SStefano Zampini } 45385cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 453906656605SStefano Zampini 454006656605SStefano Zampini if (n_constraints) { 454106656605SStefano Zampini Mat B; 454206656605SStefano Zampini 4543ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 454406656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 4545a961b312SStefano Zampini ierr = MatProductCreateWithMat(local_auxmat2_R,S_CC,NULL,B);CHKERRQ(ierr); 4546a961b312SStefano Zampini ierr = MatProductSetType(B,MATPRODUCT_AB);CHKERRQ(ierr); 4547a961b312SStefano Zampini ierr = MatProductSetFromOptions(B);CHKERRQ(ierr); 45486718818eSStefano Zampini ierr = MatProductSymbolic(B);CHKERRQ(ierr); 4549a961b312SStefano Zampini ierr = MatProductNumeric(B);CHKERRQ(ierr); 4550a961b312SStefano Zampini 455106656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 455206656605SStefano Zampini if (n_vertices) { 455303dfb2d7SStefano Zampini if (isCHOL || need_benign_correction) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 455480677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 455580677318SStefano Zampini } else { 455680677318SStefano Zampini Mat S_VCt; 455780677318SStefano Zampini 4558ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4559ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 456072b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 4561ad16ce7aSStefano Zampini ierr = MatDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 4562ffd830a3SStefano Zampini } 456380677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 456480677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 456580677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 456680677318SStefano Zampini } 456706656605SStefano Zampini } 456806656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 456906656605SStefano Zampini /* coarse basis functions */ 457006656605SStefano Zampini for (i=0;i<n_constraints;i++) { 457106656605SStefano Zampini PetscScalar *y; 457206656605SStefano Zampini 4573ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 457406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 457506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 457606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 457706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 457806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 457906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 458006656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 45814f1b2e48SStefano Zampini PetscInt j; 45824f1b2e48SStefano Zampini 458306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 458406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 458506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 458606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 458706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 45884f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 458906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 459006656605SStefano Zampini } 459106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 459206656605SStefano Zampini } 459306656605SStefano Zampini } 459480677318SStefano Zampini if (n_constraints) { 459580677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 459680677318SStefano Zampini } 45974f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 459872b8c272SStefano Zampini 459972b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 460072b8c272SStefano Zampini if (pcbddc->benign_n) { 460172b8c272SStefano Zampini Mat B0_B,B0_BPHI; 460272b8c272SStefano Zampini IS is_dummy; 46031683a169SBarry Smith const PetscScalar *data; 460472b8c272SStefano Zampini PetscInt j; 460572b8c272SStefano Zampini 460672b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 46077dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 460872b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 460972b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 461086c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 46111683a169SBarry Smith ierr = MatDenseGetArrayRead(B0_BPHI,&data);CHKERRQ(ierr); 461272b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 461372b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 461472b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 461572b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 461672b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 461772b8c272SStefano Zampini } 461872b8c272SStefano Zampini } 46191683a169SBarry Smith ierr = MatDenseRestoreArrayRead(B0_BPHI,&data);CHKERRQ(ierr); 462072b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 462172b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 462272b8c272SStefano Zampini } 4623019a44ceSStefano Zampini 462406656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 46253301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4626ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 4627ffd830a3SStefano Zampini PetscScalar *marray; 462806656605SStefano Zampini 462906656605SStefano Zampini if (n_constraints) { 4630ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 463106656605SStefano Zampini 4632abc8f43dSstefano_zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 463306656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 4634ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 463516f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 463606656605SStefano Zampini if (n_vertices) { 4637ffd830a3SStefano Zampini Mat S_VCT; 463806656605SStefano Zampini 463906656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 4640ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 464116f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 464206656605SStefano Zampini } 4643ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 46445b782168SStefano Zampini } else { 46455b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 464606656605SStefano Zampini } 464716f15bc4SStefano Zampini if (n_vertices && n_R) { 4648ffd830a3SStefano Zampini PetscScalar *av,*marray; 4649ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 4650ffd830a3SStefano Zampini PetscInt n; 4651ffd830a3SStefano Zampini PetscBool flg_row; 465206656605SStefano Zampini 4653ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 4654af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4655ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4656ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 4657ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4658ffd830a3SStefano Zampini for (i=0;i<n;i++) { 4659ffd830a3SStefano Zampini PetscInt j; 4660ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 4661ffd830a3SStefano Zampini } 4662ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4663ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4664ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 466506656605SStefano Zampini } 466606656605SStefano Zampini 4667ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 4668abc8f43dSstefano_zampini if (n_vertices) { 4669ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4670ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 4671ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 4672ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 467306656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4674c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 467506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 467606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 467706656605SStefano Zampini } 4678ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4679abc8f43dSstefano_zampini } 46805b782168SStefano Zampini if (B_C) { 4681ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 4682ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 4683ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 4684ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 4685ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4686c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 4687ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4688ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 468906656605SStefano Zampini } 4690ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 46915b782168SStefano Zampini } 469206656605SStefano Zampini /* coarse basis functions */ 469306656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 469406656605SStefano Zampini PetscScalar *y; 469506656605SStefano Zampini 4696ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 469706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 469806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 469906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 470006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 470106656605SStefano Zampini if (i<n_vertices) { 470206656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 470306656605SStefano Zampini } 470406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 470506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 470606656605SStefano Zampini 470706656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 470806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 470906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 471006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 471106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 471206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 471306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 471406656605SStefano Zampini } 471506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 471606656605SStefano Zampini } 4717ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 4718ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 471906656605SStefano Zampini } 4720a6e023c1Sstefano_zampini 4721d62866d3SStefano Zampini /* free memory */ 472288ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 472306656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 472406656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 472506656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 472606656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 4727d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4728d62866d3SStefano Zampini if (n_vertices) { 4729d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 4730d62866d3SStefano Zampini } 4731d62866d3SStefano Zampini if (n_constraints) { 4732d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 4733d62866d3SStefano Zampini } 47348ead10e4SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CorrectionSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 47358ead10e4SStefano Zampini 473688ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 473788ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 473888ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 4739d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 474088ebb749SStefano Zampini Mat coarse_sub_mat; 474125084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 474288ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 474388ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 474488ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 47458bec7fa6SStefano Zampini Mat C_B,CPHI; 47468bec7fa6SStefano Zampini IS is_dummy; 47478bec7fa6SStefano Zampini Vec mones; 474888ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 474988ebb749SStefano Zampini PetscReal real_value; 475088ebb749SStefano Zampini 4751a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 4752a3df083aSStefano Zampini Mat A; 4753a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 47547dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 47557dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 47567dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 47577dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4758a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 4759a3df083aSStefano Zampini } else { 476088ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 476188ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 476288ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 476388ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4764a3df083aSStefano Zampini } 476588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 476688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 4767ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 476888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 476988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 477088ebb749SStefano Zampini } 477188ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 477288ebb749SStefano Zampini 477325084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 47743301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 477525084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4776ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 477788ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 477888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 477988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 478088ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 478188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 478288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 478388ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 478488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 478588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 478688ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 478788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 478888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 478988ebb749SStefano Zampini } else { 479088ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 479188ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 479288ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 479388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 479488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 479588ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 479688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 479788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 479888ebb749SStefano Zampini } 479988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 480088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 480188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4802511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 48034f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4804fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 48051683a169SBarry Smith const PetscScalar *data2; 48061683a169SBarry Smith PetscScalar *data; 48074f1b2e48SStefano Zampini PetscInt j; 4808d12edf2fSStefano Zampini 48094f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 48107dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4811d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 481286c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4813d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 48141683a169SBarry Smith ierr = MatDenseGetArrayRead(B0_BPHI,&data2);CHKERRQ(ierr); 48154f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 48164f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4817d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 48184f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 48194f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 48204f1b2e48SStefano Zampini } 4821d12edf2fSStefano Zampini } 4822d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 48231683a169SBarry Smith ierr = MatDenseRestoreArrayRead(B0_BPHI,&data2);CHKERRQ(ierr); 4824d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4825d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4826d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4827d12edf2fSStefano Zampini } 4828d12edf2fSStefano Zampini #if 0 4829d12edf2fSStefano Zampini { 4830d12edf2fSStefano Zampini PetscViewer viewer; 4831d12edf2fSStefano Zampini char filename[256]; 4832ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4833d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4834a7414863SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4835ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4836ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4837ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4838d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 4839a7414863SStefano Zampini if (pcbddc->coarse_phi_B) { 4840ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4841ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 484272b8c272SStefano Zampini } 4843ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4844ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4845ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4846ffd830a3SStefano Zampini } 4847ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4848ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4849ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4850ffd830a3SStefano Zampini } 485172b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4852ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4853ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4854ffd830a3SStefano Zampini } 4855fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->local_mat,"A");CHKERRQ(ierr); 4856fb6280fbSStefano Zampini ierr = MatView(pcbddc->local_mat,viewer);CHKERRQ(ierr); 4857fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->ConstraintMatrix,"C");CHKERRQ(ierr); 4858fb6280fbSStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,viewer);CHKERRQ(ierr); 4859fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_I_local,"I");CHKERRQ(ierr); 4860fb6280fbSStefano Zampini ierr = ISView(pcis->is_I_local,viewer);CHKERRQ(ierr); 4861fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_B_local,"B");CHKERRQ(ierr); 4862fb6280fbSStefano Zampini ierr = ISView(pcis->is_B_local,viewer);CHKERRQ(ierr); 4863fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->is_R_local,"R");CHKERRQ(ierr); 4864fb6280fbSStefano Zampini ierr = ISView(pcbddc->is_R_local,viewer);CHKERRQ(ierr); 4865d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4866d12edf2fSStefano Zampini } 4867d12edf2fSStefano Zampini #endif 486881d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 48698bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 48701575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 487106656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 48728bec7fa6SStefano Zampini 48738bec7fa6SStefano Zampini /* check constraints */ 4874a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 48757dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 48764f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 48778bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4878a00504b5SStefano Zampini } else { 4879a00504b5SStefano Zampini PetscScalar *data; 4880a00504b5SStefano Zampini Mat tmat; 4881a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4882a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4883a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4884a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4885a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4886a00504b5SStefano Zampini } 48878bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 48888bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 48898bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 48908bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4891bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4892ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4893bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4894bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4895bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4896bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4897bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 489888ebb749SStefano Zampini } 48998bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 49008bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 49018bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 49028bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 490325084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 490488ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 490588ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 490688ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 490788ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 490888ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 490988ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 491088ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 491188ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 491288ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 491388ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4914ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 491588ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 491688ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 491788ebb749SStefano Zampini } 491888ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 491988ebb749SStefano Zampini } 49207ebab0bbSStefano Zampini /* FINAL CUDA support (we cannot currently mix viennacl and cuda vectors */ 49217ebab0bbSStefano Zampini { 49227ebab0bbSStefano Zampini PetscBool gpu; 49237ebab0bbSStefano Zampini 49247ebab0bbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->vec1_N,VECSEQCUDA,&gpu);CHKERRQ(ierr); 49257ebab0bbSStefano Zampini if (gpu) { 49267ebab0bbSStefano Zampini if (pcbddc->local_auxmat1) { 49277ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->local_auxmat1,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->local_auxmat1);CHKERRQ(ierr); 49287ebab0bbSStefano Zampini } 49297ebab0bbSStefano Zampini if (pcbddc->local_auxmat2) { 49307ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->local_auxmat2,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 49317ebab0bbSStefano Zampini } 49327ebab0bbSStefano Zampini if (pcbddc->coarse_phi_B) { 49337ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 49347ebab0bbSStefano Zampini } 49357ebab0bbSStefano Zampini if (pcbddc->coarse_phi_D) { 49367ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 49377ebab0bbSStefano Zampini } 49387ebab0bbSStefano Zampini if (pcbddc->coarse_psi_B) { 49397ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 49407ebab0bbSStefano Zampini } 49417ebab0bbSStefano Zampini if (pcbddc->coarse_psi_D) { 49427ebab0bbSStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,MATSEQDENSECUDA,MAT_INPLACE_MATRIX,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 49437ebab0bbSStefano Zampini } 49447ebab0bbSStefano Zampini } 49457ebab0bbSStefano Zampini } 49468629588bSStefano Zampini /* get back data */ 49478629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 494888ebb749SStefano Zampini PetscFunctionReturn(0); 494988ebb749SStefano Zampini } 495088ebb749SStefano Zampini 49517dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4952aa0d41d4SStefano Zampini { 4953d65f70fdSStefano Zampini Mat *work_mat; 4954d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4955d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4956c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4957aa0d41d4SStefano Zampini PetscErrorCode ierr; 4958aa0d41d4SStefano Zampini 4959aa0d41d4SStefano Zampini PetscFunctionBegin; 4960d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4961d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4962d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4963d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4964aa0d41d4SStefano Zampini 4965d65f70fdSStefano Zampini if (!rsorted) { 4966906d46d4SStefano Zampini const PetscInt *idxs; 4967906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4968aa0d41d4SStefano Zampini 4969d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4970d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4971d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4972d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4973aa0d41d4SStefano Zampini } 4974d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4975d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4976d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4977d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4978aa0d41d4SStefano Zampini } 4979d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4980d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4981d65f70fdSStefano Zampini } else { 4982d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4983d65f70fdSStefano Zampini isrow_s = isrow; 4984aa0d41d4SStefano Zampini } 4985906d46d4SStefano Zampini 4986d65f70fdSStefano Zampini if (!csorted) { 4987d65f70fdSStefano Zampini if (isrow == iscol) { 4988d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4989d65f70fdSStefano Zampini iscol_s = isrow_s; 4990d65f70fdSStefano Zampini } else { 4991d65f70fdSStefano Zampini const PetscInt *idxs; 4992d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4993906d46d4SStefano Zampini 4994d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4995d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4996d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4997d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4998d65f70fdSStefano Zampini } 4999d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 5000d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 5001d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 5002d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 5003d65f70fdSStefano Zampini } 5004d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 5005d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 5006d65f70fdSStefano Zampini } 5007d65f70fdSStefano Zampini } else { 5008d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 5009d65f70fdSStefano Zampini iscol_s = iscol; 5010d65f70fdSStefano Zampini } 5011d65f70fdSStefano Zampini 50127dae84e0SHong Zhang ierr = MatCreateSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 5013d65f70fdSStefano Zampini 5014d65f70fdSStefano Zampini if (!rsorted || !csorted) { 5015906d46d4SStefano Zampini Mat new_mat; 5016d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 5017906d46d4SStefano Zampini 5018d65f70fdSStefano Zampini if (!rsorted) { 5019d65f70fdSStefano Zampini PetscInt *idxs_r,i; 5020d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 5021d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 5022d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 5023906d46d4SStefano Zampini } 5024d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 5025d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 5026d65f70fdSStefano Zampini } else { 5027d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 5028906d46d4SStefano Zampini } 5029d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 5030d65f70fdSStefano Zampini 5031d65f70fdSStefano Zampini if (!csorted) { 5032d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 5033d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 5034d65f70fdSStefano Zampini is_perm_c = is_perm_r; 5035d65f70fdSStefano Zampini } else { 5036d65f70fdSStefano Zampini PetscInt *idxs_c,i; 5037f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 5038d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 5039d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 5040d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 5041d65f70fdSStefano Zampini } 5042d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 5043d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 5044d65f70fdSStefano Zampini } 5045d65f70fdSStefano Zampini } else { 5046d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 5047d65f70fdSStefano Zampini } 5048d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 5049d65f70fdSStefano Zampini 5050d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 5051d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 5052d65f70fdSStefano Zampini work_mat[0] = new_mat; 5053d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 5054d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 5055d65f70fdSStefano Zampini } 5056d65f70fdSStefano Zampini 5057d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 5058d65f70fdSStefano Zampini *B = work_mat[0]; 5059d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 5060d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 5061d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 5062d65f70fdSStefano Zampini PetscFunctionReturn(0); 5063d65f70fdSStefano Zampini } 5064d65f70fdSStefano Zampini 50655e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 5066aa0d41d4SStefano Zampini { 5067aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 50685e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5069022d8d2bSstefano_zampini Mat new_mat,lA; 50705e8657edSStefano Zampini IS is_local,is_global; 5071d65f70fdSStefano Zampini PetscInt local_size; 5072d65f70fdSStefano Zampini PetscBool isseqaij; 5073aa0d41d4SStefano Zampini PetscErrorCode ierr; 5074aa0d41d4SStefano Zampini 5075aa0d41d4SStefano Zampini PetscFunctionBegin; 5076aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 50775e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 50785e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 5079b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 5080aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 50817dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 5082aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 5083906d46d4SStefano Zampini 5084906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 5085906d46d4SStefano Zampini Vec x,x_change; 5086906d46d4SStefano Zampini PetscReal error; 5087906d46d4SStefano Zampini 50885e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 5089906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 50905e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 5091e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5092e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5093d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 509488428137SStefano Zampini if (!pcbddc->change_interior) { 509588428137SStefano Zampini const PetscScalar *x,*y,*v; 509688428137SStefano Zampini PetscReal lerror = 0.; 509788428137SStefano Zampini PetscInt i; 509888428137SStefano Zampini 509988428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 510088428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 510188428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 510288428137SStefano Zampini for (i=0;i<local_size;i++) 510388428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 510488428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 510588428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 510688428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 510788428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 510888428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5109637e8532SStefano Zampini if (error > PETSC_SMALL) { 5110637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 51116080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on I: %1.6e",error); 5112637e8532SStefano Zampini } else { 51136080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on I: %1.6e",error); 5114637e8532SStefano Zampini } 5115637e8532SStefano Zampini } 511688428137SStefano Zampini } 5117e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5118e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5119906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 5120906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 5121637e8532SStefano Zampini if (error > PETSC_SMALL) { 5122637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 51236080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e",error); 5124637e8532SStefano Zampini } else { 51256080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on N: %1.6e",error); 5126637e8532SStefano Zampini } 5127637e8532SStefano Zampini } 5128906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 5129906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 5130906d46d4SStefano Zampini } 5131906d46d4SStefano Zampini 5132022d8d2bSstefano_zampini /* lA is present if we are setting up an inner BDDC for a saddle point FETI-DP */ 5133022d8d2bSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 5134022d8d2bSstefano_zampini 513522d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 51367ebab0bbSStefano Zampini ierr = PetscObjectBaseTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 513722d5777bSStefano Zampini if (isseqaij) { 5138a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 5139a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 5140022d8d2bSstefano_zampini if (lA) { 5141022d8d2bSstefano_zampini Mat work; 5142022d8d2bSstefano_zampini ierr = MatPtAP(lA,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 5143022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 5144022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 5145022d8d2bSstefano_zampini } 5146aa0d41d4SStefano Zampini } else { 5147a00504b5SStefano Zampini Mat work_mat; 51481cf9b237SStefano Zampini 5149a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 5150aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 5151a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 51521d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 5153022d8d2bSstefano_zampini if (lA) { 5154022d8d2bSstefano_zampini Mat work; 5155022d8d2bSstefano_zampini ierr = MatConvert(lA,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 5156022d8d2bSstefano_zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 5157022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 5158022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 5159022d8d2bSstefano_zampini } 5160aa0d41d4SStefano Zampini } 51613301b35fSStefano Zampini if (matis->A->symmetric_set) { 51623301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 5163e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 51643301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 5165e496cd5dSStefano Zampini #endif 51663301b35fSStefano Zampini } 5167d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 5168aa0d41d4SStefano Zampini PetscFunctionReturn(0); 5169aa0d41d4SStefano Zampini } 5170aa0d41d4SStefano Zampini 51718ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 5172a64d13efSStefano Zampini { 5173a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5174a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5175d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 517653892102SStefano Zampini PetscInt *idx_R_local=NULL; 51773a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 51783a50541eSStefano Zampini PetscInt vbs,bs; 51796816873aSStefano Zampini PetscBT bitmask=NULL; 5180a64d13efSStefano Zampini PetscErrorCode ierr; 5181a64d13efSStefano Zampini 5182a64d13efSStefano Zampini PetscFunctionBegin; 5183b23d619eSStefano Zampini /* 5184b23d619eSStefano Zampini No need to setup local scatters if 5185b23d619eSStefano Zampini - primal space is unchanged 5186b23d619eSStefano Zampini AND 5187b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 5188b23d619eSStefano Zampini AND 5189b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 5190b23d619eSStefano Zampini */ 5191b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 5192f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 5193f4ddd8eeSStefano Zampini } 5194f4ddd8eeSStefano Zampini /* destroy old objects */ 5195f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 5196f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 5197f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 5198a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 5199b371cd4fSStefano Zampini n_B = pcis->n_B; 5200b371cd4fSStefano Zampini n_D = pcis->n - n_B; 5201b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 52023a50541eSStefano Zampini 5203a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 52046816873aSStefano Zampini 520553892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 5206b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 5207854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 5208a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 5209a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 52100e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 5211a64d13efSStefano Zampini } 5212a64d13efSStefano Zampini 5213a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 52144641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 52156816873aSStefano Zampini idx_R_local[n_R++] = i; 5216a64d13efSStefano Zampini } 5217a64d13efSStefano Zampini } 5218df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 5219df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 52206816873aSStefano Zampini 5221df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5222df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 52236816873aSStefano Zampini } 52243a50541eSStefano Zampini 52253a50541eSStefano Zampini /* Block code */ 52263a50541eSStefano Zampini vbs = 1; 52273a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 52283a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 52293a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 52303a50541eSStefano Zampini PetscInt *vary; 5231b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 5232785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 5233580bdb30SBarry Smith ierr = PetscArrayzero(vary,pcis->n/bs);CHKERRQ(ierr); 5234d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 5235d3df7717SStefano 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 */ 52360e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 5237d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 52383a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 52393a50541eSStefano Zampini is_blocked = PETSC_FALSE; 52403a50541eSStefano Zampini break; 52413a50541eSStefano Zampini } 52423a50541eSStefano Zampini } 5243d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 5244d3df7717SStefano Zampini } else { 5245d3df7717SStefano Zampini /* Verify directly the R set */ 5246d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 5247d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 5248d3df7717SStefano Zampini for (j=1; j<bs; j++) { 5249d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 5250d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 5251d3df7717SStefano Zampini break; 5252d3df7717SStefano Zampini } 5253d3df7717SStefano Zampini } 5254d3df7717SStefano Zampini } 5255d3df7717SStefano Zampini } 52563a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 52573a50541eSStefano Zampini vbs = bs; 52583a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 52593a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 52603a50541eSStefano Zampini } 52613a50541eSStefano Zampini } 52623a50541eSStefano Zampini } 52633a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 5264b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5265df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 526653892102SStefano Zampini 5267df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5268df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 526953892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 5270df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 527153892102SStefano Zampini } else { 52723a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 527353892102SStefano Zampini } 5274a64d13efSStefano Zampini 5275a64d13efSStefano Zampini /* print some info if requested */ 5276a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 5277a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5278a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 52791575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5280a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 52816080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %D, dirichlet_size = %D, boundary_size = %D\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 52826080607fSStefano 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); 5283a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5284a64d13efSStefano Zampini } 5285a64d13efSStefano Zampini 5286a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 5287b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 52886816873aSStefano Zampini IS is_aux1,is_aux2; 52896816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 52906816873aSStefano Zampini 52913a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5292854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 5293854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 5294a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 52954641a718SStefano Zampini for (i=0; i<n_D; i++) { 52964641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 52974641a718SStefano Zampini } 5298a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5299a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 53004641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 53014641a718SStefano Zampini aux_array1[j++] = i; 5302a64d13efSStefano Zampini } 5303a64d13efSStefano Zampini } 5304a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 5305a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5306a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 53074641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 53084641a718SStefano Zampini aux_array2[j++] = i; 5309a64d13efSStefano Zampini } 5310a64d13efSStefano Zampini } 5311a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5312a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 53139448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 5314a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 5315a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 5316a64d13efSStefano Zampini 53178eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 5318785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 5319a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 53204641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 53214641a718SStefano Zampini aux_array1[j++] = i; 5322a64d13efSStefano Zampini } 5323a64d13efSStefano Zampini } 5324a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 53259448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 5326a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 5327a64d13efSStefano Zampini } 53284641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 53293a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5330d62866d3SStefano Zampini } else { 5331df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 53326816873aSStefano Zampini IS tis; 53336816873aSStefano Zampini PetscInt schur_size; 53346816873aSStefano Zampini 5335df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 53366816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 53379448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 53386816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 53396816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 53406816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 53419448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 53426816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 5343d62866d3SStefano Zampini } 5344d62866d3SStefano Zampini } 5345a64d13efSStefano Zampini PetscFunctionReturn(0); 5346a64d13efSStefano Zampini } 5347a64d13efSStefano Zampini 53486d9e27e4SStefano Zampini static PetscErrorCode MatNullSpacePropagateAny_Private(Mat A, IS is, Mat B) 534992cccca0SStefano Zampini { 535092cccca0SStefano Zampini MatNullSpace NullSpace; 535192cccca0SStefano Zampini Mat dmat; 535292cccca0SStefano Zampini const Vec *nullvecs; 535392cccca0SStefano Zampini Vec v,v2,*nullvecs2; 53546d9e27e4SStefano Zampini VecScatter sct = NULL; 5355eb06acf8SStefano Zampini PetscContainer c; 5356eb06acf8SStefano Zampini PetscScalar *ddata; 5357295df10fSStefano Zampini PetscInt k,nnsp_size,bsiz,bsiz2,n,N,bs; 535892cccca0SStefano Zampini PetscBool nnsp_has_cnst; 535992cccca0SStefano Zampini PetscErrorCode ierr; 536092cccca0SStefano Zampini 536192cccca0SStefano Zampini PetscFunctionBegin; 53626d9e27e4SStefano Zampini if (!is && !B) { /* MATIS */ 53636d9e27e4SStefano Zampini Mat_IS* matis = (Mat_IS*)A->data; 53646d9e27e4SStefano Zampini 53656d9e27e4SStefano Zampini if (!B) { 53666d9e27e4SStefano Zampini ierr = MatISGetLocalMat(A,&B);CHKERRQ(ierr); 53676d9e27e4SStefano Zampini } 53686d9e27e4SStefano Zampini sct = matis->cctx; 53696d9e27e4SStefano Zampini ierr = PetscObjectReference((PetscObject)sct);CHKERRQ(ierr); 53706d9e27e4SStefano Zampini } else { 537192cccca0SStefano Zampini ierr = MatGetNullSpace(B,&NullSpace);CHKERRQ(ierr); 537292cccca0SStefano Zampini if (!NullSpace) { 537392cccca0SStefano Zampini ierr = MatGetNearNullSpace(B,&NullSpace);CHKERRQ(ierr); 537492cccca0SStefano Zampini } 537592cccca0SStefano Zampini if (NullSpace) PetscFunctionReturn(0); 53766d9e27e4SStefano Zampini } 537792cccca0SStefano Zampini ierr = MatGetNullSpace(A,&NullSpace);CHKERRQ(ierr); 537892cccca0SStefano Zampini if (!NullSpace) { 537992cccca0SStefano Zampini ierr = MatGetNearNullSpace(A,&NullSpace);CHKERRQ(ierr); 538092cccca0SStefano Zampini } 538192cccca0SStefano Zampini if (!NullSpace) PetscFunctionReturn(0); 53826d9e27e4SStefano Zampini 538392cccca0SStefano Zampini ierr = MatCreateVecs(A,&v,NULL);CHKERRQ(ierr); 538492cccca0SStefano Zampini ierr = MatCreateVecs(B,&v2,NULL);CHKERRQ(ierr); 53856d9e27e4SStefano Zampini if (!sct) { 53869448b7f1SJunchao Zhang ierr = VecScatterCreate(v,is,v2,NULL,&sct);CHKERRQ(ierr); 53876d9e27e4SStefano Zampini } 538892cccca0SStefano Zampini ierr = MatNullSpaceGetVecs(NullSpace,&nnsp_has_cnst,&nnsp_size,(const Vec**)&nullvecs);CHKERRQ(ierr); 5389295df10fSStefano Zampini bsiz = bsiz2 = nnsp_size+!!nnsp_has_cnst; 539092cccca0SStefano Zampini ierr = PetscMalloc1(bsiz,&nullvecs2);CHKERRQ(ierr); 539192cccca0SStefano Zampini ierr = VecGetBlockSize(v2,&bs);CHKERRQ(ierr); 539292cccca0SStefano Zampini ierr = VecGetSize(v2,&N);CHKERRQ(ierr); 539392cccca0SStefano Zampini ierr = VecGetLocalSize(v2,&n);CHKERRQ(ierr); 5394eb06acf8SStefano Zampini ierr = PetscMalloc1(n*bsiz,&ddata);CHKERRQ(ierr); 539592cccca0SStefano Zampini for (k=0;k<nnsp_size;k++) { 5396eb06acf8SStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)B),bs,n,N,ddata + n*k,&nullvecs2[k]);CHKERRQ(ierr); 539792cccca0SStefano Zampini ierr = VecScatterBegin(sct,nullvecs[k],nullvecs2[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 539892cccca0SStefano Zampini ierr = VecScatterEnd(sct,nullvecs[k],nullvecs2[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 539992cccca0SStefano Zampini } 540092cccca0SStefano Zampini if (nnsp_has_cnst) { 5401eb06acf8SStefano Zampini ierr = VecCreateMPIWithArray(PetscObjectComm((PetscObject)B),bs,n,N,ddata + n*nnsp_size,&nullvecs2[nnsp_size]);CHKERRQ(ierr); 540292cccca0SStefano Zampini ierr = VecSet(nullvecs2[nnsp_size],1.0);CHKERRQ(ierr); 540392cccca0SStefano Zampini } 5404295df10fSStefano Zampini ierr = PCBDDCOrthonormalizeVecs(&bsiz2,nullvecs2);CHKERRQ(ierr); 5405295df10fSStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)B),PETSC_FALSE,bsiz2,nullvecs2,&NullSpace);CHKERRQ(ierr); 5406295df10fSStefano Zampini 5407eb06acf8SStefano Zampini ierr = MatCreateDense(PetscObjectComm((PetscObject)B),n,PETSC_DECIDE,N,bsiz2,ddata,&dmat);CHKERRQ(ierr); 5408eb06acf8SStefano Zampini ierr = PetscContainerCreate(PetscObjectComm((PetscObject)B),&c);CHKERRQ(ierr); 5409eb06acf8SStefano Zampini ierr = PetscContainerSetPointer(c,ddata);CHKERRQ(ierr); 5410eb06acf8SStefano Zampini ierr = PetscContainerSetUserDestroy(c,PetscContainerUserDestroyDefault);CHKERRQ(ierr); 5411eb06acf8SStefano Zampini ierr = PetscObjectCompose((PetscObject)dmat,"_PBDDC_Null_dmat_arr",(PetscObject)c);CHKERRQ(ierr); 5412eb06acf8SStefano Zampini ierr = PetscContainerDestroy(&c);CHKERRQ(ierr); 541392cccca0SStefano Zampini ierr = PetscObjectCompose((PetscObject)NullSpace,"_PBDDC_Null_dmat",(PetscObject)dmat);CHKERRQ(ierr); 541492cccca0SStefano Zampini ierr = MatDestroy(&dmat);CHKERRQ(ierr); 5415eb06acf8SStefano Zampini 541692cccca0SStefano Zampini for (k=0;k<bsiz;k++) { 541792cccca0SStefano Zampini ierr = VecDestroy(&nullvecs2[k]);CHKERRQ(ierr); 541892cccca0SStefano Zampini } 541992cccca0SStefano Zampini ierr = PetscFree(nullvecs2);CHKERRQ(ierr); 542092cccca0SStefano Zampini ierr = MatSetNearNullSpace(B,NullSpace);CHKERRQ(ierr); 542192cccca0SStefano Zampini ierr = MatNullSpaceDestroy(&NullSpace);CHKERRQ(ierr); 542292cccca0SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 542392cccca0SStefano Zampini ierr = VecDestroy(&v2);CHKERRQ(ierr); 542492cccca0SStefano Zampini ierr = VecScatterDestroy(&sct);CHKERRQ(ierr); 542592cccca0SStefano Zampini PetscFunctionReturn(0); 542692cccca0SStefano Zampini } 5427304d26faSStefano Zampini 5428684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 5429304d26faSStefano Zampini { 5430304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5431304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 5432304d26faSStefano Zampini PC pc_temp; 5433304d26faSStefano Zampini Mat A_RR; 543492cccca0SStefano Zampini MatNullSpace nnsp; 5435f4ddd8eeSStefano Zampini MatReuse reuse; 5436304d26faSStefano Zampini PetscScalar m_one = -1.0; 5437304d26faSStefano Zampini PetscReal value; 543804708bb6SStefano Zampini PetscInt n_D,n_R; 543992cccca0SStefano Zampini PetscBool issbaij,opts; 5440304d26faSStefano Zampini PetscErrorCode ierr; 54410a545947SLisandro Dalcin void (*f)(void) = NULL; 5442312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 5443e604994aSStefano Zampini size_t len; 5444304d26faSStefano Zampini 5445304d26faSStefano Zampini PetscFunctionBegin; 544643371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalSolvers[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 54476d9e27e4SStefano Zampini /* approximate solver, propagate NearNullSpace if needed */ 54486d9e27e4SStefano Zampini if (!pc->setupcalled && (pcbddc->NullSpace_corr[0] || pcbddc->NullSpace_corr[2])) { 54496d9e27e4SStefano Zampini MatNullSpace gnnsp1,gnnsp2; 54506d9e27e4SStefano Zampini PetscBool lhas,ghas; 54516d9e27e4SStefano Zampini 54526d9e27e4SStefano Zampini ierr = MatGetNearNullSpace(pcbddc->local_mat,&nnsp);CHKERRQ(ierr); 54536d9e27e4SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&gnnsp1);CHKERRQ(ierr); 54546d9e27e4SStefano Zampini ierr = MatGetNullSpace(pc->pmat,&gnnsp2);CHKERRQ(ierr); 54556d9e27e4SStefano Zampini lhas = nnsp ? PETSC_TRUE : PETSC_FALSE; 54566d9e27e4SStefano Zampini ierr = MPIU_Allreduce(&lhas,&ghas,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 54576d9e27e4SStefano Zampini if (!ghas && (gnnsp1 || gnnsp2)) { 54586d9e27e4SStefano Zampini ierr = MatNullSpacePropagateAny_Private(pc->pmat,NULL,NULL);CHKERRQ(ierr); 54596d9e27e4SStefano Zampini } 54606d9e27e4SStefano Zampini } 54616d9e27e4SStefano Zampini 5462e604994aSStefano Zampini /* compute prefixes */ 5463e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 5464e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 5465e604994aSStefano Zampini if (!pcbddc->current_level) { 5466a126751eSBarry Smith ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,sizeof(dir_prefix));CHKERRQ(ierr); 5467a126751eSBarry Smith ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,sizeof(neu_prefix));CHKERRQ(ierr); 5468a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,"pc_bddc_dirichlet_",sizeof(dir_prefix));CHKERRQ(ierr); 5469a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,"pc_bddc_neumann_",sizeof(neu_prefix));CHKERRQ(ierr); 5470e604994aSStefano Zampini } else { 547135529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 5472e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5473e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 5474312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5475312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 5476a126751eSBarry Smith /* Nonstandard use of PetscStrncpy() to only copy a portion of the input string */ 547734d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 547834d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5479a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,"pc_bddc_dirichlet_",sizeof(dir_prefix));CHKERRQ(ierr); 5480a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,"pc_bddc_neumann_",sizeof(neu_prefix));CHKERRQ(ierr); 5481a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,str_level,sizeof(dir_prefix));CHKERRQ(ierr); 5482a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,str_level,sizeof(neu_prefix));CHKERRQ(ierr); 5483e604994aSStefano Zampini } 5484e604994aSStefano Zampini 5485304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 5486684f6988SStefano Zampini if (dirichlet) { 5487d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5488450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 54896080607fSStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 5490450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 5491a3df083aSStefano Zampini Mat A_IIn; 5492a3df083aSStefano Zampini 5493a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 5494a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 5495a3df083aSStefano Zampini pcis->A_II = A_IIn; 5496a3df083aSStefano Zampini } 5497450f8f5eSStefano Zampini } 54983301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 5499d1e098c7SStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric);CHKERRQ(ierr); 5500964fefecSStefano Zampini } 5501ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 5502964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 550392cccca0SStefano Zampini opts = PETSC_FALSE; 5504304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 550592cccca0SStefano Zampini opts = PETSC_TRUE; 5506304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 5507304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 5508304d26faSStefano Zampini /* default */ 5509304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 5510e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 55112f37b69bSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->pA_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 5512304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 55139577ea80SStefano Zampini if (issbaij) { 55149577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 55159577ea80SStefano Zampini } else { 5516304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 55179577ea80SStefano Zampini } 5518399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->ksp_D,pc->erroriffailure);CHKERRQ(ierr); 551992cccca0SStefano Zampini } 552092cccca0SStefano Zampini ierr = MatSetOptionsPrefix(pcis->pA_II,((PetscObject)pcbddc->ksp_D)->prefix);CHKERRQ(ierr); 55212f37b69bSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->pA_II);CHKERRQ(ierr); 5522304d26faSStefano Zampini /* Allow user's customization */ 552392cccca0SStefano Zampini if (opts) { 5524304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 552592cccca0SStefano Zampini } 55266d9e27e4SStefano Zampini ierr = MatGetNearNullSpace(pcis->pA_II,&nnsp);CHKERRQ(ierr); 55276d9e27e4SStefano Zampini if (pcbddc->NullSpace_corr[0] && !nnsp) { /* approximate solver, propagate NearNullSpace */ 55286d9e27e4SStefano Zampini ierr = MatNullSpacePropagateAny_Private(pcbddc->local_mat,pcis->is_I_local,pcis->pA_II);CHKERRQ(ierr); 552992cccca0SStefano Zampini } 553092cccca0SStefano Zampini ierr = MatGetNearNullSpace(pcis->pA_II,&nnsp);CHKERRQ(ierr); 553192cccca0SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5532cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 553392cccca0SStefano Zampini if (f && pcbddc->mat_graph->cloc && !nnsp) { 5534cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5535cd18cfedSStefano Zampini const PetscInt *idxs; 5536cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5537cd18cfedSStefano Zampini 5538cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcis->is_I_local,&nl);CHKERRQ(ierr); 5539cd18cfedSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5540cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5541cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5542cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5543cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5544cd18cfedSStefano Zampini } 5545cd18cfedSStefano Zampini } 5546cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5547cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5548cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5549cd18cfedSStefano Zampini } 5550b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5551df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5552d62866d3SStefano Zampini 5553df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 5554d5574798SStefano Zampini } 555592cccca0SStefano Zampini 5556304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5557304d26faSStefano Zampini if (!n_D) { 5558304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5559304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5560304d26faSStefano Zampini } 556193120301SStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 5562304d26faSStefano Zampini /* set ksp_D into pcis data */ 5563304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 556492cccca0SStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 5565304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 5566684f6988SStefano Zampini } 5567304d26faSStefano Zampini 5568304d26faSStefano Zampini /* NEUMANN PROBLEM */ 55690a545947SLisandro Dalcin A_RR = NULL; 5570684f6988SStefano Zampini if (neumann) { 5571d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 557204708bb6SStefano Zampini PetscInt ibs,mbs; 55730aa714b2SStefano Zampini PetscBool issbaij, reuse_neumann_solver; 557404708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 55750aa714b2SStefano Zampini 55760aa714b2SStefano Zampini reuse_neumann_solver = PETSC_FALSE; 55770aa714b2SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 55780aa714b2SStefano Zampini IS iP; 55790aa714b2SStefano Zampini 55800aa714b2SStefano Zampini reuse_neumann_solver = PETSC_TRUE; 55810aa714b2SStefano Zampini ierr = PetscObjectQuery((PetscObject)sub_schurs->A,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 55820aa714b2SStefano Zampini if (iP) reuse_neumann_solver = PETSC_FALSE; 55830aa714b2SStefano Zampini } 5584f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 55858ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 5586f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 5587f4ddd8eeSStefano Zampini PetscInt nn_R; 558881d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 5589f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5590f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 5591f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 5592f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 5593f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5594f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5595f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 5596727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 5597f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5598f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5599f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 5600f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 5601f4ddd8eeSStefano Zampini } 5602f4ddd8eeSStefano Zampini } 5603f4ddd8eeSStefano Zampini /* last check */ 5604d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 5605f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5606f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5607f4ddd8eeSStefano Zampini } 5608f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 5609f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5610f4ddd8eeSStefano Zampini } 5611365a3a41SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection 5612365a3a41SStefano Zampini TODO: Get Rid of these conversions */ 5613af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 5614af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 561504708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 561604708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 561704708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 561804708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 561904708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 5620af732b37SStefano Zampini } else { 5621511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 56226816873aSStefano Zampini } 562304708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 562404708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 562504708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 5626365a3a41SStefano Zampini ierr = MatConvert(matis->A,mbs > 1 ? MATSEQBAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 562704708bb6SStefano Zampini } else { 5628365a3a41SStefano Zampini ierr = MatConvert(pcbddc->local_mat,mbs > 1 ? MATSEQBAIJ : MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 562904708bb6SStefano Zampini } 563004708bb6SStefano Zampini } 5631a00504b5SStefano Zampini /* extract A_RR */ 56320aa714b2SStefano Zampini if (reuse_neumann_solver) { 5633a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5634a00504b5SStefano Zampini 5635a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 563616e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5637a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 563816e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 563916e386b8SStefano Zampini } else { 56407dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 5641a00504b5SStefano Zampini } 5642a00504b5SStefano Zampini } else { 5643a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5644a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 5645a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5646a00504b5SStefano Zampini } 5647a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 56487dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 564916e386b8SStefano Zampini } 56503301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 5651d1e098c7SStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric);CHKERRQ(ierr); 56526816873aSStefano Zampini } 565392cccca0SStefano Zampini opts = PETSC_FALSE; 5654f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 565592cccca0SStefano Zampini opts = PETSC_TRUE; 5656304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 5657304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 5658304d26faSStefano Zampini /* default */ 5659304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 5660e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 5661304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 56629577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 56639577ea80SStefano Zampini if (issbaij) { 56649577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 56659577ea80SStefano Zampini } else { 5666304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 56679577ea80SStefano Zampini } 5668399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->ksp_R,pc->erroriffailure);CHKERRQ(ierr); 566992cccca0SStefano Zampini } 56702f37b69bSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 567192cccca0SStefano Zampini ierr = MatSetOptionsPrefix(A_RR,((PetscObject)pcbddc->ksp_R)->prefix);CHKERRQ(ierr); 567292cccca0SStefano Zampini if (opts) { /* Allow user's customization once */ 5673304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 567492cccca0SStefano Zampini } 56756d9e27e4SStefano Zampini ierr = MatGetNearNullSpace(A_RR,&nnsp);CHKERRQ(ierr); 56766d9e27e4SStefano Zampini if (pcbddc->NullSpace_corr[2] && !nnsp) { /* approximate solver, propagate NearNullSpace */ 56776d9e27e4SStefano Zampini ierr = MatNullSpacePropagateAny_Private(pcbddc->local_mat,pcbddc->is_R_local,A_RR);CHKERRQ(ierr); 567892cccca0SStefano Zampini } 567992cccca0SStefano Zampini ierr = MatGetNearNullSpace(A_RR,&nnsp);CHKERRQ(ierr); 568092cccca0SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5681cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 568292cccca0SStefano Zampini if (f && pcbddc->mat_graph->cloc && !nnsp) { 5683cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5684cd18cfedSStefano Zampini const PetscInt *idxs; 5685cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5686cd18cfedSStefano Zampini 5687cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcbddc->is_R_local,&nl);CHKERRQ(ierr); 5688cd18cfedSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5689cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5690cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5691cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5692cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5693cd18cfedSStefano Zampini } 5694cd18cfedSStefano Zampini } 5695cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5696cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5697cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5698cd18cfedSStefano Zampini } 569992cccca0SStefano Zampini 5700304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5701304d26faSStefano Zampini if (!n_R) { 5702304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5703304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5704304d26faSStefano Zampini } 5705df4d28bfSStefano Zampini /* Reuse solver if it is present */ 57060aa714b2SStefano Zampini if (reuse_neumann_solver) { 5707df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5708d62866d3SStefano Zampini 5709df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 5710d62866d3SStefano Zampini } 571193120301SStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 5712684f6988SStefano Zampini } 5713304d26faSStefano Zampini 5714684f6988SStefano Zampini if (pcbddc->dbg_flag) { 5715684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 57161575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5717684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5718684f6988SStefano Zampini } 57198ead10e4SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalSolvers[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 5720c7017625SStefano Zampini 5721c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 5722c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 5723c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 5724c7017625SStefano Zampini } 5725c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 5726c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 5727c7017625SStefano Zampini } 5728c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 5729c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 5730c7017625SStefano Zampini } 5731c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 5732c7017625SStefano Zampini if (pcbddc->dbg_flag) { 5733684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 57340fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 57350fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 57360fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 5737c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_D,pc,pcis->vec2_D);CHKERRQ(ierr); 57380fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 57390fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 5740e604994aSStefano 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); 5741304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5742304d26faSStefano Zampini } 5743684f6988SStefano Zampini if (neumann) { /* Neumann */ 57440fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 57450fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 57460fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 5747c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec2_R);CHKERRQ(ierr); 57480fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 57490fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 5750e604994aSStefano 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); 5751304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5752304d26faSStefano Zampini } 5753684f6988SStefano Zampini } 57545cbda25cSStefano Zampini /* free Neumann problem's matrix */ 57555cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5756304d26faSStefano Zampini PetscFunctionReturn(0); 5757304d26faSStefano Zampini } 5758304d26faSStefano Zampini 575980677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 5760674ae819SStefano Zampini { 5761674ae819SStefano Zampini PetscErrorCode ierr; 5762674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5763be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5764b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE; 5765674ae819SStefano Zampini 5766674ae819SStefano Zampini PetscFunctionBegin; 5767b334f244SStefano Zampini if (!reuse_solver) { 576880677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 576920c7b377SStefano Zampini } 577080677318SStefano Zampini if (!pcbddc->switch_static) { 577180677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 577280677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 577380677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 577420c7b377SStefano Zampini } 5775b334f244SStefano Zampini if (!reuse_solver) { 577680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 577780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 577820c7b377SStefano Zampini } else { 5779df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5780be83ff47SStefano Zampini 5781df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5782df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 578320c7b377SStefano Zampini } 5784be83ff47SStefano Zampini } else { 578580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 578680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 578780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 578880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 578980677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 579080677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 579180677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 579280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 579380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5794674ae819SStefano Zampini } 5795674ae819SStefano Zampini } 5796*55c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][1],pc,0,0,0);CHKERRQ(ierr); 5797b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 579880677318SStefano Zampini if (applytranspose) { 579980677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 580080677318SStefano Zampini } else { 580180677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 580280677318SStefano Zampini } 5803c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->ksp_R,pc,pcbddc->vec1_R);CHKERRQ(ierr); 5804be83ff47SStefano Zampini } else { 5805df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5806be83ff47SStefano Zampini 5807be83ff47SStefano Zampini if (applytranspose) { 5808df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5809be83ff47SStefano Zampini } else { 5810df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5811be83ff47SStefano Zampini } 5812be83ff47SStefano Zampini } 5813*55c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][1],pc,0,0,0);CHKERRQ(ierr); 581480677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 581580677318SStefano Zampini if (!pcbddc->switch_static) { 5816b334f244SStefano Zampini if (!reuse_solver) { 581780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 581880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5819be83ff47SStefano Zampini } else { 5820df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5821be83ff47SStefano Zampini 5822df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5823df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5824be83ff47SStefano Zampini } 582580677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 582680677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 582780677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 582880677318SStefano Zampini } 582980677318SStefano Zampini } else { 583080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 583180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 583280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 583380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 583480677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 583580677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 583680677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 583780677318SStefano Zampini } 583880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 583980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 584080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 584180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5842674ae819SStefano Zampini } 5843674ae819SStefano Zampini PetscFunctionReturn(0); 5844674ae819SStefano Zampini } 5845674ae819SStefano Zampini 5846dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 5847dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 5848674ae819SStefano Zampini { 5849674ae819SStefano Zampini PetscErrorCode ierr; 5850674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5851674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 5852674ae819SStefano Zampini const PetscScalar zero = 0.0; 5853674ae819SStefano Zampini 5854674ae819SStefano Zampini PetscFunctionBegin; 5855dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 58564fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5857dc359a40SStefano Zampini if (applytranspose) { 5858674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 58598eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 5860dc359a40SStefano Zampini } else { 5861674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 5862674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 586315aaf578SStefano Zampini } 58644fee134fSStefano Zampini } else { 58654fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 58664fee134fSStefano Zampini } 5867efc2fbd9SStefano Zampini 5868efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 58694f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5870efc2fbd9SStefano Zampini PetscScalar *array; 58714f1b2e48SStefano Zampini PetscInt j; 5872efc2fbd9SStefano Zampini 5873efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 58744f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 5875efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5876efc2fbd9SStefano Zampini } 5877efc2fbd9SStefano Zampini 587812edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 587912edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 588012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 588112edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 588212edc857SStefano Zampini 58839f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 588412edc857SStefano Zampini if (pcbddc->coarse_ksp) { 588551694757SStefano Zampini Mat coarse_mat; 5886964fefecSStefano Zampini Vec rhs,sol; 588751694757SStefano Zampini MatNullSpace nullsp; 588827b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 5889964fefecSStefano Zampini 589027b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 589127b6a85dSStefano Zampini PC coarse_pc; 589227b6a85dSStefano Zampini 589327b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 589427b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 589527b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 589627b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 589727b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 589827b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 58993bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 590027b6a85dSStefano Zampini } 590127b6a85dSStefano Zampini } 5902964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 5903964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 590451694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 590512edc857SStefano Zampini if (applytranspose) { 59069a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 5907*55c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][2],pc,0,0,0);CHKERRQ(ierr); 5908964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 5909*55c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][2],pc,0,0,0);CHKERRQ(ierr); 5910c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->coarse_ksp,pc,sol);CHKERRQ(ierr); 59119bfcb8eaSStefano Zampini ierr = MatGetTransposeNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 59129bfcb8eaSStefano Zampini if (nullsp) { 59139bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 59149bfcb8eaSStefano Zampini } 59152701bc32SStefano Zampini } else { 59169bfcb8eaSStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 59171f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 59182701bc32SStefano Zampini PC coarse_pc; 59192701bc32SStefano Zampini 59209bfcb8eaSStefano Zampini if (nullsp) { 59219bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 59229bfcb8eaSStefano Zampini } 59232701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 59242701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 59253e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 59262701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 592712edc857SStefano Zampini } else { 5928*55c176c0SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Solves[pcbddc->current_level][2],pc,0,0,0);CHKERRQ(ierr); 5929964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 5930*55c176c0SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Solves[pcbddc->current_level][2],pc,0,0,0);CHKERRQ(ierr); 5931c0decd05SBarry Smith ierr = KSPCheckSolve(pcbddc->coarse_ksp,pc,sol);CHKERRQ(ierr); 59329bfcb8eaSStefano Zampini if (nullsp) { 59339bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 59349bfcb8eaSStefano Zampini } 593512edc857SStefano Zampini } 59362701bc32SStefano Zampini } 59371d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 593827b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 593927b6a85dSStefano Zampini PC coarse_pc; 594027b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 594127b6a85dSStefano Zampini 594227b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 594327b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 594427b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 59453bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 594627b6a85dSStefano Zampini } 594712edc857SStefano Zampini } 5948674ae819SStefano Zampini 5949674ae819SStefano Zampini /* Local solution on R nodes */ 59504fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 595180677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 59529f00e9b4SStefano Zampini } 59539f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 59549f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 595512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5956674ae819SStefano Zampini 59574fee134fSStefano Zampini /* Sum contributions from the two levels */ 59584fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5959dc359a40SStefano Zampini if (applytranspose) { 5960dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5961dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5962dc359a40SStefano Zampini } else { 5963674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 59648eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5965dc359a40SStefano Zampini } 5966efc2fbd9SStefano Zampini /* store p0 */ 59674f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5968efc2fbd9SStefano Zampini PetscScalar *array; 59694f1b2e48SStefano Zampini PetscInt j; 5970efc2fbd9SStefano Zampini 5971efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 59724f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 5973efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5974efc2fbd9SStefano Zampini } 59754fee134fSStefano Zampini } else { /* expand the coarse solution */ 59764fee134fSStefano Zampini if (applytranspose) { 59774fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 59784fee134fSStefano Zampini } else { 59794fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 59804fee134fSStefano Zampini } 59814fee134fSStefano Zampini } 5982674ae819SStefano Zampini PetscFunctionReturn(0); 5983674ae819SStefano Zampini } 5984674ae819SStefano Zampini 598512edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 5986674ae819SStefano Zampini { 5987674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 598812edc857SStefano Zampini Vec from,to; 59897ebab0bbSStefano Zampini const PetscScalar *array; 59907ebab0bbSStefano Zampini PetscErrorCode ierr; 5991674ae819SStefano Zampini 5992674ae819SStefano Zampini PetscFunctionBegin; 599312edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 599412edc857SStefano Zampini from = pcbddc->coarse_vec; 599512edc857SStefano Zampini to = pcbddc->vec1_P; 599612edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 599712edc857SStefano Zampini Vec tvec; 599858da7f69SStefano Zampini 599958da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 600058da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 600112edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 60027ebab0bbSStefano Zampini ierr = VecGetArrayRead(tvec,&array);CHKERRQ(ierr); 600358da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 60047ebab0bbSStefano Zampini ierr = VecRestoreArrayRead(tvec,&array);CHKERRQ(ierr); 600512edc857SStefano Zampini } 600612edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 600712edc857SStefano Zampini from = pcbddc->vec1_P; 600812edc857SStefano Zampini to = pcbddc->coarse_vec; 600912edc857SStefano Zampini } 601012edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 6011674ae819SStefano Zampini PetscFunctionReturn(0); 6012674ae819SStefano Zampini } 6013674ae819SStefano Zampini 601412edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 6015674ae819SStefano Zampini { 6016674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 601712edc857SStefano Zampini Vec from,to; 60187ebab0bbSStefano Zampini const PetscScalar *array; 60197ebab0bbSStefano Zampini PetscErrorCode ierr; 6020674ae819SStefano Zampini 6021674ae819SStefano Zampini PetscFunctionBegin; 602212edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 602312edc857SStefano Zampini from = pcbddc->coarse_vec; 602412edc857SStefano Zampini to = pcbddc->vec1_P; 602512edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 602612edc857SStefano Zampini from = pcbddc->vec1_P; 602712edc857SStefano Zampini to = pcbddc->coarse_vec; 602812edc857SStefano Zampini } 602912edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 603012edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 603112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 603212edc857SStefano Zampini Vec tvec; 603358da7f69SStefano Zampini 603412edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 60357ebab0bbSStefano Zampini ierr = VecGetArrayRead(to,&array);CHKERRQ(ierr); 603658da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 60377ebab0bbSStefano Zampini ierr = VecRestoreArrayRead(to,&array);CHKERRQ(ierr); 603858da7f69SStefano Zampini } 603958da7f69SStefano Zampini } else { 604058da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 604158da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 604212edc857SStefano Zampini } 604312edc857SStefano Zampini } 6044674ae819SStefano Zampini PetscFunctionReturn(0); 6045674ae819SStefano Zampini } 6046674ae819SStefano Zampini 6047674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 6048674ae819SStefano Zampini { 6049674ae819SStefano Zampini PetscErrorCode ierr; 6050674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 6051674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6052674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 6053984c4197SStefano Zampini /* one and zero */ 6054984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 6055984c4197SStefano Zampini /* space to store constraints and their local indices */ 60569162d606SStefano Zampini PetscScalar *constraints_data; 60579162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 60589162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 60599162d606SStefano Zampini PetscInt *constraints_n; 6060984c4197SStefano Zampini /* iterators */ 6061b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 6062984c4197SStefano Zampini /* BLAS integers */ 6063e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 6064e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 6065c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 6066727cdba6SStefano Zampini /* reuse */ 60670e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 60680e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 6069984c4197SStefano Zampini /* change of basis */ 6070b3d85658SStefano Zampini PetscBool qr_needed; 60719162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 6072984c4197SStefano Zampini /* auxiliary stuff */ 607364efe560SStefano Zampini PetscInt *nnz,*is_indices; 60748a0068c3SStefano Zampini PetscInt ncc; 6075984c4197SStefano Zampini /* some quantities */ 607645a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 6077a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 607857715f18SStefano Zampini PetscReal tol; /* tolerance for retaining eigenmodes */ 6079984c4197SStefano Zampini 6080674ae819SStefano Zampini PetscFunctionBegin; 608157715f18SStefano Zampini tol = PetscSqrtReal(PETSC_SMALL); 60828e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 60838e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 60848e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 608516909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 6086088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 6087088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 60880e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 60890e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 6090580bdb30SBarry Smith ierr = PetscArraycpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc);CHKERRQ(ierr); 6091580bdb30SBarry Smith ierr = PetscArraycpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc);CHKERRQ(ierr); 60920e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 6093088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 6094cf5a6209SStefano Zampini 6095cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 60969162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 6097cf5a6209SStefano Zampini MatNullSpace nearnullsp; 6098cf5a6209SStefano Zampini const Vec *nearnullvecs; 6099cf5a6209SStefano Zampini Vec *localnearnullsp; 6100cf5a6209SStefano Zampini PetscScalar *array; 6101cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 6102cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 6103674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 6104b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 6105674ae819SStefano Zampini PetscScalar *work; 6106674ae819SStefano Zampini PetscReal *singular_vals; 6107674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6108674ae819SStefano Zampini PetscReal *rwork; 6109674ae819SStefano Zampini #endif 611055080a34SStefano Zampini PetscScalar *temp_basis = NULL,*correlation_mat = NULL; 6111964fefecSStefano Zampini PetscBLASInt dummy_int=1; 6112964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 611355080a34SStefano Zampini PetscBool use_pod = PETSC_FALSE; 6114674ae819SStefano Zampini 611555080a34SStefano Zampini /* MKL SVD with same input gives different results on different processes! */ 611655080a34SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) || defined(PETSC_HAVE_MKL) 611755080a34SStefano Zampini use_pod = PETSC_TRUE; 611855080a34SStefano Zampini #endif 6119674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 6120d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 6121e4d548c7SStefano Zampini /* print some info */ 61225c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 6123e4d548c7SStefano Zampini PetscInt nv; 6124e4d548c7SStefano Zampini 6125c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6126e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 6127e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6128e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 61296080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%D)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 61306080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%D)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 61316080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%D)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 6132e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6133e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 6134e4d548c7SStefano Zampini } 6135e4d548c7SStefano Zampini 6136d06fc5fdSStefano Zampini /* free unneeded index sets */ 6137d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 6138d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 6139674ae819SStefano Zampini } 6140d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 6141d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 6142d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 6143d06fc5fdSStefano Zampini } 6144d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 6145d06fc5fdSStefano Zampini n_ISForEdges = 0; 6146d06fc5fdSStefano Zampini } 6147d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 6148d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 6149d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 6150d06fc5fdSStefano Zampini } 6151d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 6152d06fc5fdSStefano Zampini n_ISForFaces = 0; 6153d06fc5fdSStefano Zampini } 615470022509SStefano Zampini 6155674ae819SStefano Zampini /* check if near null space is attached to global mat */ 61566d9e27e4SStefano Zampini if (pcbddc->use_nnsp) { 6157674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 61586d9e27e4SStefano Zampini } else nearnullsp = NULL; 61596d9e27e4SStefano Zampini 6160674ae819SStefano Zampini if (nearnullsp) { 6161674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 6162f4ddd8eeSStefano Zampini /* remove any stored info */ 6163f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 6164f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 6165f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 6166f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 6167f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 6168473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 6169f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 6170f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 6171f4ddd8eeSStefano Zampini } 6172984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 6173984c4197SStefano Zampini nnsp_size = 0; 6174674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 6175674ae819SStefano Zampini } 6176984c4197SStefano Zampini /* get max number of constraints on a single cc */ 6177984c4197SStefano Zampini max_constraints = nnsp_size; 6178984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 6179984c4197SStefano Zampini 6180674ae819SStefano Zampini /* 6181674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 61829162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 61839162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 61849162d606SStefano Zampini There can be multiple constraints per connected component 6185674ae819SStefano Zampini */ 6186674ae819SStefano Zampini n_vertices = 0; 6187674ae819SStefano Zampini if (ISForVertices) { 6188674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 6189674ae819SStefano Zampini } 61909162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 61919162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 61929162d606SStefano Zampini 61939162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 61949162d606SStefano Zampini total_counts *= max_constraints; 6195674ae819SStefano Zampini total_counts += n_vertices; 61964641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 61979162d606SStefano Zampini 6198674ae819SStefano Zampini total_counts = 0; 6199674ae819SStefano Zampini max_size_of_constraint = 0; 6200674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 62019162d606SStefano Zampini IS used_is; 6202674ae819SStefano Zampini if (i<n_ISForEdges) { 62039162d606SStefano Zampini used_is = ISForEdges[i]; 6204674ae819SStefano Zampini } else { 62059162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 6206674ae819SStefano Zampini } 62079162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 6208674ae819SStefano Zampini total_counts += j; 6209674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 6210674ae819SStefano Zampini } 62119162d606SStefano 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); 62129162d606SStefano Zampini 6213984c4197SStefano Zampini /* get local part of global near null space vectors */ 6214785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 6215984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 6216984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 6217e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6218e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6219984c4197SStefano Zampini } 6220674ae819SStefano Zampini 6221242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 6222242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 6223a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 6224242a89d7SStefano Zampini 6225984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 6226a773dcb8SStefano Zampini if (!skip_lapack) { 6227674ae819SStefano Zampini PetscScalar temp_work; 6228911cabfeSStefano Zampini 622955080a34SStefano Zampini if (use_pod) { 6230984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 6231785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 6232785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 6233785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 6234674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6235785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 6236674ae819SStefano Zampini #endif 6237674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 6238c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 6239c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 6240674ae819SStefano Zampini lwork = -1; 6241674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6242674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 6243c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 6244674ae819SStefano Zampini #else 6245c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 6246674ae819SStefano Zampini #endif 6247674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6248984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 624955080a34SStefano Zampini } else { 625055080a34SStefano Zampini #if !defined(PETSC_MISSING_LAPACK_GESVD) 6251674ae819SStefano Zampini /* SVD */ 6252674ae819SStefano Zampini PetscInt max_n,min_n; 6253674ae819SStefano Zampini max_n = max_size_of_constraint; 6254984c4197SStefano Zampini min_n = max_constraints; 6255984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 6256674ae819SStefano Zampini min_n = max_size_of_constraint; 6257984c4197SStefano Zampini max_n = max_constraints; 6258674ae819SStefano Zampini } 6259785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 6260674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6261785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 6262674ae819SStefano Zampini #endif 6263674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 6264674ae819SStefano Zampini lwork = -1; 6265e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 6266e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 6267b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 6268674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6269674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 62709162d606SStefano 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)); 6271674ae819SStefano Zampini #else 62729162d606SStefano 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)); 6273674ae819SStefano Zampini #endif 6274674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6275984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 627655080a34SStefano Zampini #else 627755080a34SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"This should not happen"); 6278984c4197SStefano Zampini #endif /* on missing GESVD */ 627955080a34SStefano Zampini } 6280674ae819SStefano Zampini /* Allocate optimal workspace */ 6281674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 6282854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 6283674ae819SStefano Zampini } 6284674ae819SStefano Zampini /* Now we can loop on constraining sets */ 6285674ae819SStefano Zampini total_counts = 0; 62869162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 62879162d606SStefano Zampini constraints_data_ptr[0] = 0; 6288674ae819SStefano Zampini /* vertices */ 62899162d606SStefano Zampini if (n_vertices) { 6290674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6291580bdb30SBarry Smith ierr = PetscArraycpy(constraints_idxs,is_indices,n_vertices);CHKERRQ(ierr); 6292674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 62939162d606SStefano Zampini constraints_n[total_counts] = 1; 62949162d606SStefano Zampini constraints_data[total_counts] = 1.0; 62959162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 62969162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 6297674ae819SStefano Zampini total_counts++; 6298674ae819SStefano Zampini } 6299674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6300674ae819SStefano Zampini n_vertices = total_counts; 6301674ae819SStefano Zampini } 6302984c4197SStefano Zampini 6303674ae819SStefano Zampini /* edges and faces */ 63049162d606SStefano Zampini total_counts_cc = total_counts; 6305911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 63069162d606SStefano Zampini IS used_is; 63079162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 63089162d606SStefano Zampini 6309911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 63109162d606SStefano Zampini used_is = ISForEdges[ncc]; 6311984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 6312674ae819SStefano Zampini } else { 63139162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 6314984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 6315674ae819SStefano Zampini } 6316674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 63179162d606SStefano Zampini 63189162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 63199162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6320984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 6321984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 6322674ae819SStefano Zampini if (nnsp_has_cnst) { 63235b08dc53SStefano Zampini PetscScalar quad_value; 63249162d606SStefano Zampini 6325580bdb30SBarry Smith ierr = PetscArraycpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint);CHKERRQ(ierr); 63269162d606SStefano Zampini idxs_copied = PETSC_TRUE; 63279162d606SStefano Zampini 6328a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 6329674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 6330a773dcb8SStefano Zampini } else { 6331a773dcb8SStefano Zampini quad_value = 1.0; 6332a773dcb8SStefano Zampini } 6333674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 63349162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 6335674ae819SStefano Zampini } 63369162d606SStefano Zampini temp_constraints++; 6337674ae819SStefano Zampini total_counts++; 6338674ae819SStefano Zampini } 6339674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 6340984c4197SStefano Zampini PetscReal real_value; 63419162d606SStefano Zampini PetscScalar *ptr_to_data; 63429162d606SStefano Zampini 6343984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 63449162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 6345674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 63469162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 6347674ae819SStefano Zampini } 6348984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 6349984c4197SStefano Zampini /* check if array is null on the connected component */ 6350e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 63519162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 635257715f18SStefano Zampini if (real_value > tol*size_of_constraint) { /* keep indices and values */ 6353674ae819SStefano Zampini temp_constraints++; 6354674ae819SStefano Zampini total_counts++; 63559162d606SStefano Zampini if (!idxs_copied) { 6356580bdb30SBarry Smith ierr = PetscArraycpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint);CHKERRQ(ierr); 63579162d606SStefano Zampini idxs_copied = PETSC_TRUE; 6358674ae819SStefano Zampini } 6359674ae819SStefano Zampini } 63609162d606SStefano Zampini } 63619162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 636245a1bb75SStefano Zampini valid_constraints = temp_constraints; 6363eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 6364a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 63659162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 63669162d606SStefano Zampini 63679162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 6368a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 63699162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 6370a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 63719162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 6372a773dcb8SStefano Zampini } else { /* perform SVD */ 63739162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 6374674ae819SStefano Zampini 637555080a34SStefano Zampini if (use_pod) { 6376984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 6377984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 6378984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 6379984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 6380984c4197SStefano Zampini from that computed using LAPACKgesvd 6381984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 6382984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 6383580bdb30SBarry Smith ierr = PetscArrayzero(correlation_mat,temp_constraints*temp_constraints);CHKERRQ(ierr); 6384674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 6385e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6386984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6387674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 6388674ae819SStefano Zampini for (k=0;k<j+1;k++) { 63899162d606SStefano 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)); 6390674ae819SStefano Zampini } 6391674ae819SStefano Zampini } 6392e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 6393e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6394e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 6395674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 6396c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 6397674ae819SStefano Zampini #else 6398c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 6399674ae819SStefano Zampini #endif 6400674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6401984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 6402984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 6403674ae819SStefano Zampini j = 0; 640487b3baaaSStefano Zampini while (j < temp_constraints && singular_vals[j]/singular_vals[temp_constraints-1] < tol) j++; 6405674ae819SStefano Zampini total_counts = total_counts-j; 640645a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 6407e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 6408c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 6409c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6410c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 6411c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6412c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 6413c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6414674ae819SStefano Zampini if (j<temp_constraints) { 6415984c4197SStefano Zampini PetscInt ii; 6416984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 6417674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 64189162d606SStefano 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)); 6419674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6420984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 6421674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 64229162d606SStefano 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]; 6423674ae819SStefano Zampini } 6424674ae819SStefano Zampini } 6425674ae819SStefano Zampini } 642655080a34SStefano Zampini } else { 642755080a34SStefano Zampini #if !defined(PETSC_MISSING_LAPACK_GESVD) 6428e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 6429e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6430b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6431674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6432674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 64339162d606SStefano 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)); 6434674ae819SStefano Zampini #else 64359162d606SStefano 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)); 6436674ae819SStefano Zampini #endif 6437984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 6438674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6439984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 6440e310c8b4SStefano Zampini k = temp_constraints; 6441e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 6442674ae819SStefano Zampini j = 0; 644387b3baaaSStefano Zampini while (j < k && singular_vals[k-j-1]/singular_vals[0] < tol) j++; 644445a1bb75SStefano Zampini valid_constraints = k-j; 6445911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 644655080a34SStefano Zampini #else 644755080a34SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"This should not happen"); 6448984c4197SStefano Zampini #endif /* on missing GESVD */ 6449674ae819SStefano Zampini } 6450a773dcb8SStefano Zampini } 645155080a34SStefano Zampini } 64529162d606SStefano Zampini /* update pointers information */ 64539162d606SStefano Zampini if (valid_constraints) { 64549162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 64559162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 64569162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 64579162d606SStefano Zampini /* set change_of_basis flag */ 645845a1bb75SStefano Zampini if (boolforchange) { 6459b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 64609162d606SStefano Zampini } 6461b3d85658SStefano Zampini total_counts_cc++; 646245a1bb75SStefano Zampini } 646345a1bb75SStefano Zampini } 6464984c4197SStefano Zampini /* free workspace */ 64658f1c130eSStefano Zampini if (!skip_lapack) { 6466984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 6467984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6468984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 6469984c4197SStefano Zampini #endif 6470984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 6471984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 6472984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 6473984c4197SStefano Zampini } 6474984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 6475984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 6476984c4197SStefano Zampini } 6477984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 6478cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 6479cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 6480cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 6481cf5a6209SStefano Zampini } 6482cf5a6209SStefano Zampini if (n_ISForFaces) { 6483cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 6484cf5a6209SStefano Zampini } 6485cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 6486cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 6487cf5a6209SStefano Zampini } 6488cf5a6209SStefano Zampini if (n_ISForEdges) { 6489cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 6490cf5a6209SStefano Zampini } 6491cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 649208122e43SStefano Zampini } else { 649308122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 6494984c4197SStefano Zampini 649508122e43SStefano Zampini total_counts = 0; 649608122e43SStefano Zampini n_vertices = 0; 6497d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 6498d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 649908122e43SStefano Zampini } 650008122e43SStefano Zampini max_constraints = 0; 65019162d606SStefano Zampini total_counts_cc = 0; 650208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 650308122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 65049162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 650508122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 650608122e43SStefano Zampini } 65079162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 65089162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 65099162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 65109162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 651174d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 65129162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 65139162d606SStefano Zampini total_counts_cc = 0; 65149162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 65159162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 65169162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 651708122e43SStefano Zampini } 651808122e43SStefano Zampini } 651908122e43SStefano Zampini 65208bec7fa6SStefano Zampini max_size_of_constraint = 0; 65219162d606SStefano 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]); 65229162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 652308122e43SStefano Zampini /* Change of basis */ 6524b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 652508122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 652608122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 652708122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 6528b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 652908122e43SStefano Zampini } 653008122e43SStefano Zampini } 653108122e43SStefano Zampini } 653208122e43SStefano Zampini } 6533984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 65344f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 653508122e43SStefano Zampini 65369162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 65379162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 65386080607fSStefano 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); 6539674ae819SStefano Zampini 6540674ae819SStefano Zampini /* Create constraint matrix */ 6541674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 654216f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 6543984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 6544984c4197SStefano Zampini 6545984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 6546a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 65475a52fde0SStefano Zampini qr_needed = pcbddc->use_qr_single; 654874d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 6549984c4197SStefano Zampini total_primal_vertices=0; 6550b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 65519162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 65529162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 655372b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 65549162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 6555b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 655664efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 65579162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 65589162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 6559a717540cSStefano Zampini } 6560b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 656191af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 6562a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 6563a717540cSStefano Zampini qr_needed = PETSC_TRUE; 6564a717540cSStefano Zampini } 6565fa434743SStefano Zampini } else { 6566b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 6567fa434743SStefano Zampini } 6568a717540cSStefano Zampini } 6569b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 6570b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 6571674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 657270022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 65734f1b2e48SStefano 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); 6574580bdb30SBarry Smith ierr = PetscArraycpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices);CHKERRQ(ierr); 65750e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 6576984c4197SStefano Zampini 6577984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 657874d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 6579785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 6580984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 658174d5cdf7SStefano Zampini 6582984c4197SStefano Zampini j = total_primal_vertices; 658374d5cdf7SStefano Zampini total_counts = total_primal_vertices; 6584b3d85658SStefano Zampini cum = total_primal_vertices; 65859162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 65864641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 6587b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 6588b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 6589b3d85658SStefano Zampini cum++; 65909162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 659174d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 659274d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 659374d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 659474d5cdf7SStefano Zampini } 65959162d606SStefano Zampini j += constraints_n[i]; 6596674ae819SStefano Zampini } 6597674ae819SStefano Zampini } 6598674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 6599e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->ConstraintMatrix,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 6600674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 6601088faed8SStefano Zampini 6602674ae819SStefano Zampini /* set values in constraint matrix */ 6603984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 66040e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6605674ae819SStefano Zampini } 6606984c4197SStefano Zampini total_counts = total_primal_vertices; 66079162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 66084641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 66099162d606SStefano Zampini PetscInt *cols; 66109162d606SStefano Zampini 66119162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 66129162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 66139162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 66149162d606SStefano Zampini PetscInt row = total_counts+k; 66159162d606SStefano Zampini PetscScalar *vals; 66169162d606SStefano Zampini 66179162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 66189162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 66199162d606SStefano Zampini } 66209162d606SStefano Zampini total_counts += constraints_n[i]; 6621674ae819SStefano Zampini } 6622674ae819SStefano Zampini } 6623674ae819SStefano Zampini /* assembling */ 6624674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6625674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 66267ebab0bbSStefano Zampini ierr = MatViewFromOptions(pcbddc->ConstraintMatrix,(PetscObject)pc,"-pc_bddc_constraint_mat_view");CHKERRQ(ierr); 6627088faed8SStefano Zampini 6628674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 6629674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 6630026de310SStefano Zampini /* dual and primal dofs on a single cc */ 6631984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 6632984c4197SStefano Zampini /* working stuff for GEQRF */ 66335a52fde0SStefano Zampini PetscScalar *qr_basis = NULL,*qr_tau = NULL,*qr_work = NULL,lqr_work_t; 6634984c4197SStefano Zampini PetscBLASInt lqr_work; 6635984c4197SStefano Zampini /* working stuff for UNGQR */ 66363c377650SSatish Balay PetscScalar *gqr_work = NULL,lgqr_work_t=0.0; 6637984c4197SStefano Zampini PetscBLASInt lgqr_work; 6638984c4197SStefano Zampini /* working stuff for TRTRS */ 66395a52fde0SStefano Zampini PetscScalar *trs_rhs = NULL; 66403f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 6641984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 6642984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 6643984c4197SStefano Zampini PetscScalar *start_vals; 6644984c4197SStefano Zampini /* working stuff for values insertion */ 66454641a718SStefano Zampini PetscBT is_primal; 664664efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 6647906d46d4SStefano Zampini /* matrix sizes */ 6648906d46d4SStefano Zampini PetscInt global_size,local_size; 6649906d46d4SStefano Zampini /* temporary change of basis */ 6650906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 6651cf5a6209SStefano Zampini /* extra space for debugging */ 66525a52fde0SStefano Zampini PetscScalar *dbg_work = NULL; 6653984c4197SStefano Zampini 6654906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 6655906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 665616f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 6657bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 6658906d46d4SStefano Zampini /* nonzeros for local mat */ 6659bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 66601dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6661bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 66621dd7afcfSStefano Zampini } else { 66631dd7afcfSStefano Zampini const PetscInt *ii; 66641dd7afcfSStefano Zampini PetscInt n; 66651dd7afcfSStefano Zampini PetscBool flg_row; 66661dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 66671dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 66681dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 66691dd7afcfSStefano Zampini } 66709162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 6671a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 66729162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 6673a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 66749162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 6675a717540cSStefano Zampini } else { 66769162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 66779162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 6678a717540cSStefano Zampini } 6679a717540cSStefano Zampini } 6680a717540cSStefano Zampini } 6681906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 6682e1b21442SStefano Zampini ierr = MatSetOption(localChangeOfBasisMatrix,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 6683bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 66841dd7afcfSStefano Zampini /* Set interior change in the matrix */ 66851dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6686bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 6687906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 6688a717540cSStefano Zampini } 66891dd7afcfSStefano Zampini } else { 66901dd7afcfSStefano Zampini const PetscInt *ii,*jj; 66911dd7afcfSStefano Zampini PetscScalar *aa; 66921dd7afcfSStefano Zampini PetscInt n; 66931dd7afcfSStefano Zampini PetscBool flg_row; 66941dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 66951dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 66961dd7afcfSStefano Zampini for (i=0;i<n;i++) { 66971dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 66981dd7afcfSStefano Zampini } 66991dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 67001dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 67011dd7afcfSStefano Zampini } 6702a717540cSStefano Zampini 6703a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6704a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6705a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6706a717540cSStefano Zampini } 6707a717540cSStefano Zampini 6708a717540cSStefano Zampini 6709a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 6710a717540cSStefano Zampini /* 6711a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 6712a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 6713a717540cSStefano Zampini 6714a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 6715a717540cSStefano Zampini 6716a6b551f4SStefano 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) 6717a6b551f4SStefano Zampini 6718a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 6719a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 6720a717540cSStefano Zampini | ... | 6721a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 6722a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 6723a717540cSStefano Zampini 6724a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 6725a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 6726a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 6727a6b551f4SStefano Zampini 6728a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 6729a717540cSStefano Zampini */ 67305a52fde0SStefano Zampini if (qr_needed && max_size_of_constraint) { 6731984c4197SStefano Zampini /* space to store Q */ 6732854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 67334e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 67344e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 6735984c4197SStefano Zampini /* first we issue queries for optimal work */ 67363f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 67373f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 67383f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6739984c4197SStefano Zampini lqr_work = -1; 67403f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 6741984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 6742984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 6743785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 6744984c4197SStefano Zampini lgqr_work = -1; 67453f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 67463f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 67473f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 67483f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 67493f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 6750c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 6751c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to ORGQR/UNGQR Lapack routine %d",(int)lierr); 6752984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 6753785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 6754984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 6755785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 6756a717540cSStefano Zampini /* allocating workspace for check */ 6757a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6758cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 6759a717540cSStefano Zampini } 6760a717540cSStefano Zampini } 6761984c4197SStefano Zampini /* array to store whether a node is primal or not */ 67624641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 6763473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 67640e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 67656080607fSStefano 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); 676639e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 676739e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 676839e2fb2aSStefano Zampini } 676939e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 6770984c4197SStefano Zampini 6771a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 67729162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 67739162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 67744641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 6775984c4197SStefano Zampini /* get constraint info */ 67769162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 6777984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 6778984c4197SStefano Zampini 6779984c4197SStefano Zampini if (pcbddc->dbg_flag) { 67806080607fSStefano 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); 6781674ae819SStefano Zampini } 6782984c4197SStefano Zampini 6783fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 6784a717540cSStefano Zampini 6785a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 6786a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6787580bdb30SBarry Smith ierr = PetscArraycpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs);CHKERRQ(ierr); 6788a717540cSStefano Zampini } 6789984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 6790580bdb30SBarry Smith ierr = PetscArraycpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs);CHKERRQ(ierr); 6791984c4197SStefano Zampini 6792984c4197SStefano Zampini /* compute QR decomposition of constraints */ 67933f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 67943f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 67953f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6796674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 67973f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 6798984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 6799674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6800984c4197SStefano Zampini 6801984c4197SStefano Zampini /* explictly compute R^-T */ 6802580bdb30SBarry Smith ierr = PetscArrayzero(trs_rhs,primal_dofs*primal_dofs);CHKERRQ(ierr); 6803984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 68043f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 68053f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 68063f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 68073f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 6808984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 68093f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 6810984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 6811984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6812984c4197SStefano Zampini 6813a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2]) overwriting QR factorization in qr_basis */ 68143f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 68153f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 68163f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 68173f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6818984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6819c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 6820c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in ORGQR/UNGQR Lapack routine %d",(int)lierr); 6821984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6822984c4197SStefano Zampini 6823984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 6824984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 6825984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 68263f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 68273f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 68283f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 68293f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 68303f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 68313f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6832984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 68339162d606SStefano 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)); 6834984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6835580bdb30SBarry Smith ierr = PetscArraycpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs);CHKERRQ(ierr); 6836984c4197SStefano Zampini 6837984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 68389162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 6839984c4197SStefano Zampini /* insert cols for primal dofs */ 6840984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 6841984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 68429162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6843906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6844984c4197SStefano Zampini } 6845984c4197SStefano Zampini /* insert cols for dual dofs */ 6846984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 68479162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 6848984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 68499162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6850906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6851984c4197SStefano Zampini j++; 6852674ae819SStefano Zampini } 6853674ae819SStefano Zampini } 6854984c4197SStefano Zampini 6855984c4197SStefano Zampini /* check change of basis */ 6856984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6857984c4197SStefano Zampini PetscInt ii,jj; 6858984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 6859c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 6860c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6861c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 6862c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6863c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 6864c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 6865984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6866cf5a6209SStefano 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)); 6867984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6868984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6869984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6870cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 6871c068d9bbSLisandro 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; 6872674ae819SStefano Zampini } 6873674ae819SStefano Zampini } 6874984c4197SStefano Zampini if (!valid_qr) { 687522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 6876984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6877984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6878cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 68796080607fSStefano 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); 6880674ae819SStefano Zampini } 6881c068d9bbSLisandro Dalcin if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-(PetscReal)1) > 1.e-12) { 68826080607fSStefano 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); 6883984c4197SStefano Zampini } 6884984c4197SStefano Zampini } 6885984c4197SStefano Zampini } 6886674ae819SStefano Zampini } else { 688722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 6888674ae819SStefano Zampini } 6889674ae819SStefano Zampini } 6890a717540cSStefano Zampini } else { /* simple transformation block */ 6891a717540cSStefano Zampini PetscInt row,col; 6892a6b551f4SStefano Zampini PetscScalar val,norm; 6893a6b551f4SStefano Zampini 6894a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 68959162d606SStefano 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)); 6896a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 68979162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 68989162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6899bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 69009162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 6901906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 69029162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 6903a717540cSStefano Zampini } else { 6904a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 69059162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6906a717540cSStefano Zampini if (row != col) { 69079162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 6908a717540cSStefano Zampini } else { 69099162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 6910a717540cSStefano Zampini } 6911906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 6912a717540cSStefano Zampini } 6913a717540cSStefano Zampini } 6914a717540cSStefano Zampini } 691598a51de6SStefano Zampini if (pcbddc->dbg_flag) { 691622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 6917a717540cSStefano Zampini } 6918674ae819SStefano Zampini } 6919984c4197SStefano Zampini } else { 6920984c4197SStefano Zampini if (pcbddc->dbg_flag) { 69216080607fSStefano 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); 6922674ae819SStefano Zampini } 6923674ae819SStefano Zampini } 6924674ae819SStefano Zampini } 6925a717540cSStefano Zampini 6926a717540cSStefano Zampini /* free workspace */ 6927a717540cSStefano Zampini if (qr_needed) { 6928984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6929cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 6930984c4197SStefano Zampini } 6931984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 6932984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 6933984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 6934984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 6935984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 6936674ae819SStefano Zampini } 6937a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 6938906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6939906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6940906d46d4SStefano Zampini 6941906d46d4SStefano Zampini /* assembling of global change of variable */ 694288c03ad3SStefano Zampini if (!pcbddc->fake_change) { 6943bbb9e6c6SStefano Zampini Mat tmat; 694416f15bc4SStefano Zampini PetscInt bs; 694516f15bc4SStefano Zampini 6946906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 6947906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 6948bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6949bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 6950487b449aSStefano Zampini ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6951487b449aSStefano Zampini ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6952bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6953bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 695416f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 695516f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 6956906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 6957bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 6958487b449aSStefano Zampini ierr = MatConvert(tmat,MATAIJ,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6959bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6960bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6961bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6962e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6963e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6964bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 6965bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 696688c03ad3SStefano Zampini 6967906d46d4SStefano Zampini /* check */ 6968906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 6969906d46d4SStefano Zampini PetscReal error; 6970906d46d4SStefano Zampini Vec x,x_change; 6971906d46d4SStefano Zampini 6972906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 6973906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 6974906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 6975906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 6976e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6977e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6978bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 6979e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6980e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6981906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 6982906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 6983906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 6984637e8532SStefano Zampini if (error > PETSC_SMALL) { 69856080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e",error); 6986637e8532SStefano Zampini } 6987906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 6988906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 6989906d46d4SStefano Zampini } 6990b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 6991b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6992b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6993bf3a8328SStefano Zampini 699413903a91SSatish 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"); 6995b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6996ac632422SStefano Zampini Mat S_new,tmat; 6997bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6998bbb9e6c6SStefano Zampini 6999bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 70007dae84e0SHong Zhang ierr = MatCreateSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 7001bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 7002bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 7003bf3a8328SStefano Zampini IS is_V; 7004b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 7005b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 7006b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 7007b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 7008b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 7009bf3a8328SStefano Zampini } 7010bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 7011ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 7012b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 7013ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 7014bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 7015bf3a8328SStefano Zampini const PetscScalar *array; 7016bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 7017bf3a8328SStefano Zampini PetscInt i,n_V; 7018bf3a8328SStefano Zampini 7019b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 7020b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 7021b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 7022b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 7023b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 7024b087196eSStefano Zampini for (i=0;i<n_V;i++) { 7025b087196eSStefano Zampini PetscScalar val; 7026b087196eSStefano Zampini PetscInt idx; 7027b087196eSStefano Zampini 7028b087196eSStefano Zampini idx = idxs_V[i]; 7029b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 7030b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 7031b087196eSStefano Zampini } 7032b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7033b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7034bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 7035bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 7036bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 7037bf3a8328SStefano Zampini } 7038ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 7039ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 7040ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 7041ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 7042b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 7043ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 7044bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 7045b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 7046bf3a8328SStefano Zampini } 7047ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 7048ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 7049ac632422SStefano Zampini } 7050b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 705188c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 7052b96c3477SStefano Zampini } 7053c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 7054b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 7055c9db6a07SStefano Zampini PetscInt i; 7056c9db6a07SStefano Zampini 7057c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 7058c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 7059c9db6a07SStefano Zampini } 7060c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 7061c9db6a07SStefano Zampini } 7062b96c3477SStefano Zampini } 706316909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 706416909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 706516909a7fSStefano Zampini } else { 7066906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 706716909a7fSStefano Zampini } 70681dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 706927b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 707072b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 707172b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 707272b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 707372b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 707472b8c272SStefano Zampini } 70751dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 707627b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 7077b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 7078b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 7079906d46d4SStefano Zampini } else { 70801dd7afcfSStefano Zampini Mat benign_global = NULL; 708127b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 70821dd7afcfSStefano Zampini Mat M; 70831dd7afcfSStefano Zampini 70849e9b7b1fSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 70859e9b7b1fSStefano Zampini ierr = VecCopy(matis->counter,pcis->vec1_N);CHKERRQ(ierr); 70869e9b7b1fSStefano Zampini ierr = VecReciprocal(pcis->vec1_N);CHKERRQ(ierr); 70879e9b7b1fSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&benign_global);CHKERRQ(ierr); 70889e9b7b1fSStefano Zampini if (pcbddc->benign_change) { 70891dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 70901dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 7091906d46d4SStefano Zampini } else { 70929e9b7b1fSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&M);CHKERRQ(ierr); 70939e9b7b1fSStefano Zampini ierr = MatDiagonalSet(M,pcis->vec1_N,INSERT_VALUES);CHKERRQ(ierr); 7094906d46d4SStefano Zampini } 70959e9b7b1fSStefano Zampini ierr = MatISSetLocalMat(benign_global,M);CHKERRQ(ierr); 70969e9b7b1fSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 70979e9b7b1fSStefano Zampini ierr = MatAssemblyBegin(benign_global,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 70989e9b7b1fSStefano Zampini ierr = MatAssemblyEnd(benign_global,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 70991dd7afcfSStefano Zampini } 71001dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 71011dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 71021dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 710327b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 71041dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 71051dd7afcfSStefano Zampini } 71061dd7afcfSStefano Zampini } 710716909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 710816909a7fSStefano Zampini IS is_global; 710916909a7fSStefano Zampini const PetscInt *gidxs; 711016909a7fSStefano Zampini 711116909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 711216909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 711316909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 71147dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 711516909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 711616909a7fSStefano Zampini } 71171dd7afcfSStefano Zampini } 71181dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 71191dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 7120b9b85e73SStefano Zampini } 7121a717540cSStefano Zampini 712272b8c272SStefano Zampini if (!pcbddc->fake_change) { 71234f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 71244f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 71254f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 71264f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 7127019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 7128019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 7129019a44ceSStefano Zampini pcbddc->local_primal_size++; 7130019a44ceSStefano Zampini } 7131019a44ceSStefano Zampini 7132019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 7133727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 7134727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 7135580bdb30SBarry Smith ierr = PetscArraycmp(pcbddc->local_primal_ref_node,olocal_primal_ref_node,olocal_primal_size_cc,&pcbddc->new_primal_space_local);CHKERRQ(ierr); 7136c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 71370e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 7138580bdb30SBarry Smith ierr = PetscArraycmp(pcbddc->local_primal_ref_mult,olocal_primal_ref_mult,olocal_primal_size_cc,&pcbddc->new_primal_space_local);CHKERRQ(ierr); 7139727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 7140727cdba6SStefano Zampini } 71410e6343abSStefano Zampini } 7142727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 7143b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 714472b8c272SStefano Zampini } 714572b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 7146727cdba6SStefano Zampini 7147a717540cSStefano Zampini /* flush dbg viewer */ 7148b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 7149b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7150b8ffe317SStefano Zampini } 7151a717540cSStefano Zampini 7152e310c8b4SStefano Zampini /* free workspace */ 7153a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 71544641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 715508122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 71569162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 71579162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 715808122e43SStefano Zampini } else { 71599162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 71609162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 71619162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 716208122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 716308122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 71649162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 71659162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 716608122e43SStefano Zampini } 7167674ae819SStefano Zampini PetscFunctionReturn(0); 7168674ae819SStefano Zampini } 7169674ae819SStefano Zampini 7170674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 7171674ae819SStefano Zampini { 717271582508SStefano Zampini ISLocalToGlobalMapping map; 7173674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7174674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 717566da6bd7Sstefano_zampini PetscInt i,N; 717666da6bd7Sstefano_zampini PetscBool rcsr = PETSC_FALSE; 717766da6bd7Sstefano_zampini PetscErrorCode ierr; 7178674ae819SStefano Zampini 7179674ae819SStefano Zampini PetscFunctionBegin; 71808af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 7181b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 71828e61c736SStefano Zampini /* Reset previously computed graph */ 71838e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 7184674ae819SStefano Zampini /* Init local Graph struct */ 71857fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 718671582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 7187be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 7188674ae819SStefano Zampini 71897a0e7b2cSstefano_zampini if (pcbddc->user_primal_vertices_local && !pcbddc->user_primal_vertices) { 71907a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 71917a0e7b2cSstefano_zampini } 7192575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 71936080607fSStefano 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); 71949577ea80SStefano Zampini 7195674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 719666da6bd7Sstefano_zampini if (!pcbddc->mat_graph->xadj && pcbddc->use_local_adj) { 71974d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 71984d379d7bSStefano Zampini PetscInt nvtxs; 7199e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 7200674ae819SStefano Zampini 72012fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 72022fffb893SStefano Zampini if (flg_row) { 72034d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 7204b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 72052fffb893SStefano Zampini } 72062fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 720766da6bd7Sstefano_zampini rcsr = PETSC_TRUE; 7208674ae819SStefano Zampini } 72099b28b941SStefano Zampini if (pcbddc->dbg_flag) { 72109b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7211674ae819SStefano Zampini } 7212674ae819SStefano Zampini 7213ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cdim && !pcbddc->mat_graph->cloc) { 7214ab8c8b98SStefano Zampini PetscReal *lcoords; 7215ab8c8b98SStefano Zampini PetscInt n; 7216ab8c8b98SStefano Zampini MPI_Datatype dimrealtype; 7217ab8c8b98SStefano Zampini 72184f819b78SStefano Zampini /* TODO: support for blocked */ 7219ab8c8b98SStefano 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); 7220ab8c8b98SStefano Zampini ierr = MatGetLocalSize(matis->A,&n,NULL);CHKERRQ(ierr); 7221ab8c8b98SStefano Zampini ierr = PetscMalloc1(pcbddc->mat_graph->cdim*n,&lcoords);CHKERRQ(ierr); 7222ffc4695bSBarry Smith ierr = MPI_Type_contiguous(pcbddc->mat_graph->cdim,MPIU_REAL,&dimrealtype);CHKERRMPI(ierr); 7223ffc4695bSBarry Smith ierr = MPI_Type_commit(&dimrealtype);CHKERRMPI(ierr); 7224ab8c8b98SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 7225ab8c8b98SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 7226ffc4695bSBarry Smith ierr = MPI_Type_free(&dimrealtype);CHKERRMPI(ierr); 7227ab8c8b98SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->coords);CHKERRQ(ierr); 7228ab8c8b98SStefano Zampini 7229ab8c8b98SStefano Zampini pcbddc->mat_graph->coords = lcoords; 7230ab8c8b98SStefano Zampini pcbddc->mat_graph->cloc = PETSC_TRUE; 7231ab8c8b98SStefano Zampini pcbddc->mat_graph->cnloc = n; 7232ab8c8b98SStefano Zampini } 7233ab8c8b98SStefano 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); 72341c7a958bSStefano Zampini pcbddc->mat_graph->active_coords = (PetscBool)(pcbddc->corner_selection && !pcbddc->corner_selected); 7235ab8c8b98SStefano Zampini 7236674ae819SStefano Zampini /* Setup of Graph */ 72374b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 723814f95afaSStefano 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); 7239674ae819SStefano Zampini 72404f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 72414f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 724220c3699dSStefano Zampini PetscInt *local_subs,n,totn; 72434f1b2e48SStefano Zampini 724420c3699dSStefano Zampini ierr = MatGetLocalSize(matis->A,&n,NULL);CHKERRQ(ierr); 724520c3699dSStefano Zampini ierr = PetscMalloc1(n,&local_subs);CHKERRQ(ierr); 724620c3699dSStefano Zampini for (i=0;i<n;i++) local_subs[i] = pcbddc->n_local_subs; 72474f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 72484f1b2e48SStefano Zampini const PetscInt *idxs; 72494f1b2e48SStefano Zampini PetscInt nl,j; 72504f1b2e48SStefano Zampini 72514f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 72524f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 725371582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 72544f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 72554f1b2e48SStefano Zampini } 725620c3699dSStefano Zampini for (i=0,totn=0;i<n;i++) totn = PetscMax(totn,local_subs[i]); 725720c3699dSStefano Zampini pcbddc->mat_graph->n_local_subs = totn + 1; 72584f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 72594f1b2e48SStefano Zampini } 72608af8fcf9SStefano Zampini } 72614f1b2e48SStefano Zampini 7262cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 7263674ae819SStefano Zampini /* Graph's connected components analysis */ 7264674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 726571582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 72664f819b78SStefano Zampini pcbddc->corner_selected = pcbddc->corner_selection; 72678af8fcf9SStefano Zampini } 726866da6bd7Sstefano_zampini if (rcsr) pcbddc->mat_graph->nvtxs_csr = 0; 7269674ae819SStefano Zampini PetscFunctionReturn(0); 7270674ae819SStefano Zampini } 7271674ae819SStefano Zampini 7272295df10fSStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt *nio, Vec vecs[]) 72739a7d3425SStefano Zampini { 7274295df10fSStefano Zampini PetscInt i,j,n; 72759a7d3425SStefano Zampini PetscScalar *alphas; 7276295df10fSStefano Zampini PetscReal norm,*onorms; 72779a7d3425SStefano Zampini PetscErrorCode ierr; 72789a7d3425SStefano Zampini 72799a7d3425SStefano Zampini PetscFunctionBegin; 7280295df10fSStefano Zampini n = *nio; 72818c0031efSStefano Zampini if (!n) PetscFunctionReturn(0); 7282295df10fSStefano Zampini ierr = PetscMalloc2(n,&alphas,n,&onorms);CHKERRQ(ierr); 728392cccca0SStefano Zampini ierr = VecNormalize(vecs[0],&norm);CHKERRQ(ierr); 728492cccca0SStefano Zampini if (norm < PETSC_SMALL) { 7285295df10fSStefano Zampini onorms[0] = 0.0; 728692cccca0SStefano Zampini ierr = VecSet(vecs[0],0.0);CHKERRQ(ierr); 7287295df10fSStefano Zampini } else { 7288295df10fSStefano Zampini onorms[0] = norm; 728992cccca0SStefano Zampini } 7290295df10fSStefano Zampini 72918c0031efSStefano Zampini for (i=1;i<n;i++) { 72928c0031efSStefano Zampini ierr = VecMDot(vecs[i],i,vecs,alphas);CHKERRQ(ierr); 72938c0031efSStefano Zampini for (j=0;j<i;j++) alphas[j] = PetscConj(-alphas[j]); 72948c0031efSStefano Zampini ierr = VecMAXPY(vecs[i],i,alphas,vecs);CHKERRQ(ierr); 729592cccca0SStefano Zampini ierr = VecNormalize(vecs[i],&norm);CHKERRQ(ierr); 729692cccca0SStefano Zampini if (norm < PETSC_SMALL) { 7297295df10fSStefano Zampini onorms[i] = 0.0; 729892cccca0SStefano Zampini ierr = VecSet(vecs[i],0.0);CHKERRQ(ierr); 7299295df10fSStefano Zampini } else { 7300295df10fSStefano Zampini onorms[i] = norm; 730192cccca0SStefano Zampini } 73029a7d3425SStefano Zampini } 7303295df10fSStefano Zampini /* push nonzero vectors at the beginning */ 7304295df10fSStefano Zampini for (i=0;i<n;i++) { 7305295df10fSStefano Zampini if (onorms[i] == 0.0) { 7306295df10fSStefano Zampini for (j=i+1;j<n;j++) { 7307295df10fSStefano Zampini if (onorms[j] != 0.0) { 7308295df10fSStefano Zampini ierr = VecCopy(vecs[j],vecs[i]);CHKERRQ(ierr); 7309295df10fSStefano Zampini onorms[j] = 0.0; 7310295df10fSStefano Zampini } 7311295df10fSStefano Zampini } 7312295df10fSStefano Zampini } 7313295df10fSStefano Zampini } 7314295df10fSStefano Zampini for (i=0,*nio=0;i<n;i++) *nio += onorms[i] != 0.0 ? 1 : 0; 7315295df10fSStefano Zampini ierr = PetscFree2(alphas,onorms);CHKERRQ(ierr); 73169a7d3425SStefano Zampini PetscFunctionReturn(0); 73179a7d3425SStefano Zampini } 73189a7d3425SStefano Zampini 7319bb360cb4SStefano Zampini PetscErrorCode PCBDDCMatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 7320e7931f94SStefano Zampini { 732157de7509SStefano Zampini Mat A; 7322e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 7323e7931f94SStefano Zampini PetscMPIInt size,rank,color; 732452e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 732552e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 7326bb360cb4SStefano Zampini PetscInt im_active,active_procs,N,n,i,j,threshold = 2; 732757de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 732827b6a85dSStefano Zampini PetscInt xadj_count,*count; 732927b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 733027b6a85dSStefano Zampini PetscSubcomm psubcomm; 733127b6a85dSStefano Zampini MPI_Comm subcomm; 733252e5ac9dSStefano Zampini PetscErrorCode ierr; 7333a57a6d2fSStefano Zampini 7334e7931f94SStefano Zampini PetscFunctionBegin; 733557de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 733657de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7337fbfcfee5SBarry 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); 733857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 733957de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 73406080607fSStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %D",*n_subdomains); 734157de7509SStefano Zampini 734257de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 7343ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRMPI(ierr); 7344ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRMPI(ierr); 734557de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 734657de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 7347bb360cb4SStefano Zampini im_active = !!n; 734857de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 734957de7509SStefano Zampini void_procs = size - active_procs; 735057de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 735157de7509SStefano Zampini if (void_procs) { 735257de7509SStefano Zampini PetscInt ncand; 735357de7509SStefano Zampini 735457de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 735557de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 7356ffc4695bSBarry Smith ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRMPI(ierr); 735757de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 735857de7509SStefano Zampini if (!procs_candidates[i]) { 735957de7509SStefano Zampini procs_candidates[ncand++] = i; 736057de7509SStefano Zampini } 736157de7509SStefano Zampini } 736257de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 736357de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 736457de7509SStefano Zampini } 736557de7509SStefano Zampini 7366bb360cb4SStefano Zampini /* number of subdomains requested greater than active processes or matrix size -> just shift the matrix 736714f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 7368bb360cb4SStefano Zampini ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 7369bb360cb4SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1 || N <= *n_subdomains) { 737014f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 737114f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 737214f0bfb9SStefano Zampini else dest = rank; 737357de7509SStefano Zampini if (im_active) { 737457de7509SStefano Zampini issize = 1; 737557de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 737614f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 737757de7509SStefano Zampini } else { 737814f0bfb9SStefano Zampini isidx = dest; 737957de7509SStefano Zampini } 738057de7509SStefano Zampini } else { 738157de7509SStefano Zampini issize = 0; 738257de7509SStefano Zampini isidx = -1; 738357de7509SStefano Zampini } 7384bb360cb4SStefano Zampini if (*n_subdomains != 1) *n_subdomains = active_procs; 738557de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 7386daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 738757de7509SStefano Zampini PetscFunctionReturn(0); 738857de7509SStefano Zampini } 7389c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 7390c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 739127b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 7392e7931f94SStefano Zampini 7393e7931f94SStefano Zampini /* Get info on mapping */ 73943bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 7395e7931f94SStefano Zampini 7396e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 7397785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 7398e7931f94SStefano Zampini xadj[0] = 0; 7399e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 7400785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 7401785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 7402bb360cb4SStefano Zampini ierr = PetscCalloc1(n,&count);CHKERRQ(ierr); 740327b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 740427b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 740527b6a85dSStefano Zampini count[shared[i][j]] += 1; 7406e7931f94SStefano Zampini 740727b6a85dSStefano Zampini xadj_count = 0; 74082b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 740927b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 741027b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 7411d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 7412d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 7413d023bfaeSStefano Zampini xadj_count++; 741427b6a85dSStefano Zampini break; 741527b6a85dSStefano Zampini } 7416e7931f94SStefano Zampini } 7417e7931f94SStefano Zampini } 7418d023bfaeSStefano Zampini xadj[1] = xadj_count; 741927b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 74203bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 7421e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 7422e7931f94SStefano Zampini 74233837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 7424e7931f94SStefano Zampini 742527b6a85dSStefano Zampini /* Restrict work on active processes only */ 742627b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 742727b6a85dSStefano Zampini if (void_procs) { 742827b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 742927b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 743027b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 743127b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 743227b6a85dSStefano Zampini } else { 743327b6a85dSStefano Zampini psubcomm = NULL; 743427b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 743527b6a85dSStefano Zampini } 743627b6a85dSStefano Zampini 743727b6a85dSStefano Zampini v_wgt = NULL; 743827b6a85dSStefano Zampini if (!color) { 7439e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 7440e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 7441e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7442c8587f34SStefano Zampini } else { 744352e5ac9dSStefano Zampini Mat subdomain_adj; 744452e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 744552e5ac9dSStefano Zampini MatPartitioning partitioner; 744627b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 744752e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 744857de7509SStefano Zampini PetscMPIInt size; 7449b0c7d250SStefano Zampini PetscBool aggregate; 7450b0c7d250SStefano Zampini 7451ffc4695bSBarry Smith ierr = MPI_Comm_size(subcomm,&size);CHKERRMPI(ierr); 745227b6a85dSStefano Zampini if (void_procs) { 745327b6a85dSStefano Zampini PetscInt prank = rank; 7454785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 7455ffc4695bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRMPI(ierr); 7456e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 7457e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 7458c8587f34SStefano Zampini } 7459e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 746027b6a85dSStefano Zampini } else { 746127b6a85dSStefano Zampini oldranks = NULL; 746227b6a85dSStefano Zampini } 7463b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 746427b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 7465b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 7466b0c7d250SStefano Zampini PetscMPIInt nrank; 7467b0c7d250SStefano Zampini PetscScalar *vals; 7468b0c7d250SStefano Zampini 7469ffc4695bSBarry Smith ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRMPI(ierr); 7470b0c7d250SStefano Zampini lrows = 0; 7471b0c7d250SStefano Zampini if (nrank<redprocs) { 7472b0c7d250SStefano Zampini lrows = size/redprocs; 7473b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 7474b0c7d250SStefano Zampini } 747527b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 7476b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 7477b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7478b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7479b0c7d250SStefano Zampini row = nrank; 7480b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 7481b0c7d250SStefano Zampini cols = adjncy; 7482b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 7483b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 7484b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 7485b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7486b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 748752e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 748852e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 748952e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7490b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 749127b6a85dSStefano Zampini if (use_vwgt) { 749227b6a85dSStefano Zampini Vec v; 749327b6a85dSStefano Zampini const PetscScalar *array; 749427b6a85dSStefano Zampini PetscInt nl; 749527b6a85dSStefano Zampini 749627b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 7497bb360cb4SStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)n,INSERT_VALUES);CHKERRQ(ierr); 749827b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 749927b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 750027b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 750127b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 750227b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 750322db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 750427b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 750527b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 750627b6a85dSStefano Zampini } 7507b0c7d250SStefano Zampini } else { 750827b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 750927b6a85dSStefano Zampini if (use_vwgt) { 751027b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 7511bb360cb4SStefano Zampini v_wgt[0] = n; 751227b6a85dSStefano Zampini } 7513b0c7d250SStefano Zampini } 751422b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 7515e7931f94SStefano Zampini 7516e7931f94SStefano Zampini /* Partition */ 751727b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 7518ce64c636SStefano Zampini #if defined(PETSC_HAVE_PTSCOTCH) 7519ce64c636SStefano Zampini ierr = MatPartitioningSetType(partitioner,MATPARTITIONINGPTSCOTCH);CHKERRQ(ierr); 7520ce64c636SStefano Zampini #elif defined(PETSC_HAVE_PARMETIS) 7521ce64c636SStefano Zampini ierr = MatPartitioningSetType(partitioner,MATPARTITIONINGPARMETIS);CHKERRQ(ierr); 7522ce64c636SStefano Zampini #else 7523ce64c636SStefano Zampini ierr = MatPartitioningSetType(partitioner,MATPARTITIONINGAVERAGE);CHKERRQ(ierr); 7524ce64c636SStefano Zampini #endif 7525e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 752627b6a85dSStefano Zampini if (v_wgt) { 7527e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 7528c8587f34SStefano Zampini } 752957de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 753057de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 7531e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 7532e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 753322b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 7534e7931f94SStefano Zampini 753552e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 75366583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 753752e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 753852e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 753957de7509SStefano Zampini if (!aggregate) { 754057de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 7541cf9c20a2SJed Brown if (PetscUnlikelyDebug(!oldranks)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 754257de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 754327b6a85dSStefano Zampini } else if (oldranks) { 7544b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 754527b6a85dSStefano Zampini } else { 754627b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 754757de7509SStefano Zampini } 754828143c3dSStefano Zampini } else { 75497fb8a5e4SKarl Rupp PetscInt idx = 0; 7550b0c7d250SStefano Zampini PetscMPIInt tag; 7551b0c7d250SStefano Zampini MPI_Request *reqs; 7552b0c7d250SStefano Zampini 7553b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 7554b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 7555b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 7556ffc4695bSBarry Smith ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRMPI(ierr); 755728143c3dSStefano Zampini } 7558ffc4695bSBarry Smith ierr = MPI_Recv(&idx,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRMPI(ierr); 7559ffc4695bSBarry Smith ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRMPI(ierr); 7560b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 756157de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 7562cf9c20a2SJed Brown if (PetscUnlikelyDebug(!oldranks)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 75637fb8a5e4SKarl Rupp ranks_send_to_idx[0] = procs_candidates[oldranks[idx]]; 756427b6a85dSStefano Zampini } else if (oldranks) { 75657fb8a5e4SKarl Rupp ranks_send_to_idx[0] = oldranks[idx]; 756627b6a85dSStefano Zampini } else { 75677fb8a5e4SKarl Rupp ranks_send_to_idx[0] = idx; 7568e7931f94SStefano Zampini } 756957de7509SStefano Zampini } 757052e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 7571e7931f94SStefano Zampini /* clean up */ 7572e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 757352e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 7574e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 7575e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 7576e7931f94SStefano Zampini } 757727b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 757857de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 7579e7931f94SStefano Zampini 7580e7931f94SStefano Zampini /* assemble parallel IS for sends */ 7581e7931f94SStefano Zampini i = 1; 758227b6a85dSStefano Zampini if (!color) i=0; 758357de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 7584e7931f94SStefano Zampini PetscFunctionReturn(0); 7585e7931f94SStefano Zampini } 7586e7931f94SStefano Zampini 7587e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 7588e7931f94SStefano Zampini 75891e0482f5SStefano 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[]) 7590e7931f94SStefano Zampini { 759170cf5478SStefano Zampini Mat local_mat; 7592e7931f94SStefano Zampini IS is_sends_internal; 75939d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 75941ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 75959d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 7596e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 7597e7931f94SStefano Zampini PetscInt* l2gmap_indices; 7598e7931f94SStefano Zampini const PetscInt* is_indices; 7599e7931f94SStefano Zampini MatType new_local_type; 7600e7931f94SStefano Zampini /* buffers */ 7601e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 760228143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 76039d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 76041683a169SBarry Smith PetscScalar *ptr_vals,*recv_buffer_vals; 76051683a169SBarry Smith const PetscScalar *send_buffer_vals; 76061ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 7607e7931f94SStefano Zampini /* MPI */ 760828143c3dSStefano Zampini MPI_Comm comm,comm_n; 760928143c3dSStefano Zampini PetscSubcomm subcomm; 7610e569e4e1SStefano Zampini PetscMPIInt n_sends,n_recvs,size; 761128143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 761228143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 76131ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 76141ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 76151ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 7616e7931f94SStefano Zampini PetscErrorCode ierr; 7617e7931f94SStefano Zampini 7618e7931f94SStefano Zampini PetscFunctionBegin; 761957de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7620e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7621fbfcfee5SBarry 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); 762257de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 762357de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 762457de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 762557de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 762657de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 76271ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 76281ae86dd6SStefano Zampini if (nvecs) { 76291ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 76301ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 76311ae86dd6SStefano Zampini } 763257de7509SStefano Zampini /* further checks */ 7633e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7634e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 7635e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 7636e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 7637e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 763857de7509SStefano Zampini if (reuse && *mat_n) { 763970cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 764057de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 764170cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 764228143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 764370cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 764470cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 764570cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 764670cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 764770cf5478SStefano Zampini } 7648e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 7649e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 765057de7509SStefano Zampini 7651e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 7652e7931f94SStefano Zampini if (!is_sends) { 765328143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 7654bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 7655c8587f34SStefano Zampini } else { 7656e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 7657e7931f94SStefano Zampini is_sends_internal = is_sends; 7658c8587f34SStefano Zampini } 7659e7931f94SStefano Zampini 7660e7931f94SStefano Zampini /* get comm */ 7661a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 7662e7931f94SStefano Zampini 7663e7931f94SStefano Zampini /* compute number of sends */ 7664e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 7665e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 7666e7931f94SStefano Zampini 7667e7931f94SStefano Zampini /* compute number of receives */ 7668ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 7669e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&iflags);CHKERRQ(ierr); 7670580bdb30SBarry Smith ierr = PetscArrayzero(iflags,size);CHKERRQ(ierr); 7671e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7672e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 7673e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 7674e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 7675e7931f94SStefano Zampini 767628143c3dSStefano Zampini /* restrict comm if requested */ 76770a545947SLisandro Dalcin subcomm = NULL; 767828143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 767928143c3dSStefano Zampini if (restrict_comm) { 7680779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 7681779c1cceSStefano Zampini 768228143c3dSStefano Zampini color = 0; 768353a05cb3SStefano Zampini if (restrict_full) { 768453a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 768553a05cb3SStefano Zampini } else { 768653a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 768753a05cb3SStefano Zampini } 7688b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 7689e569e4e1SStefano Zampini subcommsize = size - subcommsize; 769028143c3dSStefano Zampini /* check if reuse has been requested */ 769157de7509SStefano Zampini if (reuse) { 769228143c3dSStefano Zampini if (*mat_n) { 769328143c3dSStefano Zampini PetscMPIInt subcommsize2; 7694ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRMPI(ierr); 769528143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 769628143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 769728143c3dSStefano Zampini } else { 769828143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 769928143c3dSStefano Zampini } 770028143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 7701779c1cceSStefano Zampini PetscMPIInt rank; 7702779c1cceSStefano Zampini 7703ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 770428143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 770528143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 770628143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 7707306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 770828143c3dSStefano Zampini } 770928143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 771028143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 771128143c3dSStefano Zampini } else { 771228143c3dSStefano Zampini comm_n = comm; 771328143c3dSStefano Zampini } 771428143c3dSStefano Zampini 7715e7931f94SStefano Zampini /* prepare send/receive buffers */ 7716e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&ilengths_idxs);CHKERRQ(ierr); 7717580bdb30SBarry Smith ierr = PetscArrayzero(ilengths_idxs,size);CHKERRQ(ierr); 7718e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&ilengths_vals);CHKERRQ(ierr); 7719580bdb30SBarry Smith ierr = PetscArrayzero(ilengths_vals,size);CHKERRQ(ierr); 772028143c3dSStefano Zampini if (nis) { 7721e569e4e1SStefano Zampini ierr = PetscCalloc1(size,&ilengths_idxs_is);CHKERRQ(ierr); 772228143c3dSStefano Zampini } 7723e7931f94SStefano Zampini 772428143c3dSStefano Zampini /* Get data from local matrices */ 77256c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 7726e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 7727e7931f94SStefano Zampini /* 7728e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 7729e7931f94SStefano Zampini send_buffer_idxs should contain: 7730e7931f94SStefano Zampini - MatType_PRIVATE type 7731e7931f94SStefano Zampini - PetscInt size_of_l2gmap 7732e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 7733e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 7734e7931f94SStefano Zampini */ 77356c4ed002SBarry Smith else { 77361683a169SBarry Smith ierr = MatDenseGetArrayRead(local_mat,&send_buffer_vals);CHKERRQ(ierr); 77373bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 7738854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 7739e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 7740e7931f94SStefano Zampini send_buffer_idxs[1] = i; 77413bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7742580bdb30SBarry Smith ierr = PetscArraycpy(&send_buffer_idxs[2],ptr_idxs,i);CHKERRQ(ierr); 77433bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7744e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 7745e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7746e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 7747e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 7748c8587f34SStefano Zampini } 7749c8587f34SStefano Zampini } 7750e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 775128143c3dSStefano Zampini /* additional is (if any) */ 775228143c3dSStefano Zampini if (nis) { 775328143c3dSStefano Zampini PetscMPIInt psum; 775428143c3dSStefano Zampini PetscInt j; 775528143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 775628143c3dSStefano Zampini PetscInt plen; 775728143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 775828143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 775928143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 776028143c3dSStefano Zampini } 7761854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 776228143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 776328143c3dSStefano Zampini PetscInt plen; 776428143c3dSStefano Zampini const PetscInt *is_array_idxs; 776528143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 776628143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 776728143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 7768580bdb30SBarry Smith ierr = PetscArraycpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen);CHKERRQ(ierr); 776928143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 777028143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 777128143c3dSStefano Zampini } 777228143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 777328143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 777428143c3dSStefano Zampini } 777528143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 777628143c3dSStefano Zampini } 77773b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 777828143c3dSStefano Zampini 7779e7931f94SStefano Zampini buf_size_idxs = 0; 7780e7931f94SStefano Zampini buf_size_vals = 0; 778128143c3dSStefano Zampini buf_size_idxs_is = 0; 77821ae86dd6SStefano Zampini buf_size_vecs = 0; 7783e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7784e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 7785e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 778628143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 77871ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 7788e7931f94SStefano Zampini } 7789785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 7790785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 779195ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 77921ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 7793e7931f94SStefano Zampini 7794e7931f94SStefano Zampini /* get new tags for clean communications */ 7795e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 7796e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 779728143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 77981ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 7799e7931f94SStefano Zampini 7800e7931f94SStefano Zampini /* allocate for requests */ 7801785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 7802785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 780395ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 78041ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 7805785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 7806785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 780795ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 78081ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 7809e7931f94SStefano Zampini 7810e7931f94SStefano Zampini /* communications */ 7811e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7812e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 781328143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 78141ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 7815e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7816e7931f94SStefano Zampini source_dest = onodes[i]; 7817ffc4695bSBarry Smith ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRMPI(ierr); 7818ffc4695bSBarry Smith ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRMPI(ierr); 7819e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7820e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 782128143c3dSStefano Zampini if (nis) { 782257de7509SStefano Zampini source_dest = onodes_is[i]; 7823ffc4695bSBarry Smith ierr = MPI_Irecv(ptr_idxs_is,olengths_idxs_is[i],MPIU_INT,source_dest,tag_idxs_is,comm,&recv_req_idxs_is[i]);CHKERRMPI(ierr); 782428143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 782528143c3dSStefano Zampini } 78261ae86dd6SStefano Zampini if (nvecs) { 78271ae86dd6SStefano Zampini source_dest = onodes[i]; 7828ffc4695bSBarry Smith ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRMPI(ierr); 78291ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 78301ae86dd6SStefano Zampini } 7831e7931f94SStefano Zampini } 7832e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7833e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 7834ffc4695bSBarry Smith ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRMPI(ierr); 7835ffc4695bSBarry Smith ierr = MPI_Isend((PetscScalar*)send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRMPI(ierr); 783628143c3dSStefano Zampini if (nis) { 7837ffc4695bSBarry Smith 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]);CHKERRMPI(ierr); 783828143c3dSStefano Zampini } 78391ae86dd6SStefano Zampini if (nvecs) { 78401ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 7841ffc4695bSBarry Smith ierr = MPI_Isend(send_buffer_vecs,ilengths_idxs[source_dest]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&send_req_vecs[i]);CHKERRMPI(ierr); 78421ae86dd6SStefano Zampini } 7843e7931f94SStefano Zampini } 7844e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7845e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 7846e7931f94SStefano Zampini 7847e7931f94SStefano Zampini /* assemble new l2g map */ 7848ffc4695bSBarry Smith ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRMPI(ierr); 7849e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 78509d30be91SStefano Zampini new_local_rows = 0; 7851e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 78529d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7853e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7854e7931f94SStefano Zampini } 78559d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 7856e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 78579d30be91SStefano Zampini new_local_rows = 0; 7858e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7859580bdb30SBarry Smith ierr = PetscArraycpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,*(ptr_idxs+1));CHKERRQ(ierr); 78609d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7861e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7862e7931f94SStefano Zampini } 78639d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 78649d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 7865e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 7866e7931f94SStefano Zampini 7867e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 7868e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 7869e7931f94SStefano 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) */ 7870e7931f94SStefano Zampini if (n_recvs) { 787128143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 7872e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7873e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7874e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 7875e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 7876e7931f94SStefano Zampini break; 7877e7931f94SStefano Zampini } 7878e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7879e7931f94SStefano Zampini } 7880e7931f94SStefano Zampini switch (new_local_type_private) { 788128143c3dSStefano Zampini case MATDENSE_PRIVATE: 7882e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7883e7931f94SStefano Zampini bs = 1; 7884e7931f94SStefano Zampini break; 7885e7931f94SStefano Zampini case MATAIJ_PRIVATE: 7886e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7887e7931f94SStefano Zampini bs = 1; 7888e7931f94SStefano Zampini break; 7889e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 7890e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 7891e7931f94SStefano Zampini break; 7892e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 7893e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 7894e7931f94SStefano Zampini break; 7895e7931f94SStefano Zampini default: 7896fbfcfee5SBarry Smith SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,PETSC_FUNCTION_NAME); 7897e7931f94SStefano Zampini } 7898ed8ed4edSstefano_zampini } else { /* by default, new_local_type is seqaij */ 7899ed8ed4edSstefano_zampini new_local_type = MATSEQAIJ; 790028143c3dSStefano Zampini bs = 1; 7901e7931f94SStefano Zampini } 7902e7931f94SStefano Zampini 790370cf5478SStefano Zampini /* create MATIS object if needed */ 790457de7509SStefano Zampini if (!reuse) { 7905e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 7906e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 790770cf5478SStefano Zampini } else { 790870cf5478SStefano Zampini /* it also destroys the local matrices */ 790957de7509SStefano Zampini if (*mat_n) { 791070cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 791157de7509SStefano Zampini } else { /* this is a fake object */ 791257de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 791357de7509SStefano Zampini } 791470cf5478SStefano Zampini } 791570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 7916e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 79179d30be91SStefano Zampini 7918ffc4695bSBarry Smith ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRMPI(ierr); 79199d30be91SStefano Zampini 79209d30be91SStefano Zampini /* Global to local map of received indices */ 79219d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 79229d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 79239d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 79249d30be91SStefano Zampini 79259d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 79269d30be91SStefano Zampini buf_size_idxs = 0; 79279d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 79289d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 79299d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 79309d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 79319d30be91SStefano Zampini } 79329d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 79339d30be91SStefano Zampini 79349d30be91SStefano Zampini /* set preallocation */ 79359d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 79369d30be91SStefano Zampini if (!newisdense) { 79370a545947SLisandro Dalcin PetscInt *new_local_nnz=NULL; 79389d30be91SStefano Zampini 79399d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 79409d30be91SStefano Zampini if (n_recvs) { 79419d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 79429d30be91SStefano Zampini } 79439d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 79449d30be91SStefano Zampini PetscInt j; 79459d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 79469d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 79479d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 79489d30be91SStefano Zampini } 79499d30be91SStefano Zampini } else { 79509d30be91SStefano Zampini /* TODO */ 79519d30be91SStefano Zampini } 79529d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 79539d30be91SStefano Zampini } 79549d30be91SStefano Zampini if (new_local_nnz) { 79559d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 79569d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 79579d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 79589d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 79599d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 79609d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 79619d30be91SStefano Zampini } else { 79629d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 79639d30be91SStefano Zampini } 79649d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 79659d30be91SStefano Zampini } else { 79669d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 79679d30be91SStefano Zampini } 7968e7931f94SStefano Zampini 7969e7931f94SStefano Zampini /* set values */ 7970e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 79719d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 7972e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7973e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 7974e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 79759d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 7976e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7977e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7978e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 797928143c3dSStefano Zampini } else { 798028143c3dSStefano Zampini /* TODO */ 7981e7931f94SStefano Zampini } 7982e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7983e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 7984e7931f94SStefano Zampini } 7985e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7986e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 79873b3b1effSJed Brown ierr = MatISRestoreLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 798870cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 798970cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 79909d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 7991e7931f94SStefano Zampini 7992dfd14d43SStefano Zampini #if 0 799328143c3dSStefano Zampini if (!restrict_comm) { /* check */ 7994e7931f94SStefano Zampini Vec lvec,rvec; 7995e7931f94SStefano Zampini PetscReal infty_error; 7996e7931f94SStefano Zampini 79972a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 7998e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 7999e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 8000e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 800170cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 8002e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 8003e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 8004e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 8005e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 8006e7931f94SStefano Zampini } 800728143c3dSStefano Zampini #endif 8008e7931f94SStefano Zampini 800928143c3dSStefano Zampini /* assemble new additional is (if any) */ 801028143c3dSStefano Zampini if (nis) { 801128143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 801228143c3dSStefano Zampini 8013ffc4695bSBarry Smith ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRMPI(ierr); 8014854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 801528143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 801628143c3dSStefano Zampini psum = 0; 801728143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 801828143c3dSStefano Zampini for (j=0;j<nis;j++) { 801928143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 802028143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 802128143c3dSStefano Zampini psum += plen; 802228143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 802328143c3dSStefano Zampini } 802428143c3dSStefano Zampini } 8025854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 8026854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 802728143c3dSStefano Zampini for (i=1;i<nis;i++) { 802828143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 802928143c3dSStefano Zampini } 8030580bdb30SBarry Smith ierr = PetscArrayzero(count_is,nis);CHKERRQ(ierr); 803128143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 803228143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 803328143c3dSStefano Zampini for (j=0;j<nis;j++) { 803428143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 8035580bdb30SBarry Smith ierr = PetscArraycpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen);CHKERRQ(ierr); 803628143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 803728143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 803828143c3dSStefano Zampini } 803928143c3dSStefano Zampini } 804028143c3dSStefano Zampini for (i=0;i<nis;i++) { 804128143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 8042c3b366b1Sprj- ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr); 804328143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 804428143c3dSStefano Zampini } 804528143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 804628143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 804728143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 804828143c3dSStefano Zampini } 8049e7931f94SStefano Zampini /* free workspace */ 805028143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 8051ffc4695bSBarry Smith ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRMPI(ierr); 8052e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 8053ffc4695bSBarry Smith ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRMPI(ierr); 8054e7931f94SStefano Zampini if (isdense) { 8055e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 80561683a169SBarry Smith ierr = MatDenseRestoreArrayRead(local_mat,&send_buffer_vals);CHKERRQ(ierr); 80573b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 8058e7931f94SStefano Zampini } else { 8059e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 8060e7931f94SStefano Zampini } 806128143c3dSStefano Zampini if (nis) { 8062ffc4695bSBarry Smith ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRMPI(ierr); 806328143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 806428143c3dSStefano Zampini } 80651ae86dd6SStefano Zampini 80661ae86dd6SStefano Zampini if (nvecs) { 8067ffc4695bSBarry Smith ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRMPI(ierr); 8068ffc4695bSBarry Smith ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRMPI(ierr); 80691ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 80701ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 80711ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 80721ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 80731ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 80741ae86dd6SStefano Zampini /* set values */ 80751ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 80761ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 80771ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 80781ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 80791ae86dd6SStefano Zampini PetscInt j; 80801ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 80811ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 80821ae86dd6SStefano Zampini } 80831ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 80841ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 80851ae86dd6SStefano Zampini } 80861ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 80871ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 80881ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 80891ae86dd6SStefano Zampini } 80901ae86dd6SStefano Zampini 80911ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 80921ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 8093e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 8094e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 80951ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 809628143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 8097e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 8098e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 80991ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 810028143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 8101e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 8102e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 8103e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 8104e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 8105e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 810628143c3dSStefano Zampini if (nis) { 810728143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 810828143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 810928143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 811028143c3dSStefano Zampini } 811128143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 811228143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 811328143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 811428143c3dSStefano Zampini for (i=0;i<nis;i++) { 811528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 811628143c3dSStefano Zampini } 81171ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 81181ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 81191ae86dd6SStefano Zampini } 812053a05cb3SStefano Zampini *mat_n = NULL; 812128143c3dSStefano Zampini } 8122e7931f94SStefano Zampini PetscFunctionReturn(0); 8123e7931f94SStefano Zampini } 8124a57a6d2fSStefano Zampini 812512edc857SStefano Zampini /* temporary hack into ksp private data structure */ 8126af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 812712edc857SStefano Zampini 8128c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 8129c8587f34SStefano Zampini { 8130c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 8131c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 813220a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 81331ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 81341e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 81359881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 813620a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 81374f819b78SStefano Zampini IS coarse_is,*isarray,corners; 81386e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 813930368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 8140e569e4e1SStefano Zampini PetscInt coarse_eqs_per_proc; 8141f9eb5b7dSStefano Zampini PC pc_temp; 8142c8587f34SStefano Zampini PCType coarse_pc_type; 8143c8587f34SStefano Zampini KSPType coarse_ksp_type; 8144f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 81457274672aSStefano Zampini PetscBool coarse_reuse; 81461e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 814768457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 814822bc73bbSStefano Zampini PetscScalar *array; 814957de7509SStefano Zampini MatReuse coarse_mat_reuse; 815057de7509SStefano Zampini PetscBool restr, full_restr, have_void; 8151e569e4e1SStefano Zampini PetscMPIInt size; 81529881197aSStefano Zampini PetscErrorCode ierr; 8153fdc09c96SStefano Zampini 8154c8587f34SStefano Zampini PetscFunctionBegin; 815543371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CoarseSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8156c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 815768457ee5SStefano 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 */ 8158fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 81595a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 81607de4f681Sstefano_zampini 81617de4f681Sstefano_zampini pcbddc->new_primal_space = PETSC_TRUE; 8162fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 8163f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 8164f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 8165f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 8166fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 816751bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 816851bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 8169727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 8170fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 8171fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 8172fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 8173f4ddd8eeSStefano Zampini } 8174fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 8175fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 8176f4ddd8eeSStefano Zampini } 817770cf5478SStefano Zampini /* reset any subassembling information */ 817857de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 817970cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 818057de7509SStefano Zampini } 81816e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 8182fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 8183f4ddd8eeSStefano Zampini } 818457de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 818557de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 818657de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 818757de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 818818a45a71SStefano Zampini } else { 818957de7509SStefano Zampini coarse_mat = NULL; 819057de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 81916e683305SStefano Zampini } 8192e7931f94SStefano Zampini 8193abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 8194abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 8195abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 8196abbbba34SStefano Zampini 8197abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 81984f819b78SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_submat_dense);CHKERRQ(ierr); 8199e176bc59SStefano 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); 82006e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 82016e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 82026e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 8203abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 8204abbbba34SStefano Zampini 820557de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 820657de7509SStefano Zampini im_active = !!(pcis->n); 820757de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 820857de7509SStefano Zampini 820914f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 821028d58a37SPierre Jolivet /* restr : whether we want to exclude senders (which are not receivers) from the subassembling pattern */ 821157de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 8212ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr); 821357de7509SStefano Zampini coarse_mat_is = NULL; 821457de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 821557de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 8216e569e4e1SStefano Zampini coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 8217ce64c636SStefano Zampini if (coarse_eqs_per_proc < 0) coarse_eqs_per_proc = pcbddc->coarse_size; 821857de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 8219e569e4e1SStefano Zampini if (pcbddc->coarse_size <= pcbddc->coarse_eqs_limit) multilevel_requested = PETSC_FALSE; 822057de7509SStefano Zampini if (multilevel_requested) { 822157de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 822257de7509SStefano Zampini restr = PETSC_FALSE; 822357de7509SStefano Zampini full_restr = PETSC_FALSE; 822457de7509SStefano Zampini } else { 8225e569e4e1SStefano Zampini ncoarse = pcbddc->coarse_size/coarse_eqs_per_proc + !!(pcbddc->coarse_size%coarse_eqs_per_proc); 822657de7509SStefano Zampini restr = PETSC_TRUE; 822757de7509SStefano Zampini full_restr = PETSC_TRUE; 822857de7509SStefano Zampini } 8229e569e4e1SStefano Zampini if (!pcbddc->coarse_size || size == 1) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 823057de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 823157de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 8232a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 8233bb360cb4SStefano Zampini if (multilevel_requested) { 8234bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 8235bb360cb4SStefano Zampini } else { 8236bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 8237bb360cb4SStefano Zampini } 8238a198735bSStefano Zampini } else { 82397de4f681Sstefano_zampini PetscMPIInt rank; 824028d58a37SPierre Jolivet 8241ffc4695bSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRMPI(ierr); 8242e569e4e1SStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 8243a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 8244a198735bSStefano Zampini } 824557de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 824657de7509SStefano Zampini PetscInt psum; 824757de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 824857de7509SStefano Zampini else psum = 0; 824957de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8250075e25bcSStefano Zampini have_void = ncoarse < size ? PETSC_TRUE : PETSC_FALSE; 825157de7509SStefano Zampini } 825257de7509SStefano Zampini /* determine if we can go multilevel */ 825357de7509SStefano Zampini if (multilevel_requested) { 825457de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 825557de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 825657de7509SStefano Zampini } 825757de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 825857de7509SStefano Zampini 8259e4d548c7SStefano Zampini /* dump subassembling pattern */ 8260e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 8261e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 8262e4d548c7SStefano Zampini } 82636e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 82641e0482f5SStefano Zampini nedcfield = -1; 82654f819b78SStefano Zampini corners = NULL; 82668966356dSPierre Jolivet if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal || pcbddc->corner_selected)) { /* protects from unneeded computations */ 82676e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 82686e683305SStefano Zampini const PetscInt *idxs; 82696e683305SStefano Zampini ISLocalToGlobalMapping tmap; 82706e683305SStefano Zampini 82716e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 82720be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 82736e683305SStefano Zampini /* allocate space for temporary storage */ 8274854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 8275854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 82766e683305SStefano Zampini /* allocate for IS array */ 82776e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 82781e0482f5SStefano Zampini if (pcbddc->nedclocal) { 82791e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 82801e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 82811e0482f5SStefano Zampini } else { 82821e0482f5SStefano Zampini nedcfield = 0; 82836080607fSStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%D)",nisdofs); 82841e0482f5SStefano Zampini nisdofs = 1; 82851e0482f5SStefano Zampini } 82861e0482f5SStefano Zampini } 82876e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 828827b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 828930368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 8290854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 82916e683305SStefano Zampini /* dofs splitting */ 82926e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 82936e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 82941e0482f5SStefano Zampini if (nedcfield != i) { 82956e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 82966e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 82976e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 82986e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 82991e0482f5SStefano Zampini } else { 83001e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 83011e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 83021e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 83036080607fSStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %D != %D",tsize,nout); 83041e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 83051e0482f5SStefano Zampini } 83066e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 830730368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 83086e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 83096e683305SStefano Zampini } 83106e683305SStefano Zampini /* neumann boundaries */ 83116e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 83126e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 83136e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 83146e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 83156e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 83166e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 83176e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 831830368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 83196e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 83206e683305SStefano Zampini } 83214f819b78SStefano Zampini /* coordinates */ 83224f819b78SStefano Zampini if (pcbddc->corner_selected) { 83234f819b78SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&corners);CHKERRQ(ierr); 83244f819b78SStefano Zampini ierr = ISGetLocalSize(corners,&tsize);CHKERRQ(ierr); 83254f819b78SStefano Zampini ierr = ISGetIndices(corners,&idxs);CHKERRQ(ierr); 83264f819b78SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 83274f819b78SStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping corners! %D != %D",tsize,nout); 83284f819b78SStefano Zampini ierr = ISRestoreIndices(corners,&idxs);CHKERRQ(ierr); 83294f819b78SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&corners);CHKERRQ(ierr); 83304f819b78SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 83314f819b78SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&corners);CHKERRQ(ierr); 83324f819b78SStefano Zampini } 83336e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 83346e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 83356e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 83366e683305SStefano Zampini } else { 83376e683305SStefano Zampini nis = 0; 83386e683305SStefano Zampini nisdofs = 0; 83396e683305SStefano Zampini nisneu = 0; 834030368db7SStefano Zampini nisvert = 0; 83416e683305SStefano Zampini isarray = NULL; 83426e683305SStefano Zampini } 83436e683305SStefano Zampini /* destroy no longer needed map */ 83446e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 83456e683305SStefano Zampini 834657de7509SStefano Zampini /* subassemble */ 834757de7509SStefano Zampini if (multilevel_allowed) { 83481ae86dd6SStefano Zampini Vec vp[1]; 83491ae86dd6SStefano Zampini PetscInt nvecs = 0; 835057de7509SStefano Zampini PetscBool reuse,reuser; 83511ae86dd6SStefano Zampini 835257de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 835357de7509SStefano Zampini else reuse = PETSC_FALSE; 835457de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 83551ae86dd6SStefano Zampini vp[0] = NULL; 83561ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 83571ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 83581ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 83591ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 83601ae86dd6SStefano Zampini nvecs = 1; 83611ae86dd6SStefano Zampini 83621ae86dd6SStefano Zampini if (pcbddc->divudotp) { 8363a198735bSStefano Zampini Mat B,loc_divudotp; 83641ae86dd6SStefano Zampini Vec v,p; 83651ae86dd6SStefano Zampini IS dummy; 83661ae86dd6SStefano Zampini PetscInt np; 83671ae86dd6SStefano Zampini 8368a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 8369a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 83701ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 83717dae84e0SHong Zhang ierr = MatCreateSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 83721ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 83731ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 83741ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 83751ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 83761ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 83771ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 83781ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 83791ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 83801ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 83811ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 83821ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 83831ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 838474e2c79eSStefano Zampini } 83851ae86dd6SStefano Zampini } 83861ae86dd6SStefano Zampini if (reuser) { 83871e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 838874e2c79eSStefano Zampini } else { 83891e0482f5SStefano 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); 83901ae86dd6SStefano Zampini } 83911ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 83921683a169SBarry Smith PetscScalar *arraym; 83931683a169SBarry Smith const PetscScalar *arrayv; 83941ae86dd6SStefano Zampini PetscInt nl; 83951ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 83961ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 83971ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 83981683a169SBarry Smith ierr = VecGetArrayRead(vp[0],&arrayv);CHKERRQ(ierr); 8399580bdb30SBarry Smith ierr = PetscArraycpy(arraym,arrayv,nl);CHKERRQ(ierr); 84001683a169SBarry Smith ierr = VecRestoreArrayRead(vp[0],&arrayv);CHKERRQ(ierr); 84011ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 84021ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 8403a198735bSStefano Zampini } else { 8404a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 84051ae86dd6SStefano Zampini } 84061ae86dd6SStefano Zampini } else { 84071e0482f5SStefano 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); 84086e683305SStefano Zampini } 840957de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 841057de7509SStefano Zampini if (!multilevel_allowed) { 8411487b449aSStefano Zampini ierr = MatConvert(coarse_mat_is,MATAIJ,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 84126e683305SStefano Zampini } else { 841357de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 841457de7509SStefano Zampini if (coarse_mat_is) { 841557de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 841657de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 841757de7509SStefano Zampini coarse_mat = coarse_mat_is; 841857de7509SStefano Zampini } 8419779c1cceSStefano Zampini } 8420779c1cceSStefano Zampini } 842157de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 842257de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 84236e683305SStefano Zampini 84246e683305SStefano Zampini /* create local to global scatters for coarse problem */ 842568457ee5SStefano Zampini if (compute_vecs) { 84266e683305SStefano Zampini PetscInt lrows; 84276e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 842857de7509SStefano Zampini if (coarse_mat) { 842957de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 84306e683305SStefano Zampini } else { 84316e683305SStefano Zampini lrows = 0; 84326e683305SStefano Zampini } 84336e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 84346e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 843589535278SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,coarse_mat ? coarse_mat->defaultvectype : VECSTANDARD);CHKERRQ(ierr); 84366e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 84379448b7f1SJunchao Zhang ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 84386e683305SStefano Zampini } 84396e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 8440c8587f34SStefano Zampini 8441f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 8442f9eb5b7dSStefano Zampini if (multilevel_allowed) { 8443f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 8444f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 8445f9eb5b7dSStefano Zampini } else { 8446f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 8447f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 8448c8587f34SStefano Zampini } 8449c8587f34SStefano Zampini 84506e683305SStefano Zampini /* print some info if requested */ 84516e683305SStefano Zampini if (pcbddc->dbg_flag) { 84526e683305SStefano Zampini if (!multilevel_allowed) { 84536e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 84546e683305SStefano Zampini if (multilevel_requested) { 84556080607fSStefano 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); 84566e683305SStefano Zampini } else if (pcbddc->max_levels) { 84576080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%D)\n",pcbddc->max_levels);CHKERRQ(ierr); 84586e683305SStefano Zampini } 84596e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 84606e683305SStefano Zampini } 84616e683305SStefano Zampini } 84626e683305SStefano Zampini 84631e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 84641e0482f5SStefano Zampini coarseG = NULL; 84651e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 84661e0482f5SStefano Zampini MPI_Comm ccomm; 84671e0482f5SStefano Zampini if (coarse_mat) { 84681e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 84691e0482f5SStefano Zampini } else { 84701e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 84711e0482f5SStefano Zampini } 84721e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 84731e0482f5SStefano Zampini } 84741e0482f5SStefano Zampini 8475f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 847657de7509SStefano Zampini if (coarse_mat) { 847728d58a37SPierre Jolivet PetscBool isredundant,isbddc,force,valid; 84786a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 84797274672aSStefano Zampini 84806e683305SStefano Zampini if (pcbddc->dbg_flag) { 848157de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 84826e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 84836e683305SStefano Zampini } 8484f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 8485312be037SStefano Zampini char prefix[256],str_level[16]; 8486e604994aSStefano Zampini size_t len; 84871e0482f5SStefano Zampini 848857de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 8489422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 8490c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 8491f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 849257de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8493c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 84946e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 8495c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 84961e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 8497c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8498e604994aSStefano Zampini /* prefix */ 8499e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 8500e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 8501e604994aSStefano Zampini if (!pcbddc->current_level) { 8502a126751eSBarry Smith ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,sizeof(prefix));CHKERRQ(ierr); 8503a126751eSBarry Smith ierr = PetscStrlcat(prefix,"pc_bddc_coarse_",sizeof(prefix));CHKERRQ(ierr); 8504c8587f34SStefano Zampini } else { 8505e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 8506312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 8507312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 8508a126751eSBarry Smith /* Nonstandard use of PetscStrncpy() to copy only a portion of the string */ 850934d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 851035529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 8511a126751eSBarry Smith ierr = PetscStrlcat(prefix,str_level,sizeof(prefix));CHKERRQ(ierr); 8512e604994aSStefano Zampini } 8513e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 85143e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 85153e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 85163e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 85173e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 8518f9eb5b7dSStefano Zampini /* allow user customization */ 8519f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 8520e569e4e1SStefano Zampini /* get some info after set from options */ 8521e569e4e1SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 852228d58a37SPierre Jolivet /* multilevel cannot be done with coarse PC different from BDDC, NN, HPDDM, unless forced to */ 852328d58a37SPierre Jolivet force = PETSC_FALSE; 852428d58a37SPierre Jolivet ierr = PetscOptionsGetBool(NULL,((PetscObject)pc_temp)->prefix,"-pc_type_forced",&force,NULL);CHKERRQ(ierr); 852528d58a37SPierre Jolivet ierr = PetscObjectTypeCompareAny((PetscObject)pc_temp,&valid,PCBDDC,PCNN,PCHPDDM,"");CHKERRQ(ierr); 8526e569e4e1SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 852728d58a37SPierre Jolivet if (multilevel_allowed && !force && !valid) { 8528e569e4e1SStefano Zampini isbddc = PETSC_TRUE; 8529e569e4e1SStefano Zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 8530e569e4e1SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 8531e569e4e1SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 8532e569e4e1SStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 85334f819b78SStefano Zampini if (pc_temp->ops->setfromoptions) { /* need to setfromoptions again, skipping the pc_type */ 85344f819b78SStefano Zampini ierr = PetscObjectOptionsBegin((PetscObject)pc_temp);CHKERRQ(ierr); 85354f819b78SStefano Zampini ierr = (*pc_temp->ops->setfromoptions)(PetscOptionsObject,pc_temp);CHKERRQ(ierr); 85364f819b78SStefano Zampini ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pc_temp);CHKERRQ(ierr); 85374f819b78SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 85384f819b78SStefano Zampini pc_temp->setfromoptionscalled++; 85394f819b78SStefano Zampini } 8540e569e4e1SStefano Zampini } 85413e3c6dadSStefano Zampini } 85423e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 854351bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 85443e3c6dadSStefano Zampini if (nisdofs) { 85453e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 85463e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 85473e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 85483e3c6dadSStefano Zampini } 85493e3c6dadSStefano Zampini } 85503e3c6dadSStefano Zampini if (nisneu) { 85513e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 85523e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 8553312be037SStefano Zampini } 855430368db7SStefano Zampini if (nisvert) { 855530368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 855630368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 855730368db7SStefano Zampini } 85581e0482f5SStefano Zampini if (coarseG) { 85591e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 85601e0482f5SStefano Zampini } 8561f9eb5b7dSStefano Zampini 8562f9eb5b7dSStefano Zampini /* get some info after set from options */ 8563f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 85644f819b78SStefano Zampini 8565b76f3995Sstefano_zampini /* multilevel can only be requested via -pc_bddc_levels or PCBDDCSetLevels */ 8566b76f3995Sstefano_zampini if (isbddc && !multilevel_allowed) { 8567f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8568f9eb5b7dSStefano Zampini } 856928d58a37SPierre Jolivet /* multilevel cannot be done with coarse PC different from BDDC, NN, HPDDM, unless forced to */ 857028d58a37SPierre Jolivet force = PETSC_FALSE; 857128d58a37SPierre Jolivet ierr = PetscOptionsGetBool(NULL,((PetscObject)pc_temp)->prefix,"-pc_type_forced",&force,NULL);CHKERRQ(ierr); 857228d58a37SPierre Jolivet ierr = PetscObjectTypeCompareAny((PetscObject)pc_temp,&valid,PCBDDC,PCNN,PCHPDDM,"");CHKERRQ(ierr); 857328d58a37SPierre Jolivet if (multilevel_requested && multilevel_allowed && !valid && !force) { 8574b76f3995Sstefano_zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 8575b76f3995Sstefano_zampini } 85767274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 85774f3a063dSStefano Zampini if (isredundant) { 85784f3a063dSStefano Zampini KSP inner_ksp; 85794f3a063dSStefano Zampini PC inner_pc; 85809326c5c6Sstefano_zampini 85814f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 85824f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 85834f3a063dSStefano Zampini } 8584f9eb5b7dSStefano Zampini 858557de7509SStefano Zampini /* parameters which miss an API */ 85867274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 858757de7509SStefano Zampini if (isbddc) { 8588720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 85897274672aSStefano Zampini 8590720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 859157de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 8592e569e4e1SStefano Zampini pcbddc_coarse->coarse_eqs_limit = pcbddc->coarse_eqs_limit; 859327b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 859427b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 8595a198735bSStefano Zampini Mat coarsedivudotp_is; 8596a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 8597a198735bSStefano Zampini IS row,col; 8598a198735bSStefano Zampini const PetscInt *gidxs; 8599a198735bSStefano Zampini PetscInt n,st,M,N; 8600a198735bSStefano Zampini 8601a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 8602ffc4695bSBarry Smith ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRMPI(ierr); 8603a198735bSStefano Zampini st = st-n; 8604a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 8605a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 8606a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 8607a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8608a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 8609a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8610a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 8611a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 8612a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 8613a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 8614a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 8615a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 8616a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 8617a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 8618a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 8619a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 8620a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 8621a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 8622a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 8623a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 86248ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 8625a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 8626720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 8627bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[0] == 0.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 8628720d30f9SStefano Zampini } 8629d4d8cf7bSStefano Zampini } 86309881197aSStefano Zampini 86313301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 86325a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 86333301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 86343301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 86353301b35fSStefano Zampini } 86363301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 86373301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 86383301b35fSStefano Zampini } 86393301b35fSStefano Zampini if (pc->pmat->spd_set) { 86403301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 86413301b35fSStefano Zampini } 864227b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 864327b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 864427b6a85dSStefano Zampini } 86456e683305SStefano Zampini /* set operators */ 864604fe1396SStefano Zampini ierr = MatViewFromOptions(coarse_mat,(PetscObject)pc,"-pc_bddc_coarse_mat_view");CHKERRQ(ierr); 86473007b4efSStefano Zampini ierr = MatSetOptionsPrefix(coarse_mat,((PetscObject)pcbddc->coarse_ksp)->prefix);CHKERRQ(ierr); 86485f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 86496e683305SStefano Zampini if (pcbddc->dbg_flag) { 86506e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 86516e683305SStefano Zampini } 86526e683305SStefano Zampini } 86531e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 86546e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 8655b1ecc7b1SStefano Zampini #if 0 8656b9b85e73SStefano Zampini { 8657b9b85e73SStefano Zampini PetscViewer viewer; 8658b9b85e73SStefano Zampini char filename[256]; 8659b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 8660b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 86616a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 8662b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 8663f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 8664b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 8665b9b85e73SStefano Zampini } 8666b9b85e73SStefano Zampini #endif 8667f9eb5b7dSStefano Zampini 86684f819b78SStefano Zampini if (corners) { 86694f819b78SStefano Zampini Vec gv; 86704f819b78SStefano Zampini IS is; 86714f819b78SStefano Zampini const PetscInt *idxs; 86724f819b78SStefano Zampini PetscInt i,d,N,n,cdim = pcbddc->mat_graph->cdim; 86734f819b78SStefano Zampini PetscScalar *coords; 86744f819b78SStefano Zampini 86754f819b78SStefano Zampini if (!pcbddc->mat_graph->cloc) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing local coordinates"); 86764f819b78SStefano Zampini ierr = VecGetSize(pcbddc->coarse_vec,&N);CHKERRQ(ierr); 86774f819b78SStefano Zampini ierr = VecGetLocalSize(pcbddc->coarse_vec,&n);CHKERRQ(ierr); 86784f819b78SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcbddc->coarse_vec),&gv);CHKERRQ(ierr); 86794f819b78SStefano Zampini ierr = VecSetBlockSize(gv,cdim);CHKERRQ(ierr); 86804f819b78SStefano Zampini ierr = VecSetSizes(gv,n*cdim,N*cdim);CHKERRQ(ierr); 86814f819b78SStefano Zampini ierr = VecSetType(gv,VECSTANDARD);CHKERRQ(ierr); 86824f819b78SStefano Zampini ierr = VecSetFromOptions(gv);CHKERRQ(ierr); 86834f819b78SStefano Zampini ierr = VecSet(gv,PETSC_MAX_REAL);CHKERRQ(ierr); /* we only propagate coordinates from vertices constraints */ 86844f819b78SStefano Zampini 86854f819b78SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&is);CHKERRQ(ierr); 86864f819b78SStefano Zampini ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 86874f819b78SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 86884f819b78SStefano Zampini ierr = PetscMalloc1(n*cdim,&coords);CHKERRQ(ierr); 86894f819b78SStefano Zampini for (i=0;i<n;i++) { 86904f819b78SStefano Zampini for (d=0;d<cdim;d++) { 86914f819b78SStefano Zampini coords[cdim*i+d] = pcbddc->mat_graph->coords[cdim*idxs[i]+d]; 86924f819b78SStefano Zampini } 86934f819b78SStefano Zampini } 86944f819b78SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 86954f819b78SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&is);CHKERRQ(ierr); 86964f819b78SStefano Zampini 86974f819b78SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 86984f819b78SStefano Zampini ierr = ISGetIndices(corners,&idxs);CHKERRQ(ierr); 86994f819b78SStefano Zampini ierr = VecSetValuesBlocked(gv,n,idxs,coords,INSERT_VALUES);CHKERRQ(ierr); 87004f819b78SStefano Zampini ierr = ISRestoreIndices(corners,&idxs);CHKERRQ(ierr); 87014f819b78SStefano Zampini ierr = PetscFree(coords);CHKERRQ(ierr); 87024f819b78SStefano Zampini ierr = VecAssemblyBegin(gv);CHKERRQ(ierr); 87034f819b78SStefano Zampini ierr = VecAssemblyEnd(gv);CHKERRQ(ierr); 87044f819b78SStefano Zampini ierr = VecGetArray(gv,&coords);CHKERRQ(ierr); 87054f819b78SStefano Zampini if (pcbddc->coarse_ksp) { 87064f819b78SStefano Zampini PC coarse_pc; 87074f819b78SStefano Zampini PetscBool isbddc; 87084f819b78SStefano Zampini 87094f819b78SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 87104f819b78SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 87114f819b78SStefano Zampini if (isbddc) { /* coarse coordinates have PETSC_MAX_REAL, specific for BDDC */ 87124f819b78SStefano Zampini PetscReal *realcoords; 87134f819b78SStefano Zampini 87144f819b78SStefano Zampini ierr = VecGetLocalSize(gv,&n);CHKERRQ(ierr); 87154f819b78SStefano Zampini #if defined(PETSC_USE_COMPLEX) 87164f819b78SStefano Zampini ierr = PetscMalloc1(n,&realcoords);CHKERRQ(ierr); 87174f819b78SStefano Zampini for (i=0;i<n;i++) realcoords[i] = PetscRealPart(coords[i]); 87184f819b78SStefano Zampini #else 87194f819b78SStefano Zampini realcoords = coords; 87204f819b78SStefano Zampini #endif 87214f819b78SStefano Zampini ierr = PCSetCoordinates(coarse_pc,cdim,n/cdim,realcoords);CHKERRQ(ierr); 87224f819b78SStefano Zampini #if defined(PETSC_USE_COMPLEX) 87234f819b78SStefano Zampini ierr = PetscFree(realcoords);CHKERRQ(ierr); 87244f819b78SStefano Zampini #endif 87254f819b78SStefano Zampini } 87264f819b78SStefano Zampini } 87274f819b78SStefano Zampini ierr = VecRestoreArray(gv,&coords);CHKERRQ(ierr); 87284f819b78SStefano Zampini ierr = VecDestroy(&gv);CHKERRQ(ierr); 87294f819b78SStefano Zampini } 87304f819b78SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 87314f819b78SStefano Zampini 873298a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 873398a51de6SStefano Zampini Vec crhs,csol; 873404708bb6SStefano Zampini 8735f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 8736f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 8737f347579bSStefano Zampini if (!csol) { 87382a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 8739f9eb5b7dSStefano Zampini } 8740f347579bSStefano Zampini if (!crhs) { 87412a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 8742f347579bSStefano Zampini } 8743b0f5fe93SStefano Zampini } 87441ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 8745b0f5fe93SStefano Zampini 8746b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 8747b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 8748b0f5fe93SStefano Zampini 8749b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 87504f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 87514f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 87524f1b2e48SStefano Zampini } 8753b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 8754b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 8755b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8756b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8757b0f5fe93SStefano Zampini if (coarse_mat) { 8758b0f5fe93SStefano Zampini Vec nullv; 8759b0f5fe93SStefano Zampini PetscScalar *array,*array2; 8760b0f5fe93SStefano Zampini PetscInt nl; 8761b0f5fe93SStefano Zampini 8762b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 8763b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 8764b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8765b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 8766580bdb30SBarry Smith ierr = PetscArraycpy(array2,array,nl);CHKERRQ(ierr); 8767b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 8768b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8769b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 8770b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 8771b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 8772b0f5fe93SStefano Zampini } 8773b0f5fe93SStefano Zampini } 877443371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CoarseSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8775b0f5fe93SStefano Zampini 877643371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CoarseSolver[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8777b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 8778b0f5fe93SStefano Zampini PetscBool ispreonly; 8779b0f5fe93SStefano Zampini 8780b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8781b0f5fe93SStefano Zampini PetscBool isnull; 8782b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 8783bef83e63SStefano Zampini if (isnull) { 8784b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 8785b0f5fe93SStefano Zampini } 8786bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 8787b0f5fe93SStefano Zampini } 8788b0f5fe93SStefano Zampini /* setup coarse ksp */ 8789b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 8790cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 8791cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 87926e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates)) { 8793c8587f34SStefano Zampini KSP check_ksp; 87942b510759SStefano Zampini KSPType check_ksp_type; 8795c8587f34SStefano Zampini PC check_pc; 87966e683305SStefano Zampini Vec check_vec,coarse_vec; 87976a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 87982b510759SStefano Zampini PetscInt its; 87996e683305SStefano Zampini PetscBool compute_eigs; 88006e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 88016e683305SStefano Zampini PetscInt neigs; 88028e185a42SStefano Zampini const char *prefix; 8803c8587f34SStefano Zampini 88042b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 88056e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 880615579a77SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)check_ksp,(PetscObject)pcbddc->coarse_ksp,0);CHKERRQ(ierr); 8807399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 880823ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8809f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 8810e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 8811e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 8812e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 88132b510759SStefano Zampini if (ispreonly) { 88142b510759SStefano Zampini check_ksp_type = KSPPREONLY; 88156e683305SStefano Zampini compute_eigs = PETSC_FALSE; 88162b510759SStefano Zampini } else { 8817cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 88186e683305SStefano Zampini compute_eigs = PETSC_TRUE; 8819c8587f34SStefano Zampini } 8820c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 88216e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 88226e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 88236e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 8824a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 8825a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 8826a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 8827a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 8828c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 8829c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 8830c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 8831c8587f34SStefano Zampini /* create random vec */ 88322701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 8833c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 88346e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 8835c8587f34SStefano Zampini /* solve coarse problem */ 88366e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 8837c0decd05SBarry Smith ierr = KSPCheckSolve(check_ksp,pc,coarse_vec);CHKERRQ(ierr); 8838cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 88396e683305SStefano Zampini if (compute_eigs) { 8840854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 8841854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 88426e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 88431ae86dd6SStefano Zampini if (neigs) { 88446e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 88456e683305SStefano Zampini lambda_min = eigs_r[0]; 88466e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 88472701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 88482701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 8849cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 8850cbcc2c2aSStefano Zampini } 8851c8587f34SStefano Zampini } 8852c8587f34SStefano Zampini } 88531ae86dd6SStefano Zampini } 8854cbcc2c2aSStefano Zampini 8855c8587f34SStefano Zampini /* check coarse problem residual error */ 88566e683305SStefano Zampini if (pcbddc->dbg_flag) { 88576e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 88586e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 88596e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 8860c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 88616e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 88626e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 8863779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 88646e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 88656e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 88666e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 88676e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 8868b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8869b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 8870b0f5fe93SStefano Zampini } 88716e683305SStefano Zampini if (compute_eigs) { 88726e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 8873b03ebc13SStefano Zampini KSPConvergedReason reason; 8874deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 8875c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 8876b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 88776e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 8878b03ebc13SStefano 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); 88796e683305SStefano Zampini for (i=0;i<neigs;i++) { 88806e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 8881c8587f34SStefano Zampini } 88826e683305SStefano Zampini } 88836e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 88846e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 88856e683305SStefano Zampini } 8886e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 88872701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 8888c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 88896e683305SStefano Zampini if (compute_eigs) { 88906e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 88916e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 8892c8587f34SStefano Zampini } 88936e683305SStefano Zampini } 88946e683305SStefano Zampini } 8895bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 8896cbcc2c2aSStefano Zampini /* print additional info */ 8897cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 88986e683305SStefano Zampini /* waits until all processes reaches this point */ 88996e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 89006080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %D\n",pcbddc->current_level);CHKERRQ(ierr); 8901cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8902cbcc2c2aSStefano Zampini } 8903cbcc2c2aSStefano Zampini 89042b510759SStefano Zampini /* free memory */ 8905fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 890643371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CoarseSolver[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8907c8587f34SStefano Zampini PetscFunctionReturn(0); 8908c8587f34SStefano Zampini } 8909674ae819SStefano Zampini 8910f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 8911f34684f1SStefano Zampini { 8912f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8913f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 8914f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 8915dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 8916dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 891773be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 8918dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 8919f34684f1SStefano Zampini PetscErrorCode ierr; 8920f34684f1SStefano Zampini 8921f34684f1SStefano Zampini PetscFunctionBegin; 8922f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 89236c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 8924dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 89253bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 8926dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8927dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 89286583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 8929dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 8930dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 8931dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 89326c4ed002SBarry 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); 8933dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 8934dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8935580bdb30SBarry Smith ierr = PetscArraycpy(local_primal_indices,t_local_primal_indices,local_size);CHKERRQ(ierr); 8936dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8937dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8938f34684f1SStefano Zampini 8939f34684f1SStefano Zampini /* check numbering */ 8940f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 8941019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 8942dc456d91SStefano Zampini PetscInt i; 8943b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 8944f34684f1SStefano Zampini 8945f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8946f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8947f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 89481575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8949019a44ceSStefano Zampini /* counter */ 8950019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8951019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 8952019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8953019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8954019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8955019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8956f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 8957f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 8958727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 8959f34684f1SStefano Zampini } 8960f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8961f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8962f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8963e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8964e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8965e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8966e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8967f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8968019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8969f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8970019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 89712c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 897275c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 8973b9b85e73SStefano Zampini set_error = PETSC_TRUE; 89742c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 89756080607fSStefano 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); 8976f34684f1SStefano Zampini } 8977f34684f1SStefano Zampini } 8978019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8979b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8980f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8981f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8982f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 8983f34684f1SStefano Zampini } 8984f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8985f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8986e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8987e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8988f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 89896080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %D (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 8990b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 8991ca8b9ea9SStefano Zampini PetscInt *gidxs; 8992ca8b9ea9SStefano Zampini 8993ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 89943bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 8995f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 8996f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8997f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 8998f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 89996080607fSStefano 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); 9000f34684f1SStefano Zampini } 9001f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 9002ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 9003f34684f1SStefano Zampini } 9004f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 90051575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 9006302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 9007f34684f1SStefano Zampini } 90086080607fSStefano Zampini 9009f34684f1SStefano Zampini /* get back data */ 9010f34684f1SStefano Zampini *coarse_size_n = coarse_size; 9011f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 9012674ae819SStefano Zampini PetscFunctionReturn(0); 9013674ae819SStefano Zampini } 9014674ae819SStefano Zampini 9015a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 9016e456f2a8SStefano Zampini { 9017e456f2a8SStefano Zampini IS localis_t; 9018a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 9019e456f2a8SStefano Zampini PetscScalar *vals; 9020e456f2a8SStefano Zampini PetscErrorCode ierr; 9021e456f2a8SStefano Zampini 9022e456f2a8SStefano Zampini PetscFunctionBegin; 9023a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 9024e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 9025854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 9026e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 9027e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 9028a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 9029a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 90301035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 90313151afb1SStefano Zampini ierr = VecSetOption(gwork,VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE);CHKERRQ(ierr); 9032a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 90331035eff8SStefano Zampini } 9034a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 9035e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 9036e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 9037a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 9038a7dc3881SStefano Zampini /* now compute set in local ordering */ 9039a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9040a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9041a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 9042a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 9043a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 9044ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 9045e456f2a8SStefano Zampini lsize++; 9046e456f2a8SStefano Zampini } 9047e456f2a8SStefano Zampini } 9048854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 9049a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 9050ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 9051e456f2a8SStefano Zampini idxs[lsize++] = i; 9052e456f2a8SStefano Zampini } 9053e456f2a8SStefano Zampini } 9054a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 9055a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 9056e456f2a8SStefano Zampini *localis = localis_t; 9057e456f2a8SStefano Zampini PetscFunctionReturn(0); 9058e456f2a8SStefano Zampini } 9059906d46d4SStefano Zampini 906008122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 9061b96c3477SStefano Zampini { 9062a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 9063b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 9064b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 9065a64f4aa4SStefano Zampini Mat S_j; 9066b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 9067b96c3477SStefano Zampini PetscBool free_used_adj; 9068b96c3477SStefano Zampini PetscErrorCode ierr; 9069b96c3477SStefano Zampini 9070b96c3477SStefano Zampini PetscFunctionBegin; 907143371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Schurs[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 9072b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 9073b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 907408122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 9075b96c3477SStefano Zampini used_xadj = NULL; 9076b96c3477SStefano Zampini used_adjncy = NULL; 9077b96c3477SStefano Zampini } else { 907808122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 907908122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 908008122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 908108122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 9082b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 9083b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 9084b96c3477SStefano Zampini } else { 90852fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 9086b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 9087b96c3477SStefano Zampini PetscInt nvtxs; 9088b96c3477SStefano Zampini 90892fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 90902fffb893SStefano Zampini if (flg_row) { 9091b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 9092580bdb30SBarry Smith ierr = PetscArraycpy(used_xadj,xadj,nvtxs+1);CHKERRQ(ierr); 9093580bdb30SBarry Smith ierr = PetscArraycpy(used_adjncy,adjncy,xadj[nvtxs]);CHKERRQ(ierr); 9094b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 90952fffb893SStefano Zampini } else { 90962fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 90972fffb893SStefano Zampini used_xadj = NULL; 90982fffb893SStefano Zampini used_adjncy = NULL; 90992fffb893SStefano Zampini } 91002fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 9101b96c3477SStefano Zampini } 9102b96c3477SStefano Zampini } 9103d5574798SStefano Zampini 9104d5574798SStefano Zampini /* setup sub_schurs data */ 91052f37b69bSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->pA_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 9106df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 9107df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 9108a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 910991af6908SStefano 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); 9110a64f4aa4SStefano Zampini } else { 911172b8c272SStefano Zampini Mat change = NULL; 91129d54b7f4SStefano Zampini Vec scaling = NULL; 9113111315fdSstefano_zampini IS change_primal = NULL, iP; 9114111315fdSstefano_zampini PetscInt benign_n; 9115111315fdSstefano_zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 91167ebab0bbSStefano Zampini PetscBool need_change = PETSC_FALSE; 9117111315fdSstefano_zampini PetscBool discrete_harmonic = PETSC_FALSE; 9118a3df083aSStefano Zampini 91195feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 91205feab87aSStefano Zampini PetscInt n_vertices; 91215feab87aSStefano Zampini 91225feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 91232034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 91245feab87aSStefano Zampini } 9125a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 9126a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 9127ca92afb2SStefano Zampini } else { 9128a3df083aSStefano Zampini benign_n = 0; 9129ca92afb2SStefano Zampini } 9130b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 9131b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 9132b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 913372b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 913422db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 9135b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 913622db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 9137b7ab4a40SStefano Zampini } 9138b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 9139b7ab4a40SStefano 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 */ 9140b7ab4a40SStefano Zampini if (need_change) { 914188c03ad3SStefano Zampini PC_IS *pcisf; 914288c03ad3SStefano Zampini PC_BDDC *pcbddcf; 914388c03ad3SStefano Zampini PC pcf; 914488c03ad3SStefano Zampini 9145e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 914688c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 914788c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 914888c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 9149b9be95fcSstefano_zampini 915088c03ad3SStefano Zampini /* hacks */ 915188c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 915272b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 915372b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 915472b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 915572b8c272SStefano Zampini pcisf->n = pcis->n; 915672b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 915788c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 915888c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 915988c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 916088c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 916188c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 916288c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 916372b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 916488c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 9165b9be95fcSstefano_zampini 9166b9be95fcSstefano_zampini /* setup constraints so that we can get information on primal vertices and change of basis (in local numbering) */ 916788c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 916872b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 916972b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 917072b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 917172b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 9172b9be95fcSstefano_zampini 917388c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 917472b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 917588c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 917688c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 917788c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 917888c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 917988c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 918088c03ad3SStefano Zampini pcf->ops->destroy = NULL; 9181b9be95fcSstefano_zampini pcf->ops->reset = NULL; 918288c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 918388c03ad3SStefano Zampini } 91849d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 9185111315fdSstefano_zampini 9186111315fdSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 9187111315fdSstefano_zampini if (iP) { 9188111315fdSstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)iP),sub_schurs->prefix,"BDDC sub_schurs options","PC");CHKERRQ(ierr); 9189111315fdSstefano_zampini ierr = PetscOptionsBool("-sub_schurs_discrete_harmonic",NULL,NULL,discrete_harmonic,&discrete_harmonic,NULL);CHKERRQ(ierr); 9190111315fdSstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 9191111315fdSstefano_zampini } 9192111315fdSstefano_zampini if (discrete_harmonic) { 9193111315fdSstefano_zampini Mat A; 9194111315fdSstefano_zampini ierr = MatDuplicate(pcbddc->local_mat,MAT_COPY_VALUES,&A);CHKERRQ(ierr); 9195111315fdSstefano_zampini ierr = MatZeroRowsColumnsIS(A,iP,1.0,NULL,NULL);CHKERRQ(ierr); 9196111315fdSstefano_zampini ierr = PetscObjectCompose((PetscObject)A,"__KSPFETIDP_iP",(PetscObject)iP);CHKERRQ(ierr); 9197111315fdSstefano_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); 9198111315fdSstefano_zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 9199111315fdSstefano_zampini } else { 920091af6908SStefano 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); 9201111315fdSstefano_zampini } 920272b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 920372b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 9204ca92afb2SStefano Zampini } 9205d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 9206b96c3477SStefano Zampini 9207b96c3477SStefano Zampini /* free adjacency */ 9208b96c3477SStefano Zampini if (free_used_adj) { 9209b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 9210b96c3477SStefano Zampini } 921143371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Schurs[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 9212b96c3477SStefano Zampini PetscFunctionReturn(0); 9213b96c3477SStefano Zampini } 9214b96c3477SStefano Zampini 921508122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 9216b96c3477SStefano Zampini { 9217b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 9218b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 9219b96c3477SStefano Zampini PCBDDCGraph graph; 9220b96c3477SStefano Zampini PetscErrorCode ierr; 9221b96c3477SStefano Zampini 9222b96c3477SStefano Zampini PetscFunctionBegin; 9223b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 922408122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 92253301b35fSStefano Zampini IS verticesIS,verticescomm; 92263301b35fSStefano Zampini PetscInt vsize,*idxs; 9227b96c3477SStefano Zampini 9228b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 92293301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 92303301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 92313301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 92323301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 9233c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 9234b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 9235be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 9236441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 92373301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 9238b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 9239b96c3477SStefano Zampini } else { 9240b96c3477SStefano Zampini graph = pcbddc->mat_graph; 9241b96c3477SStefano Zampini } 9242e4d548c7SStefano Zampini /* print some info */ 92435c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 9244e4d548c7SStefano Zampini IS vertices; 9245e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 9246c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 9247e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 9248e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 9249e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 9250e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 92516080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%D)\n",PetscGlobalRank,(int)nv,pcbddc->use_vertices);CHKERRQ(ierr); 92526080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%D)\n",PetscGlobalRank,(int)nedges,pcbddc->use_edges);CHKERRQ(ierr); 92536080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%D)\n",PetscGlobalRank,(int)nfaces,pcbddc->use_faces);CHKERRQ(ierr); 9254e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 9255e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 9256c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 9257e4d548c7SStefano Zampini } 9258b96c3477SStefano Zampini 9259b96c3477SStefano Zampini /* sub_schurs init */ 9260b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 9261b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 9262b334f244SStefano Zampini } 926388113c35SStefano 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); 9264a64f4aa4SStefano Zampini 9265b96c3477SStefano Zampini /* free graph struct */ 926608122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 9267b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 9268b96c3477SStefano Zampini } 9269b96c3477SStefano Zampini PetscFunctionReturn(0); 9270b96c3477SStefano Zampini } 9271fa34dd3eSStefano Zampini 9272fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 9273fa34dd3eSStefano Zampini { 9274fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 9275fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 9276fa34dd3eSStefano Zampini PetscErrorCode ierr; 9277fa34dd3eSStefano Zampini 9278fa34dd3eSStefano Zampini PetscFunctionBegin; 9279fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 9280fa34dd3eSStefano Zampini IS zerodiag = NULL; 92814f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 9282fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 92834f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 928475c01103SStefano Zampini PetscReal norm; 9285fa34dd3eSStefano Zampini PetscInt i; 9286fa34dd3eSStefano Zampini 9287fa34dd3eSStefano Zampini /* B0 and B0_B */ 9288fa34dd3eSStefano Zampini if (zerodiag) { 9289fa34dd3eSStefano Zampini IS dummy; 9290fa34dd3eSStefano Zampini 92914f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 92927dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 9293fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 9294fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 9295fa34dd3eSStefano Zampini } 9296fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 9297fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 9298fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 9299fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9300fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9301fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9302fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9303fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 9304fa34dd3eSStefano Zampini /* S_j */ 93052f37b69bSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->pA_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 9306fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 9307fa34dd3eSStefano Zampini 9308fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 9309fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 9310fa34dd3eSStefano Zampini /* continuous in primal space */ 9311fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 9312fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9313fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9314fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 93154f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 93164f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 9317fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 9318fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 9319fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 9320fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 9321fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9322fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9323fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 9324fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 9325fa34dd3eSStefano Zampini 9326fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 9327fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 9328fa34dd3eSStefano Zampini /* local with Schur */ 9329fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 9330fa34dd3eSStefano Zampini if (zerodiag) { 9331fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 93324f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 9333fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 9334fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 9335fa34dd3eSStefano Zampini } 9336fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 9337fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9338fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9339fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 9340fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 9341fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 9342fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 9343fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 9344fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 9345fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9346fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9347fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9348fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9349fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 9350fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 9351fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 9352fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 9353fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 9354fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 9355fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 9356fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9357fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9358fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 9359fa34dd3eSStefano Zampini if (zerodiag) { 9360fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 9361fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 93624f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 9363fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 9364fa34dd3eSStefano Zampini } 9365fa34dd3eSStefano Zampini /* BDDC */ 9366fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 9367fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 9368fa34dd3eSStefano Zampini 9369fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 9370fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 9371fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 93726080607fSStefano Zampini ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm);CHKERRQ(ierr); 93734f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 93746080607fSStefano 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); 9375fa34dd3eSStefano Zampini } 93764f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 9377fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 9378fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 9379fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 9380fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 9381fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 9382fa34dd3eSStefano Zampini } 9383fa34dd3eSStefano Zampini PetscFunctionReturn(0); 9384fa34dd3eSStefano Zampini } 93851e0482f5SStefano Zampini 93861e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 93871e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 93881e0482f5SStefano Zampini { 93891e0482f5SStefano Zampini Mat At; 93901e0482f5SStefano Zampini IS rows; 93911e0482f5SStefano Zampini PetscInt rst,ren; 93921e0482f5SStefano Zampini PetscErrorCode ierr; 93931e0482f5SStefano Zampini PetscLayout rmap; 93941e0482f5SStefano Zampini 93951e0482f5SStefano Zampini PetscFunctionBegin; 93961e0482f5SStefano Zampini rst = ren = 0; 93971e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 93981e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 93991e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 94001e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 94011e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 94021e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 94031e0482f5SStefano Zampini } 9404e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 94057dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 94061e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 94071e0482f5SStefano Zampini 94081e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 94091e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 94101e0482f5SStefano Zampini IS from,to; 94111e0482f5SStefano Zampini Vec gvec; 94121e0482f5SStefano Zampini PetscInt lsize; 94131e0482f5SStefano Zampini 94141e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 94151e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 94161e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 94171e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 94181e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 94191e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 94201e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 9421ffc4695bSBarry Smith ierr = MPI_Comm_size(ccomm,&b->size);CHKERRMPI(ierr); 9422ffc4695bSBarry Smith ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRMPI(ierr); 94231e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 94241e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 94251e0482f5SStefano Zampini b->A = a->A; 94261e0482f5SStefano Zampini b->B = a->B; 94271e0482f5SStefano Zampini 94281e0482f5SStefano Zampini b->donotstash = a->donotstash; 94291e0482f5SStefano Zampini b->roworiented = a->roworiented; 94300a545947SLisandro Dalcin b->rowindices = NULL; 94310a545947SLisandro Dalcin b->rowvalues = NULL; 94321e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 94331e0482f5SStefano Zampini 94341e0482f5SStefano Zampini (*B)->rmap = rmap; 94351e0482f5SStefano Zampini (*B)->factortype = A->factortype; 94361e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 94371e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 94381e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 94391e0482f5SStefano Zampini 94401e0482f5SStefano Zampini if (a->colmap) { 94411e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 94421e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 94431e0482f5SStefano Zampini #else 94441e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 94451e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 9446580bdb30SBarry Smith ierr = PetscArraycpy(b->colmap,a->colmap,At->cmap->N);CHKERRQ(ierr); 94471e0482f5SStefano Zampini #endif 94480a545947SLisandro Dalcin } else b->colmap = NULL; 94491e0482f5SStefano Zampini if (a->garray) { 94501e0482f5SStefano Zampini PetscInt len; 94511e0482f5SStefano Zampini len = a->B->cmap->n; 94521e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 94531e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 9454580bdb30SBarry Smith if (len) { ierr = PetscArraycpy(b->garray,a->garray,len);CHKERRQ(ierr); } 94550a545947SLisandro Dalcin } else b->garray = NULL; 94561e0482f5SStefano Zampini 94571e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 94581e0482f5SStefano Zampini b->lvec = a->lvec; 94591e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 94601e0482f5SStefano Zampini 94611e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 94621e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 94631e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 94641e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 94651e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 94669448b7f1SJunchao Zhang ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 94671e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 94681e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 94691e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 94701e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 94711e0482f5SStefano Zampini } 94721e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 94731e0482f5SStefano Zampini PetscFunctionReturn(0); 94741e0482f5SStefano Zampini } 9475