11cf9b237SStefano Zampini #include <../src/mat/impls/aij/seq/aij.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> 3ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 4674ae819SStefano Zampini #include <petscblaslapack.h> 5daf8a457SStefano Zampini #include <petsc/private/sfimpl.h> 6674ae819SStefano Zampini 7a13144ffSStefano Zampini /* returns B s.t. range(B) _|_ range(A) */ 8a13144ffSStefano Zampini #undef __FUNCT__ 9a13144ffSStefano Zampini #define __FUNCT__ "MatDense_OrthogonalComplement" 10a13144ffSStefano Zampini PetscErrorCode MatDense_OrthogonalComplement(Mat A, PetscInt lw, PetscScalar *work, PetscReal *rwork, Mat *B) 11a13144ffSStefano Zampini { 12a13144ffSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 13a13144ffSStefano Zampini PetscScalar *uwork,*data,*U, ds = 0.; 14a13144ffSStefano Zampini PetscReal *sing; 15a13144ffSStefano Zampini PetscBLASInt bM,bN,lwork,lierr,di = 1; 16a13144ffSStefano Zampini PetscInt ulw,i,nr,nc,n; 17a13144ffSStefano Zampini PetscErrorCode ierr; 18a13144ffSStefano Zampini 19a13144ffSStefano Zampini PetscFunctionBegin; 20a13144ffSStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 21a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"LAPACK _GESVD not available"); 22a13144ffSStefano Zampini #endif 23a13144ffSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 24a13144ffSStefano Zampini if (!nr || !nc) PetscFunctionReturn(0); 25a13144ffSStefano Zampini 26a13144ffSStefano Zampini /* workspace */ 27a13144ffSStefano Zampini if (!work) { 28a13144ffSStefano Zampini ulw = PetscMax(PetscMax(1,5*PetscMin(nr,nc)),3*PetscMin(nr,nc)+PetscMax(nr,nc)); 29a13144ffSStefano Zampini ierr = PetscMalloc1(ulw,&uwork); 30a13144ffSStefano Zampini } else { 31a13144ffSStefano Zampini ulw = lw; 32a13144ffSStefano Zampini uwork = work; 33a13144ffSStefano Zampini } 34a13144ffSStefano Zampini n = PetscMin(nr,nc); 35a13144ffSStefano Zampini if (!rwork) { 36a13144ffSStefano Zampini ierr = PetscMalloc1(n,&sing);CHKERRQ(ierr); 37a13144ffSStefano Zampini } else { 38a13144ffSStefano Zampini sing = rwork; 39a13144ffSStefano Zampini } 40a13144ffSStefano Zampini 41a13144ffSStefano Zampini /* SVD */ 42a13144ffSStefano Zampini ierr = PetscMalloc1(nr*nr,&U);CHKERRQ(ierr); 43a13144ffSStefano Zampini ierr = PetscBLASIntCast(nr,&bM);CHKERRQ(ierr); 44a13144ffSStefano Zampini ierr = PetscBLASIntCast(nc,&bN);CHKERRQ(ierr); 45a13144ffSStefano Zampini ierr = PetscBLASIntCast(ulw,&lwork);CHKERRQ(ierr); 46a13144ffSStefano Zampini ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); 47a13144ffSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 48a13144ffSStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,&lierr)); 49a13144ffSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 50a13144ffSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 51a13144ffSStefano Zampini ierr = MatDenseRestoreArray(A,&data);CHKERRQ(ierr); 52a13144ffSStefano Zampini for (i=0;i<n;i++) if (sing[i] < PETSC_SMALL) break; 53a13144ffSStefano Zampini if (!rwork) { 54a13144ffSStefano Zampini ierr = PetscFree(sing);CHKERRQ(ierr); 55a13144ffSStefano Zampini } 56a13144ffSStefano Zampini if (!work) { 57a13144ffSStefano Zampini ierr = PetscFree(uwork);CHKERRQ(ierr); 58a13144ffSStefano Zampini } 59a13144ffSStefano Zampini /* create B */ 60a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 61a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 62a13144ffSStefano Zampini ierr = PetscMemcpy(data,U+nr*i,(nr-i)*nr*sizeof(PetscScalar));CHKERRQ(ierr); 63a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 64a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 65a13144ffSStefano Zampini #else 66a13144ffSStefano Zampini PetscFunctionBegin; 67a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for complexes"); 68a13144ffSStefano Zampini #endif 69a13144ffSStefano Zampini PetscFunctionReturn(0); 70a13144ffSStefano Zampini } 71a13144ffSStefano Zampini 72a13144ffSStefano Zampini #undef __FUNCT__ 73a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCComputeNedelecChangeEdge" 74a13144ffSStefano Zampini PetscErrorCode PCBDDCComputeNedelecChangeEdge(Mat lG, IS edge, IS extrow, IS extcol, Mat* Gins, Mat* GKins, PetscScalar *work, PetscReal *rwork) 75a13144ffSStefano Zampini { 76a13144ffSStefano Zampini PetscErrorCode ierr; 77a13144ffSStefano Zampini Mat GE,GEd; 78a13144ffSStefano Zampini PetscInt rsize,csize,esize; 79a13144ffSStefano Zampini PetscScalar *ptr; 80a13144ffSStefano Zampini 81a13144ffSStefano Zampini PetscFunctionBegin; 82a13144ffSStefano Zampini ierr = ISGetSize(edge,&esize);CHKERRQ(ierr); 83a13144ffSStefano Zampini ierr = ISGetSize(extrow,&rsize);CHKERRQ(ierr); 84a13144ffSStefano Zampini ierr = ISGetSize(extcol,&csize);CHKERRQ(ierr); 85a13144ffSStefano Zampini 86a13144ffSStefano Zampini /* gradients */ 87a13144ffSStefano Zampini ptr = work + 5*esize; 88a13144ffSStefano Zampini ierr = MatGetSubMatrix(lG,extrow,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 89a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,rsize,csize,ptr,Gins);CHKERRQ(ierr); 90a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,Gins);CHKERRQ(ierr); 91a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 92a13144ffSStefano Zampini 93a13144ffSStefano Zampini /* constants */ 94a13144ffSStefano Zampini ptr += rsize*csize; 95a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,esize,csize,ptr,&GEd);CHKERRQ(ierr); 96a13144ffSStefano Zampini ierr = MatGetSubMatrix(lG,edge,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 97a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,&GEd);CHKERRQ(ierr); 98a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 99a13144ffSStefano Zampini ierr = MatDense_OrthogonalComplement(GEd,5*esize,work,rwork,GKins);CHKERRQ(ierr); 100a13144ffSStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 101a13144ffSStefano Zampini PetscFunctionReturn(0); 102a13144ffSStefano Zampini } 103a13144ffSStefano Zampini 104a13144ffSStefano Zampini #undef __FUNCT__ 105a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCNedelecSupport" 106a13144ffSStefano Zampini PetscErrorCode PCBDDCNedelecSupport(PC pc) 107a13144ffSStefano Zampini { 108a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 109a13144ffSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 110a13144ffSStefano Zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGw; 111a13144ffSStefano Zampini MatNullSpace nnsp; 112a13144ffSStefano Zampini Vec tvec,*quads; 113a13144ffSStefano Zampini PetscSF sfv; 114a13144ffSStefano Zampini ISLocalToGlobalMapping el2g,vl2g; 115a13144ffSStefano Zampini MPI_Comm comm; 116a13144ffSStefano Zampini IS lned,primals; 117a13144ffSStefano Zampini IS *eedges,*extrows,*extcols; 118a13144ffSStefano Zampini PetscBT btv,bte,btb,btvcand,iwork; 119a13144ffSStefano Zampini PetscScalar *vals,*work; 120a13144ffSStefano Zampini PetscReal *rwork; 121a13144ffSStefano Zampini const PetscInt *idxs,*ii,*jj,*iit,*jjt; 122a13144ffSStefano Zampini PetscInt ne,nv,Ne,Nv,Le,Lv,order; 123a13144ffSStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 124a13144ffSStefano Zampini PetscInt *interior; 125a13144ffSStefano Zampini PetscInt i,j,extmem,cum,maxsize,rst,nee,nquads=2; 126a13144ffSStefano Zampini PetscInt *extrow,*extrowcum,*marks,*emarks,*vmarks,*gidxs; 127a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 128a13144ffSStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,ismpiaij; 129a13144ffSStefano Zampini PetscErrorCode ierr; 130a13144ffSStefano Zampini 131a13144ffSStefano Zampini PetscFunctionBegin; 132a13144ffSStefano Zampini /* test variable order code and print debug info TODO: to be removed */ 133a13144ffSStefano Zampini print = PETSC_FALSE; 134a13144ffSStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_print_nedelec",&print,NULL);CHKERRQ(ierr); 135a13144ffSStefano Zampini ierr = PetscOptionsGetInt(NULL,NULL,"-pc_bddc_nedelec_order",&pcbddc->nedorder,NULL);CHKERRQ(ierr); 136a13144ffSStefano Zampini 137a13144ffSStefano Zampini /* Return to caller if there are no edges in the decomposition */ 138a13144ffSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 139a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&el2g,NULL);CHKERRQ(ierr); 140a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(el2g,&ne);CHKERRQ(ierr); 141a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 142a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 143a13144ffSStefano Zampini for (i=0;i<ne;i++) { 144a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 145a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 146a13144ffSStefano Zampini break; 147a13144ffSStefano Zampini } 148a13144ffSStefano Zampini } 149a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 150a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 151a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 152a13144ffSStefano Zampini 153a13144ffSStefano Zampini /* Get relevant objects */ 154a13144ffSStefano Zampini G = pcbddc->discretegradient; 155a13144ffSStefano Zampini order = pcbddc->nedorder; 156a13144ffSStefano Zampini conforming = pcbddc->conforming; 157a13144ffSStefano Zampini 158a13144ffSStefano Zampini /* Compute local and global sizes of egde dofs and nodal dofs */ 159a13144ffSStefano Zampini ierr = MatGetSize(G,&Ne,&Nv);CHKERRQ(ierr); 160a13144ffSStefano Zampini ierr = MatGetLocalSize(G,&Le,&Lv);CHKERRQ(ierr); 161a13144ffSStefano Zampini 162a13144ffSStefano Zampini /* Sanity checks */ 163a13144ffSStefano Zampini if (!order) SETERRQ(comm,PETSC_ERR_SUP,"Variable order not yet implemented"); 164a13144ffSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 165a13144ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)G,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 166a13144ffSStefano Zampini if (!ismpiaij) SETERRQ1(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with discrete gradient of type %s. Please use MPIAIJ",((PetscObject)G)->type_name); 167a13144ffSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 168a13144ffSStefano Zampini if (order && Ne%order) SETERRQ2(comm,PETSC_ERR_USER,"The number of edge dofs %d it's not a multiple of the order %d",Ne,order); 169a13144ffSStefano 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); 170a13144ffSStefano Zampini ierr = MatGetSize(pc->pmat,&i,NULL);CHKERRQ(ierr); 171a13144ffSStefano Zampini if (Ne != i) SETERRQ2(comm,PETSC_ERR_USER,"Global matrix sizes should match! Number of rows of G %d differs from that of A %d",Ne,i); 172a13144ffSStefano Zampini ierr = MatGetLocalSize(pc->pmat,&i,NULL);CHKERRQ(ierr); 173a13144ffSStefano Zampini if (Le != i) SETERRQ2(comm,PETSC_ERR_USER,"Local matrix sizes should match! Number of local rows of G %d differs from that of A %d",Le,i); 174a13144ffSStefano Zampini 175a13144ffSStefano Zampini /* Drop connections for interior edges (this modifies G) */ 176a13144ffSStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 177a13144ffSStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->counter,tvec,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 178a13144ffSStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->counter,tvec,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 179a13144ffSStefano Zampini ierr = PetscMalloc1(Le,&marks);CHKERRQ(ierr); 180a13144ffSStefano Zampini ierr = VecGetOwnershipRange(tvec,&rst,NULL);CHKERRQ(ierr); 181a13144ffSStefano Zampini ierr = VecGetArrayRead(tvec,(const PetscScalar**)&vals);CHKERRQ(ierr); 182a13144ffSStefano Zampini cum = 0; 183a13144ffSStefano Zampini for (i=0;i<Le;i++) if (PetscRealPart(vals[i]) < 1.5) marks[cum++] = i+rst; 184a13144ffSStefano Zampini ierr = VecRestoreArrayRead(tvec,(const PetscScalar**)&vals);CHKERRQ(ierr); 185a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 186a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 187a13144ffSStefano Zampini ierr = MatZeroRows(G,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 188a13144ffSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 189a13144ffSStefano Zampini 190a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 191a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 192a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 193a13144ffSStefano Zampini ierr = MatGetSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 194a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 195a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 196a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 197a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 198a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 199a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 200a13144ffSStefano Zampini if (print) { 201a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 202a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 203a13144ffSStefano Zampini } 204a13144ffSStefano Zampini 205a13144ffSStefano Zampini /* SF for nodal communications */ 206a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 207a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 208a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 209a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 210a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 211a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 212a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 213a13144ffSStefano Zampini ierr = PetscMalloc2(nv,&sfvleaves,Lv,&sfvroots);CHKERRQ(ierr); 214a13144ffSStefano Zampini 215a13144ffSStefano Zampini /* Destroy temporary G created in MATIS format */ 216a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 217a13144ffSStefano Zampini 218a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 219a13144ffSStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGw);CHKERRQ(ierr); 220a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 221a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 222a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 223a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 224a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 225a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 226a13144ffSStefano Zampini ierr = ISGetLocalSize(pcbddc->DirichletBoundariesLocal,&cum);CHKERRQ(ierr); 227a13144ffSStefano Zampini ierr = ISGetIndices(pcbddc->DirichletBoundariesLocal,&idxs);CHKERRQ(ierr); 228a13144ffSStefano Zampini for (i=0;i<cum;i++) { 229a13144ffSStefano Zampini if (idxs[i] >= 0) { 230a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 231a13144ffSStefano Zampini } 232a13144ffSStefano Zampini } 233a13144ffSStefano Zampini ierr = ISRestoreIndices(pcbddc->DirichletBoundariesLocal,&idxs);CHKERRQ(ierr); 234a13144ffSStefano Zampini } 235a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 236a13144ffSStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&cum);CHKERRQ(ierr); 237a13144ffSStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 238a13144ffSStefano Zampini for (i=0;i<cum;i++) { 239a13144ffSStefano Zampini if (idxs[i] >= 0) { 240a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 241a13144ffSStefano Zampini } 242a13144ffSStefano Zampini } 243a13144ffSStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 244a13144ffSStefano Zampini } 245a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 246a13144ffSStefano Zampini /* need to remove coarse faces' dofs to ensure the 247a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 248a13144ffSStefano Zampini ierr = PetscCalloc1(ne,&marks);CHKERRQ(ierr); 249a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 250a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 251a13144ffSStefano Zampini PetscInt j; 252a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) marks[shared[i][j]]++; 253a13144ffSStefano Zampini } 254a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 255a13144ffSStefano Zampini cum = 0; 256a13144ffSStefano Zampini ierr = MatGetRowIJ(lGw,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 257a13144ffSStefano Zampini for (i=0;i<ne;i++) { 258a13144ffSStefano Zampini if (!marks[i] || (marks[i] == 1 && !PetscBTLookup(btb,i))) { /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 259a13144ffSStefano Zampini marks[cum++] = i; 260a13144ffSStefano Zampini } else if (!conforming && ii[i+1]-ii[i] != order + 1) { /* set badly connected edge dofs as primal */ 261a13144ffSStefano Zampini marks[cum++] = i; 262a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 263a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 264a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 265a13144ffSStefano Zampini } 266a13144ffSStefano Zampini } 267a13144ffSStefano Zampini } 268a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGw,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 269a13144ffSStefano Zampini ierr = MatSetOption(lGw,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 270a13144ffSStefano Zampini ierr = MatZeroRows(lGw,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 271a13144ffSStefano Zampini /* identify splitpoints and corner candidates: TODO variable order */ 272a13144ffSStefano Zampini ierr = MatTranspose(lGw,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 273a13144ffSStefano Zampini if (print) { 274a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGw,"work_lG");CHKERRQ(ierr); 275a13144ffSStefano Zampini ierr = MatView(lGw,NULL);CHKERRQ(ierr); 276a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"work_lGt");CHKERRQ(ierr); 277a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 278a13144ffSStefano Zampini } 279a13144ffSStefano Zampini ierr = MatDestroy(&lGw);CHKERRQ(ierr); 280a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 281a13144ffSStefano Zampini for (i=0;i<nv;i++) { 282a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 283a13144ffSStefano Zampini if ((ii[i+1]-ii[i])%order) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected number of edge dofs %d connected with nodal dof %d with order %d",ii[i+1]-ii[i],i,order); 284a13144ffSStefano Zampini #endif 285a13144ffSStefano Zampini if (ii[i+1]-ii[i] >= 3*order) { /* splitpoints */ 286a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d\n",i); 287a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 288a13144ffSStefano Zampini } else if (ii[i+1]-ii[i] == order) { 289a13144ffSStefano Zampini if (order == 1) { 290a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 291a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 292a13144ffSStefano Zampini } else { 293a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 294a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 295a13144ffSStefano Zampini } 296a13144ffSStefano Zampini } 297a13144ffSStefano Zampini } 298a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 299a13144ffSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 300a13144ffSStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 301a13144ffSStefano Zampini 302a13144ffSStefano Zampini /* Get the local G^T explicitly */ 303a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 304a13144ffSStefano Zampini if (print) { 305a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"initial_lGt");CHKERRQ(ierr); 306a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 307a13144ffSStefano Zampini } 308a13144ffSStefano Zampini 309a13144ffSStefano Zampini /* Eliminate interior nodal dofs */ 310a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 311a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&iwork);CHKERRQ(ierr); 312a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&interior);CHKERRQ(ierr); 313a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 314a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 315a13144ffSStefano Zampini ierr = PetscBTSet(iwork,shared[i][j]);CHKERRQ(ierr); 316a13144ffSStefano Zampini } 317a13144ffSStefano Zampini } 318a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 319a13144ffSStefano Zampini for (i=0,cum=0;i<nv;i++) if (!PetscBTLookup(iwork,i)) interior[cum++] = i; 320a13144ffSStefano Zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 321a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,interior,0.,NULL,NULL);CHKERRQ(ierr); 322a13144ffSStefano Zampini if (print) { 323a13144ffSStefano Zampini IS tbz; 324a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,interior,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 325a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"interior_nodal_dofs");CHKERRQ(ierr); 326a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 327a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 328a13144ffSStefano Zampini } 329a13144ffSStefano Zampini ierr = PetscBTDestroy(&iwork);CHKERRQ(ierr); 330a13144ffSStefano Zampini ierr = PetscFree(interior);CHKERRQ(ierr); 331a13144ffSStefano Zampini 332a13144ffSStefano Zampini /* communicate corners and splitpoints */ 333a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 334a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 335a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 336a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 337a13144ffSStefano Zampini 338a13144ffSStefano Zampini if (print) { 339a13144ffSStefano Zampini IS tbz; 340a13144ffSStefano Zampini 341a13144ffSStefano Zampini cum = 0; 342a13144ffSStefano Zampini for (i=0;i<nv;i++) 343a13144ffSStefano Zampini if (sfvleaves[i]) 344a13144ffSStefano Zampini vmarks[cum++] = i; 345a13144ffSStefano Zampini 346a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 347a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 348a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 349a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 350a13144ffSStefano Zampini } 351a13144ffSStefano Zampini 352a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 353a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 354a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 355a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 356a13144ffSStefano Zampini 357a13144ffSStefano Zampini /* Zero rows of lGt corresponding to identified corners (if any) 358a13144ffSStefano Zampini TODO: this can be merged with the previous zerorows call */ 359a13144ffSStefano Zampini cum = 0; 360a13144ffSStefano Zampini for (i=0;i<nv;i++) { 361a13144ffSStefano Zampini if (sfvleaves[i]) { 362a13144ffSStefano Zampini vmarks[cum++] = i; 363a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 364a13144ffSStefano Zampini } 365a13144ffSStefano Zampini } 366a13144ffSStefano Zampini if (print) { 367a13144ffSStefano Zampini IS tbz; 368a13144ffSStefano Zampini 369a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 370a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed");CHKERRQ(ierr); 371a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 372a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 373a13144ffSStefano Zampini } 374a13144ffSStefano Zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 375a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 376a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 377a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 378a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 379a13144ffSStefano Zampini 380a13144ffSStefano Zampini /* Recompute G */ 381a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 382a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 383a13144ffSStefano Zampini if (print) { 384a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 385a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 386a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 387a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 388a13144ffSStefano Zampini } 389a13144ffSStefano Zampini 390a13144ffSStefano Zampini /* Get primal dofs (if any) */ 391a13144ffSStefano Zampini cum = 0; 392a13144ffSStefano Zampini for (i=0;i<ne;i++) { 393a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 394a13144ffSStefano Zampini } 395a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 396a13144ffSStefano Zampini if (print) { 397a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 398a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 399a13144ffSStefano Zampini } 400a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 401a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 402a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 403a13144ffSStefano Zampini 404a13144ffSStefano Zampini /* Compute edge connectivity */ 405a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 406a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 407a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 408a13144ffSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,ne,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 409a13144ffSStefano Zampini 410a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 411a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 412a13144ffSStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 413a13144ffSStefano Zampini 414a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 415a13144ffSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 416a13144ffSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&eedges,&primals);CHKERRQ(ierr); 417a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 418a13144ffSStefano Zampini 419a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 420a13144ffSStefano Zampini maxsize = 0; 421a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 422a13144ffSStefano Zampini for (i=0;i<nee;i++) { 423a13144ffSStefano Zampini PetscInt size,mark = i+1; 424a13144ffSStefano Zampini 425a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 426a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 427a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 428a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 429a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 430a13144ffSStefano Zampini } 431a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 432a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 433a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 434a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 435a13144ffSStefano Zampini if (print) { 436a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 437a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 438a13144ffSStefano Zampini } 439a13144ffSStefano Zampini 440a13144ffSStefano Zampini /* Find coarse edge endpoints */ 441a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 442a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 443a13144ffSStefano Zampini for (i=0;i<nee;i++) { 444a13144ffSStefano Zampini PetscInt mark = i+1,size; 445a13144ffSStefano Zampini 446a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 447a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 448a13144ffSStefano Zampini if (print) { 449a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 450a13144ffSStefano Zampini ISView(eedges[i],NULL); 451a13144ffSStefano Zampini } 452a13144ffSStefano Zampini for (j=0;j<size;j++) { 453a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 454a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 455a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 456a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 457a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 458a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 459a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 460a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," candidate? %d\n",(PetscBool)(PetscBTLookup(btvcand,jj[k]))); 461a13144ffSStefano Zampini PetscInt k2; 462a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 463a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 464a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," INSPECTING %d: count %d, mark %d (ref mark %d), special %d\n",jjt[k2],pcbddc->mat_graph->count[jjt[k2]],marks[jjt[k2]],mark,pcbddc->mat_graph->special_dof[jjt[k2]]); 465a13144ffSStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || 466a13144ffSStefano Zampini pcbddc->mat_graph->special_dof[jjt[k2]] == PCBDDCGRAPH_DIRICHLET_MARK) { 467a13144ffSStefano Zampini corner = PETSC_TRUE; 468a13144ffSStefano Zampini break; 469a13144ffSStefano Zampini } 470a13144ffSStefano Zampini } 471a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 472a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 473a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 474a13144ffSStefano Zampini } else { 475a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 476a13144ffSStefano Zampini } 477a13144ffSStefano Zampini } 478a13144ffSStefano Zampini } 479a13144ffSStefano Zampini } 480a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 481a13144ffSStefano Zampini } 482a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 483a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 484a13144ffSStefano Zampini 485a13144ffSStefano Zampini /* Reset marked primal dofs */ 486a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 487a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 488a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 489a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 490a13144ffSStefano Zampini 491a13144ffSStefano Zampini /* Compute extended cols indices */ 492a13144ffSStefano Zampini ierr = MatGetRowIJ(lG ,0,PETSC_FALSE,PETSC_FALSE,&i, &ii, &jj,&done);CHKERRQ(ierr); 493a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 494a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 495a13144ffSStefano Zampini i *= maxsize; 496a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extcols);CHKERRQ(ierr); 497a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&emarks);CHKERRQ(ierr); 498a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 499a13144ffSStefano Zampini eerr = PETSC_FALSE; 500a13144ffSStefano Zampini for (i=0;i<nee;i++) { 501a13144ffSStefano Zampini PetscInt size; 502a13144ffSStefano Zampini 503a13144ffSStefano Zampini cum = 0; 504a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 505a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 506a13144ffSStefano Zampini for (j=0;j<size;j++) { 507a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 508a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 509a13144ffSStefano Zampini } 510a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 511a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 512a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 513a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 514a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 515a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 516a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 517a13144ffSStefano Zampini if (cum != size -1) { 518a13144ffSStefano Zampini emarks[i] = 1; 519a13144ffSStefano Zampini if (print) { 520a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 521a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 522a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 523a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 524a13144ffSStefano Zampini } 525a13144ffSStefano Zampini eerr = PETSC_TRUE; 526a13144ffSStefano Zampini } 527a13144ffSStefano Zampini } 528a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 529a13144ffSStefano Zampini if (done) { 530a13144ffSStefano Zampini PetscInt *newprimals; 531a13144ffSStefano Zampini 532a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 533a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 534a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 535a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 536a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 537a13144ffSStefano Zampini for (i=0;i<nee;i++) { 538a13144ffSStefano Zampini if (emarks[i]) { 539a13144ffSStefano Zampini PetscInt size,mark = i+1; 540a13144ffSStefano Zampini 541a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 542a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 543a13144ffSStefano Zampini for (j=0;j<size;j++) { 544a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 545a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 546a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 547a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 548a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 549a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 550a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 551a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 552a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 553a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 554a13144ffSStefano Zampini newprimals[cum++] = ee2; 555a13144ffSStefano Zampini /* finally set the new corners */ 556a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 557a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 558a13144ffSStefano Zampini } 559a13144ffSStefano Zampini } 560a13144ffSStefano Zampini } 561a13144ffSStefano Zampini } 562a13144ffSStefano Zampini } 563a13144ffSStefano Zampini } 564a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 565a13144ffSStefano Zampini } 566a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 567a13144ffSStefano Zampini } 568a13144ffSStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&eedges,&primals);CHKERRQ(ierr); 569a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 570a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 571a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 572a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 573a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 574a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 575a13144ffSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&eedges,&primals);CHKERRQ(ierr); 576a13144ffSStefano Zampini 577a13144ffSStefano Zampini /* Mark again */ 578a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 579a13144ffSStefano Zampini for (i=0;i<nee;i++) { 580a13144ffSStefano Zampini PetscInt size,mark = i+1; 581a13144ffSStefano Zampini 582a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 583a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 584a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 585a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 586a13144ffSStefano Zampini } 587a13144ffSStefano Zampini if (print) { 588a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 589a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 590a13144ffSStefano Zampini } 591a13144ffSStefano Zampini 592a13144ffSStefano Zampini /* Recompute extended cols */ 593a13144ffSStefano Zampini eerr = PETSC_FALSE; 594a13144ffSStefano Zampini for (i=0;i<nee;i++) { 595a13144ffSStefano Zampini PetscInt size; 596a13144ffSStefano Zampini 597a13144ffSStefano Zampini cum = 0; 598a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 599a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 600a13144ffSStefano Zampini for (j=0;j<size;j++) { 601a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 602a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 603a13144ffSStefano Zampini if (!PetscBTLookup(btv,jj[k])) { 604a13144ffSStefano Zampini extrow[cum++] = jj[k]; 605a13144ffSStefano Zampini } 606a13144ffSStefano Zampini } 607a13144ffSStefano Zampini } 608a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 609a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 610a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 611a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 612a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 613a13144ffSStefano Zampini if (cum != size -1) { 614a13144ffSStefano Zampini if (print) { 615a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 616a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 617a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 618a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 619a13144ffSStefano Zampini } 620a13144ffSStefano Zampini eerr = PETSC_TRUE; 621a13144ffSStefano Zampini } 622a13144ffSStefano Zampini } 623a13144ffSStefano Zampini } 624a13144ffSStefano Zampini ierr = MatRestoreRowIJ( lG,0,PETSC_FALSE,PETSC_FALSE,&i, &ii, &jj,&done);CHKERRQ(ierr); 625a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 626a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 627a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 628a13144ffSStefano Zampini /* an error should not occur at this point */ 629a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 630a13144ffSStefano Zampini 631a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 632a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 633a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 634a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 635a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 636a13144ffSStefano Zampini for (i=0;i<nv;i++) { 637a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 638a13144ffSStefano Zampini 639a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 640a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 641a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 642a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 643a13144ffSStefano Zampini if (emax < emarks[j]) { 644a13144ffSStefano Zampini emax = emarks[j]; 645a13144ffSStefano Zampini eemax = j; 646a13144ffSStefano Zampini } 647a13144ffSStefano Zampini } 648a13144ffSStefano Zampini /* not relevant for edges */ 649a13144ffSStefano Zampini if (!eemax) continue; 650a13144ffSStefano Zampini 651a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 652a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 653a13144ffSStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Found 2 coarse edges (id %d and %d) connected through the %d nodal dof at edge dod %d\n",marks[jj[j]]-1,eemax,i,jj[j]); 654a13144ffSStefano Zampini } 655a13144ffSStefano Zampini } 656a13144ffSStefano Zampini } 657a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 658a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 659a13144ffSStefano Zampini #endif 660a13144ffSStefano Zampini 661a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 662a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 663a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 664a13144ffSStefano Zampini extmem *= maxsize; 665a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 666a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 667a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 668a13144ffSStefano Zampini for (i=0;i<nv;i++) { 669a13144ffSStefano Zampini PetscInt mark = 0,size,start; 670a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 671a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 672a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 673a13144ffSStefano Zampini mark = marks[jj[j]]; 674a13144ffSStefano Zampini 675a13144ffSStefano Zampini /* not relevant */ 676a13144ffSStefano Zampini if (!mark) continue; 677a13144ffSStefano Zampini 678a13144ffSStefano Zampini /* import extended row */ 679a13144ffSStefano Zampini mark--; 680a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 681a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 682a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 683a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 684a13144ffSStefano Zampini #endif 685a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 686a13144ffSStefano Zampini extrowcum[mark] += size; 687a13144ffSStefano Zampini } 688a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 689a13144ffSStefano Zampini cum = 0; 690a13144ffSStefano Zampini for (i=0;i<nee;i++) { 691a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 692a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 693a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 694a13144ffSStefano Zampini cum = PetscMax(cum,size); 695a13144ffSStefano Zampini } 696a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 697a13144ffSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 698a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 699a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 700a13144ffSStefano Zampini 701a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 702a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 703a13144ffSStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 704a13144ffSStefano Zampini for (i=0;i<maxsize;i++) vals[i] = 1.; 705a13144ffSStefano Zampini 706a13144ffSStefano Zampini /* Create vectors for quadrature rules */ 707a13144ffSStefano Zampini ierr = PetscMalloc1(nquads,&quads);CHKERRQ(ierr); 708a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 709a13144ffSStefano Zampini ierr = MatCreateVecs(pc->pmat,&quads[i],NULL);CHKERRQ(ierr); 710a13144ffSStefano Zampini ierr = VecSetLocalToGlobalMapping(quads[i],el2g);CHKERRQ(ierr); 711a13144ffSStefano Zampini } 712a13144ffSStefano Zampini ierr = PCBDDCNullSpaceCreate(comm,PETSC_FALSE,nquads,quads,&nnsp);CHKERRQ(ierr); 713a13144ffSStefano Zampini 714a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 715a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 716a13144ffSStefano Zampini ierr = MatSetSizes(T,Le,Le,Ne,Ne);CHKERRQ(ierr); 717a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 718a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 719a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 720a13144ffSStefano Zampini ierr = MatSetLocalToGlobalMapping(T,el2g,el2g);CHKERRQ(ierr); 721a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 722a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 723a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 724a13144ffSStefano Zampini 725a13144ffSStefano Zampini /* Defaults to identity */ 726a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 727a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 728a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 729a13144ffSStefano Zampini 730a13144ffSStefano Zampini for (i=0;i<nee;i++) { 731a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 732a13144ffSStefano Zampini 733a13144ffSStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],&Gins,&GKins,work,rwork);CHKERRQ(ierr); 734a13144ffSStefano Zampini if (Gins && GKins) { 735a13144ffSStefano Zampini PetscScalar *data; 736a13144ffSStefano Zampini const PetscInt *rows,*cols; 737a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 738a13144ffSStefano Zampini 739a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 740a13144ffSStefano Zampini /* H1 */ 741a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 742a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 743a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 744a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 745a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 746a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 747a13144ffSStefano Zampini /* complement */ 748a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 749a13144ffSStefano Zampini if (ncc > nquads-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet supported ncc %d nquads %d",ncc,nquads); 750a13144ffSStefano Zampini if (ncc + nch != nrc) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"The sum of the number of columns of GKins %d and Gins %d does not match %d",ncc,nch,nrc); 751a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 752a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 753a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 754a13144ffSStefano Zampini /* Gins kernel quadratures */ 755a13144ffSStefano Zampini for (j=0;j<ncc;j++) { 756a13144ffSStefano Zampini ierr = VecSetValueLocal(quads[j],cols[nch+j],1.,INSERT_VALUES);CHKERRQ(ierr); 757a13144ffSStefano Zampini } 758a13144ffSStefano Zampini /* H1 average */ 759a13144ffSStefano Zampini ierr = VecSetValuesLocal(quads[nquads-1],nch,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 760a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 761a13144ffSStefano Zampini } 762a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 763a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 764a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 765a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 766a13144ffSStefano Zampini } 767a13144ffSStefano Zampini 768a13144ffSStefano Zampini /* Start assembling */ 769a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 770a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 771a13144ffSStefano Zampini ierr = VecAssemblyBegin(quads[i]);CHKERRQ(ierr); 772a13144ffSStefano Zampini } 773a13144ffSStefano Zampini 774a13144ffSStefano Zampini /* Free */ 775a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 776a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 777a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 778a13144ffSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 779a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 780a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 781a13144ffSStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&eedges,&primals);CHKERRQ(ierr); 782a13144ffSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 783a13144ffSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 784a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 785a13144ffSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 786a13144ffSStefano Zampini 787a13144ffSStefano Zampini /* Complete assembling */ 788a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 789a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 790a13144ffSStefano Zampini ierr = VecAssemblyEnd(quads[i]);CHKERRQ(ierr); 791a13144ffSStefano Zampini } 792a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 793a13144ffSStefano Zampini ierr = VecDestroy(&quads[i]);CHKERRQ(ierr); 794a13144ffSStefano Zampini } 795a13144ffSStefano Zampini ierr = PetscFree(quads);CHKERRQ(ierr); 796a13144ffSStefano Zampini 797a13144ffSStefano Zampini /* tell PCBDDC the topography has been analyzed */ 798a13144ffSStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 799a13144ffSStefano Zampini 800a13144ffSStefano Zampini /* set change of basis */ 801a13144ffSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,PETSC_FALSE);CHKERRQ(ierr); 802a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 803a13144ffSStefano Zampini 804a13144ffSStefano Zampini /* set quadratures */ 805a13144ffSStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnsp);CHKERRQ(ierr); 806a13144ffSStefano Zampini ierr = MatNullSpaceDestroy(&nnsp);CHKERRQ(ierr); 807a13144ffSStefano Zampini 808a13144ffSStefano Zampini PetscFunctionReturn(0); 809a13144ffSStefano Zampini } 810a13144ffSStefano Zampini 811d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 812d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 813d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 814d8203eabSStefano Zampini #undef __FUNCT__ 815d8203eabSStefano Zampini #define __FUNCT__ "PCBDDCNullSpaceCreate" 816d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 817d8203eabSStefano Zampini { 818d8203eabSStefano Zampini PetscErrorCode ierr; 819d8203eabSStefano Zampini PetscInt i; 820d8203eabSStefano Zampini 821d8203eabSStefano Zampini PetscFunctionBegin; 822d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 823d8203eabSStefano Zampini PetscInt first,last; 824d8203eabSStefano Zampini 825d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 82686fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 827d8203eabSStefano Zampini if (i>=first && i < last) { 828d8203eabSStefano Zampini PetscScalar *data; 829d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 830d8203eabSStefano Zampini if (!has_const) { 831d8203eabSStefano Zampini data[i-first] = 1.; 832d8203eabSStefano Zampini } else { 83386fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 83486fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 835d8203eabSStefano Zampini } 836d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 837d8203eabSStefano Zampini } 838d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 839d8203eabSStefano Zampini } 840d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 841d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 842d8203eabSStefano Zampini PetscInt first,last; 843d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 844d8203eabSStefano Zampini if (i>=first && i < last) { 845d8203eabSStefano Zampini PetscScalar *data; 846d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 847d8203eabSStefano Zampini if (!has_const) { 848d8203eabSStefano Zampini data[i-first] = 0.; 849d8203eabSStefano Zampini } else { 85086fa73c5SStefano Zampini data[2*i-first] = 0.; 85186fa73c5SStefano Zampini data[2*i-first+1] = 0.; 852d8203eabSStefano Zampini } 853d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 854d8203eabSStefano Zampini } 855d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 856d8203eabSStefano Zampini } 857d8203eabSStefano Zampini PetscFunctionReturn(0); 858d8203eabSStefano Zampini } 859d8203eabSStefano Zampini 860669cc0f4SStefano Zampini #undef __FUNCT__ 861669cc0f4SStefano Zampini #define __FUNCT__ "PCBDDCComputeNoNetFlux" 8628ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 863669cc0f4SStefano Zampini { 864a198735bSStefano Zampini Mat loc_divudotp; 865fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 8668ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 867669cc0f4SStefano Zampini IS *faces,*edges; 868669cc0f4SStefano Zampini PetscScalar *vals; 869669cc0f4SStefano Zampini const PetscScalar *array; 870669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 8711ae86dd6SStefano Zampini PetscMPIInt rank; 872a198735bSStefano Zampini PetscErrorCode ierr; 873669cc0f4SStefano Zampini 874669cc0f4SStefano Zampini PetscFunctionBegin; 875669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 876669cc0f4SStefano Zampini if (graph->twodim) { 877669cc0f4SStefano Zampini lmaxneighs = 2; 878669cc0f4SStefano Zampini } else { 879669cc0f4SStefano Zampini lmaxneighs = 1; 880669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 881669cc0f4SStefano Zampini const PetscInt *idxs; 882669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 883669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 884669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 885669cc0f4SStefano Zampini } 886669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 887669cc0f4SStefano Zampini } 888669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 889669cc0f4SStefano Zampini maxsize = 0; 890669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 891669cc0f4SStefano Zampini PetscInt nn; 892669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 893669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 894669cc0f4SStefano Zampini } 895669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 896669cc0f4SStefano Zampini PetscInt nn; 897669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 898669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 899669cc0f4SStefano Zampini } 900669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 901669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 902669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 9038ae0ca82SStefano Zampini if (!transpose) { 9048ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 9058ae0ca82SStefano Zampini } else { 9068ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 9078ae0ca82SStefano Zampini } 908669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 9091ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 910d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 911669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 9128ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 913669cc0f4SStefano Zampini } 914d8203eabSStefano Zampini 915669cc0f4SStefano Zampini /* compute local quad vec */ 916a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 9178ae0ca82SStefano Zampini if (!transpose) { 918a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 9198ae0ca82SStefano Zampini } else { 9208ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 9218ae0ca82SStefano Zampini } 922669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 9238ae0ca82SStefano Zampini if (!transpose) { 924a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 9258ae0ca82SStefano Zampini } else { 9268ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 9278ae0ca82SStefano Zampini } 928fa23a32eSStefano Zampini if (vl2l) { 929fa23a32eSStefano Zampini ierr = VecGetSubVector(v,vl2l,&vins);CHKERRQ(ierr); 930fa23a32eSStefano Zampini } else { 931fa23a32eSStefano Zampini vins = v; 932fa23a32eSStefano Zampini } 933fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 934669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 9359a962809SStefano Zampini 9361ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 9371ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 938669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 939669cc0f4SStefano Zampini const PetscInt *idxs; 940669cc0f4SStefano Zampini PetscInt idx,nn,j; 941669cc0f4SStefano Zampini 942669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 943669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 944669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 9451ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 946669cc0f4SStefano Zampini idx = -(idx+1); 947669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 948669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 949669cc0f4SStefano Zampini } 950669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 951669cc0f4SStefano Zampini const PetscInt *idxs; 952669cc0f4SStefano Zampini PetscInt idx,nn,j; 953669cc0f4SStefano Zampini 954669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 955669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 956669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 9571ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 958669cc0f4SStefano Zampini idx = -(idx+1); 959669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 960669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 961669cc0f4SStefano Zampini } 962c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 963fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 964fa23a32eSStefano Zampini if (vl2l) { 965fa23a32eSStefano Zampini ierr = VecRestoreSubVector(v,vl2l,&vins);CHKERRQ(ierr); 966fa23a32eSStefano Zampini } 967669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 968669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 969669cc0f4SStefano Zampini 970669cc0f4SStefano Zampini /* assemble near null space */ 971669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 972669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 973669cc0f4SStefano Zampini } 974669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 975669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 976669cc0f4SStefano Zampini } 977669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 978669cc0f4SStefano Zampini PetscFunctionReturn(0); 979669cc0f4SStefano Zampini } 980669cc0f4SStefano Zampini 981669cc0f4SStefano Zampini 982a3df083aSStefano Zampini #undef __FUNCT__ 9831f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 9841f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 9851f4df5f7SStefano Zampini { 9861f4df5f7SStefano Zampini PetscErrorCode ierr; 9871f4df5f7SStefano Zampini Vec local,global; 9881f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 9891f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 9901f4df5f7SStefano Zampini 9911f4df5f7SStefano Zampini PetscFunctionBegin; 9921f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 9931f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 9941f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 9951f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 9961f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 9971f4df5f7SStefano Zampini PetscInt i; 9981f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 9991f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 10001f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 10011f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 10021f4df5f7SStefano Zampini } 10031f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 10041f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 10051f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 10061f4df5f7SStefano Zampini } 10071f4df5f7SStefano Zampini } else { 1008986cdee1SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering if bs > 1 */ 10091f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1010986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 1011986cdee1SStefano Zampini if (i > 1) { 1012986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 10131f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 10141f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 10151f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 10161f4df5f7SStefano Zampini } 10171f4df5f7SStefano Zampini } 10181f4df5f7SStefano Zampini } 1019986cdee1SStefano Zampini } 10201f4df5f7SStefano Zampini 10211f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 10221f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 10231f4df5f7SStefano Zampini } 10241f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 10251f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 10261f4df5f7SStefano Zampini } 10271f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 10281f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 10291f4df5f7SStefano Zampini } 10301f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 10311f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 10321f4df5f7SStefano Zampini PetscFunctionReturn(0); 10331f4df5f7SStefano Zampini } 10341f4df5f7SStefano Zampini 10351f4df5f7SStefano Zampini #undef __FUNCT__ 10363e589ea0SStefano Zampini #define __FUNCT__ "PCBDDCBenignRemoveInterior" 10373e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 10383e589ea0SStefano Zampini { 10393e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 10403e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 10413e589ea0SStefano Zampini PetscErrorCode ierr; 10423e589ea0SStefano Zampini 10433e589ea0SStefano Zampini PetscFunctionBegin; 10443e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 10453e589ea0SStefano Zampini PetscFunctionReturn(0); 10463e589ea0SStefano Zampini } 10473e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 10483e589ea0SStefano Zampini Vec swap; 10493e589ea0SStefano Zampini 10503e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 10513e589ea0SStefano Zampini swap = pcbddc->work_change; 10523e589ea0SStefano Zampini pcbddc->work_change = r; 10533e589ea0SStefano Zampini r = swap; 10543e589ea0SStefano Zampini } 10553e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10563e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10573e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 10583e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 10593e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10603e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10613e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 10623e589ea0SStefano Zampini Vec swap; 10633e589ea0SStefano Zampini 10643e589ea0SStefano Zampini swap = r; 10653e589ea0SStefano Zampini r = pcbddc->work_change; 10663e589ea0SStefano Zampini pcbddc->work_change = swap; 10673e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 10683e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 10693e589ea0SStefano Zampini } 10703e589ea0SStefano Zampini PetscFunctionReturn(0); 10713e589ea0SStefano Zampini } 10723e589ea0SStefano Zampini 10733e589ea0SStefano Zampini #undef __FUNCT__ 1074a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 1075a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1076a3df083aSStefano Zampini { 1077a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1078a3df083aSStefano Zampini PetscErrorCode ierr; 1079a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1080a3df083aSStefano Zampini 1081a3df083aSStefano Zampini PetscFunctionBegin; 1082a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1083a3df083aSStefano Zampini if (transpose) { 1084a3df083aSStefano Zampini apply_right = ctx->apply_left; 1085a3df083aSStefano Zampini apply_left = ctx->apply_right; 1086a3df083aSStefano Zampini } else { 1087a3df083aSStefano Zampini apply_right = ctx->apply_right; 1088a3df083aSStefano Zampini apply_left = ctx->apply_left; 1089a3df083aSStefano Zampini } 1090a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1091a3df083aSStefano Zampini if (apply_right) { 1092a3df083aSStefano Zampini const PetscScalar *ax; 1093a3df083aSStefano Zampini PetscInt nl,i; 1094a3df083aSStefano Zampini 1095a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1096a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1097a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1098a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1099a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1100a3df083aSStefano Zampini PetscScalar sum,val; 1101a3df083aSStefano Zampini const PetscInt *idxs; 1102a3df083aSStefano Zampini PetscInt nz,j; 1103a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1104a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1105a3df083aSStefano Zampini sum = 0.; 1106a3df083aSStefano Zampini if (ctx->apply_p0) { 1107a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1108a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1109a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1110a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1111a3df083aSStefano Zampini } 1112a3df083aSStefano Zampini } else { 1113a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1114a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1115a3df083aSStefano Zampini } 1116a3df083aSStefano Zampini } 1117a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1118a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1119a3df083aSStefano Zampini } 1120a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1121a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1122a3df083aSStefano Zampini } 1123a3df083aSStefano Zampini if (transpose) { 1124a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1125a3df083aSStefano Zampini } else { 1126a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1127a3df083aSStefano Zampini } 1128a3df083aSStefano Zampini if (reset_x) { 1129a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1130a3df083aSStefano Zampini } 1131a3df083aSStefano Zampini if (apply_left) { 1132a3df083aSStefano Zampini PetscScalar *ay; 1133a3df083aSStefano Zampini PetscInt i; 1134a3df083aSStefano Zampini 1135a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1136a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1137a3df083aSStefano Zampini PetscScalar sum,val; 1138a3df083aSStefano Zampini const PetscInt *idxs; 1139a3df083aSStefano Zampini PetscInt nz,j; 1140a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1141a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1142a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1143a3df083aSStefano Zampini if (ctx->apply_p0) { 1144a3df083aSStefano Zampini sum = 0.; 1145a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1146a3df083aSStefano Zampini sum += ay[idxs[j]]; 1147a3df083aSStefano Zampini ay[idxs[j]] += val; 1148a3df083aSStefano Zampini } 1149a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1150a3df083aSStefano Zampini } else { 1151a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1152a3df083aSStefano Zampini ay[idxs[j]] += val; 1153a3df083aSStefano Zampini } 1154a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1155a3df083aSStefano Zampini } 1156a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1157a3df083aSStefano Zampini } 1158a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1159a3df083aSStefano Zampini } 1160a3df083aSStefano Zampini PetscFunctionReturn(0); 1161a3df083aSStefano Zampini } 1162a3df083aSStefano Zampini 1163a3df083aSStefano Zampini #undef __FUNCT__ 1164a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 1165a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1166a3df083aSStefano Zampini { 1167a3df083aSStefano Zampini PetscErrorCode ierr; 1168a3df083aSStefano Zampini 1169a3df083aSStefano Zampini PetscFunctionBegin; 1170a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1171a3df083aSStefano Zampini PetscFunctionReturn(0); 1172a3df083aSStefano Zampini } 1173a3df083aSStefano Zampini 1174a3df083aSStefano Zampini #undef __FUNCT__ 1175a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 1176a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1177a3df083aSStefano Zampini { 1178a3df083aSStefano Zampini PetscErrorCode ierr; 1179a3df083aSStefano Zampini 1180a3df083aSStefano Zampini PetscFunctionBegin; 1181a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1182a3df083aSStefano Zampini PetscFunctionReturn(0); 1183a3df083aSStefano Zampini } 1184a3df083aSStefano Zampini 1185a3df083aSStefano Zampini #undef __FUNCT__ 1186a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 1187a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1188a3df083aSStefano Zampini { 1189a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1190a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1191a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1192a3df083aSStefano Zampini PetscErrorCode ierr; 1193a3df083aSStefano Zampini 1194a3df083aSStefano Zampini PetscFunctionBegin; 1195a3df083aSStefano Zampini if (!restore) { 11961dd7afcfSStefano Zampini Mat A_IB,A_BI; 1197a3df083aSStefano Zampini PetscScalar *work; 1198b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1199a3df083aSStefano Zampini 12009a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 12019a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1202a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1203a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1204a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1205a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1206a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1207a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1208a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 1209a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 1210a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 1211a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 1212a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 1213a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 1214059032f7SStefano Zampini if (reuse) { 1215a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 12161dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 1217059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 1218059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 1219059032f7SStefano Zampini PetscInt i; 1220059032f7SStefano Zampini 1221059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 1222059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1223059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1224059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1225059032f7SStefano Zampini } 1226059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 12271dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 1228059032f7SStefano Zampini } 1229a3df083aSStefano Zampini ctx->A = pcis->A_IB; 1230a3df083aSStefano Zampini ctx->work = work; 1231a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 1232a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1233a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1234a3df083aSStefano Zampini pcis->A_IB = A_IB; 1235a3df083aSStefano Zampini 1236a3df083aSStefano Zampini /* A_BI as A_IB^T */ 1237a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 1238a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 1239a3df083aSStefano Zampini pcis->A_BI = A_BI; 1240a3df083aSStefano Zampini } else { 12411dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 12421dd7afcfSStefano Zampini PetscFunctionReturn(0); 12431dd7afcfSStefano Zampini } 1244a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 1245a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1246a3df083aSStefano Zampini pcis->A_IB = ctx->A; 12471dd7afcfSStefano Zampini ctx->A = NULL; 12481dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 12491dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 12501dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 12511dd7afcfSStefano Zampini if (ctx->free) { 1252059032f7SStefano Zampini PetscInt i; 12531dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1254059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1255059032f7SStefano Zampini } 1256059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1257059032f7SStefano Zampini } 1258a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 1259a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 1260a3df083aSStefano Zampini } 1261a3df083aSStefano Zampini PetscFunctionReturn(0); 1262a3df083aSStefano Zampini } 1263a3df083aSStefano Zampini 1264a3df083aSStefano Zampini /* used just in bddc debug mode */ 1265a3df083aSStefano Zampini #undef __FUNCT__ 1266a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 1267a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 1268a3df083aSStefano Zampini { 1269a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1270a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1271a3df083aSStefano Zampini Mat An; 1272a3df083aSStefano Zampini PetscErrorCode ierr; 1273a3df083aSStefano Zampini 1274a3df083aSStefano Zampini PetscFunctionBegin; 1275a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 1276a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 1277a3df083aSStefano Zampini if (is1) { 1278a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 1279a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 1280a3df083aSStefano Zampini } else { 1281a3df083aSStefano Zampini *B = An; 1282a3df083aSStefano Zampini } 1283a3df083aSStefano Zampini PetscFunctionReturn(0); 1284a3df083aSStefano Zampini } 1285a3df083aSStefano Zampini 12861cf9b237SStefano Zampini /* TODO: add reuse flag */ 12871cf9b237SStefano Zampini #undef __FUNCT__ 12881cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 12891cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 12901cf9b237SStefano Zampini { 12911cf9b237SStefano Zampini Mat Bt; 12921cf9b237SStefano Zampini PetscScalar *a,*bdata; 12931cf9b237SStefano Zampini const PetscInt *ii,*ij; 12941cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 12951cf9b237SStefano Zampini PetscBool flg_row; 12961cf9b237SStefano Zampini PetscErrorCode ierr; 12971cf9b237SStefano Zampini 12981cf9b237SStefano Zampini PetscFunctionBegin; 12991cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 13001cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 13011cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 13021cf9b237SStefano Zampini nnz = n; 13031cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 13041cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 13051cf9b237SStefano Zampini } 13061cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 13071cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 13081cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 13091cf9b237SStefano Zampini nnz = 0; 13101cf9b237SStefano Zampini bii[0] = 0; 13111cf9b237SStefano Zampini for (i=0;i<n;i++) { 13121cf9b237SStefano Zampini PetscInt j; 13131cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 13141cf9b237SStefano Zampini PetscScalar entry = a[j]; 13151cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 13161cf9b237SStefano Zampini bij[nnz] = ij[j]; 13171cf9b237SStefano Zampini bdata[nnz] = entry; 13181cf9b237SStefano Zampini nnz++; 13191cf9b237SStefano Zampini } 13201cf9b237SStefano Zampini } 13211cf9b237SStefano Zampini bii[i+1] = nnz; 13221cf9b237SStefano Zampini } 13231cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 13241cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 13251cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 13261cf9b237SStefano Zampini { 13271cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 13281cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 13291cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 13301cf9b237SStefano Zampini } 13311cf9b237SStefano Zampini *B = Bt; 13321cf9b237SStefano Zampini PetscFunctionReturn(0); 13331cf9b237SStefano Zampini } 13341cf9b237SStefano Zampini 1335674ae819SStefano Zampini #undef __FUNCT__ 13364f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 13374f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 13384f1b2e48SStefano Zampini { 13394f1b2e48SStefano Zampini Mat B; 13404f1b2e48SStefano Zampini IS is_dummy,*cc_n; 13414f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 13424f1b2e48SStefano Zampini PCBDDCGraph graph; 13434f1b2e48SStefano Zampini PetscInt i,n; 13444f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 13454f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 13464f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 13474f1b2e48SStefano Zampini PetscErrorCode ierr; 13484f1b2e48SStefano Zampini 13494f1b2e48SStefano Zampini PetscFunctionBegin; 135063c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 135163c961adSStefano Zampini *ncc = 0; 135263c961adSStefano Zampini *cc = NULL; 135363c961adSStefano Zampini PetscFunctionReturn(0); 135463c961adSStefano Zampini } 13554f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 13564f1b2e48SStefano Zampini if (!isseqaij && filter) { 13571cf9b237SStefano Zampini PetscBool isseqdense; 13581cf9b237SStefano Zampini 13591cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 13601cf9b237SStefano Zampini if (!isseqdense) { 13614f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 13621cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 13631cf9b237SStefano Zampini PetscScalar *array; 13641cf9b237SStefano Zampini PetscReal chop=1.e-6; 13651cf9b237SStefano Zampini 13661cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 13671cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 13681cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 13691cf9b237SStefano Zampini for (i=0;i<n;i++) { 13701cf9b237SStefano Zampini PetscInt j; 13711cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 13721cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 13731cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 13741cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 13751cf9b237SStefano Zampini } 13761cf9b237SStefano Zampini } 13771cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 13789d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 13791cf9b237SStefano Zampini } 13804f1b2e48SStefano Zampini } else { 13814f1b2e48SStefano Zampini B = A; 13824f1b2e48SStefano Zampini } 13834f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 13844f1b2e48SStefano Zampini 13854f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 13864f1b2e48SStefano Zampini if (filter) { 13874f1b2e48SStefano Zampini PetscScalar *data; 13884f1b2e48SStefano Zampini PetscInt j,cum; 13894f1b2e48SStefano Zampini 13904f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 13914f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 13924f1b2e48SStefano Zampini cum = 0; 13934f1b2e48SStefano Zampini for (i=0;i<n;i++) { 13944f1b2e48SStefano Zampini PetscInt t; 13954f1b2e48SStefano Zampini 13964f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 13974f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 13984f1b2e48SStefano Zampini continue; 13994f1b2e48SStefano Zampini } 14004f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 14014f1b2e48SStefano Zampini } 14024f1b2e48SStefano Zampini t = xadj_filtered[i]; 14034f1b2e48SStefano Zampini xadj_filtered[i] = cum; 14044f1b2e48SStefano Zampini cum += t; 14054f1b2e48SStefano Zampini } 14064f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 14074f1b2e48SStefano Zampini } else { 14084f1b2e48SStefano Zampini xadj_filtered = NULL; 14094f1b2e48SStefano Zampini adjncy_filtered = NULL; 14104f1b2e48SStefano Zampini } 14114f1b2e48SStefano Zampini 14124f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 14134f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 14144f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 14154f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 14164f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 1417*be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 14184f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 14194f1b2e48SStefano Zampini if (xadj_filtered) { 14204f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 14214f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 14224f1b2e48SStefano Zampini } else { 14234f1b2e48SStefano Zampini graph->xadj = xadj; 14244f1b2e48SStefano Zampini graph->adjncy = adjncy; 14254f1b2e48SStefano Zampini } 14264f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 14274f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 14284f1b2e48SStefano Zampini /* partial clean up */ 14294f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 14304f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 14311cf9b237SStefano Zampini if (A != B) { 14324f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 14334f1b2e48SStefano Zampini } 14344f1b2e48SStefano Zampini 14354f1b2e48SStefano Zampini /* get back data */ 14361cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 14371cf9b237SStefano Zampini if (cc) { 14384f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 14394f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 14404f1b2e48SStefano 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); 14414f1b2e48SStefano Zampini } 14424f1b2e48SStefano Zampini *cc = cc_n; 14431cf9b237SStefano Zampini } 14444f1b2e48SStefano Zampini /* clean up graph */ 14454f1b2e48SStefano Zampini graph->xadj = 0; 14464f1b2e48SStefano Zampini graph->adjncy = 0; 14474f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 14484f1b2e48SStefano Zampini PetscFunctionReturn(0); 14494f1b2e48SStefano Zampini } 14504f1b2e48SStefano Zampini 14514f1b2e48SStefano Zampini #undef __FUNCT__ 14525408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 14535408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 14545408967cSStefano Zampini { 14555408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 14565408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1457dee84bffSStefano Zampini IS dirIS = NULL; 14584f1b2e48SStefano Zampini PetscInt i; 14595408967cSStefano Zampini PetscErrorCode ierr; 14605408967cSStefano Zampini 14615408967cSStefano Zampini PetscFunctionBegin; 1462dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 14635408967cSStefano Zampini if (zerodiag) { 14645408967cSStefano Zampini Mat A; 14655408967cSStefano Zampini Vec vec3_N; 14665408967cSStefano Zampini PetscScalar *vals; 14675408967cSStefano Zampini const PetscInt *idxs; 1468d12d3064SStefano Zampini PetscInt nz,*count; 14695408967cSStefano Zampini 14705408967cSStefano Zampini /* p0 */ 14715408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 14725408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 14735408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 14745408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 14754f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 14765408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 14775408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 14785408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 14795408967cSStefano Zampini /* v_I */ 14805408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 14815408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 14825408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 14835408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 14845408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 14855408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 14865408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 14875408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 14885408967cSStefano Zampini if (dirIS) { 14895408967cSStefano Zampini PetscInt n; 14905408967cSStefano Zampini 14915408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 14925408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 14935408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 14945408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 14955408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 14965408967cSStefano Zampini } 14975408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 14985408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 14995408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 15005408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 1501669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 15025408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 15035408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 15049a962809SStefano 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])); 15055408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 15065408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 1507d12d3064SStefano Zampini 1508d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 1509d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 1510d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 1511d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 1512d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 1513d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 15149a962809SStefano 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]); 1515d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 1516d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 15175408967cSStefano Zampini } 1518dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 15195408967cSStefano Zampini 15205408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 15215408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 15224f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 15235408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 15244f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 15255408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 1526f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1527f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 1528f2a566d8SStefano Zampini if (val != -PetscGlobalRank-i) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error testing PCBDDCBenignGetOrSetP0! Found %g at %d instead of %g\n",PetscRealPart(pcbddc->benign_p0[i]),i,-PetscGlobalRank-i);CHKERRQ(ierr); 1529f2a566d8SStefano Zampini } 15305408967cSStefano Zampini PetscFunctionReturn(0); 15315408967cSStefano Zampini } 15325408967cSStefano Zampini 15335408967cSStefano Zampini #undef __FUNCT__ 1534339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 1535339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 1536339f8db1SStefano Zampini { 1537339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 15384f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 1539b0f5fe93SStefano Zampini PetscInt nz,n; 15401f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 15414f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 1542339f8db1SStefano Zampini PetscErrorCode ierr; 1543339f8db1SStefano Zampini 1544339f8db1SStefano Zampini PetscFunctionBegin; 15459f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 15469f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1547a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 1548a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 1549a3df083aSStefano Zampini } 1550a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1551a3df083aSStefano Zampini pcbddc->benign_n = 0; 15521ae86dd6SStefano Zampini /* if a local info on dofs is present, assumes that the last field represents "pressures" 15534f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 15544f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 15554f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 15561ae86dd6SStefano Zampini since the local Schur complements are already SPD 15574f1b2e48SStefano Zampini */ 15584f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 15594f1b2e48SStefano Zampini have_null = PETSC_TRUE; 156040fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 15614f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 15624f1b2e48SStefano Zampini 15634f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 15644f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 15654f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 15664f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 1567ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 156840fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 156940fa8d13SStefano Zampini if (!sorted) { 157040fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 157140fa8d13SStefano Zampini } 157240fa8d13SStefano Zampini } else { 157340fa8d13SStefano Zampini pressures = NULL; 157440fa8d13SStefano Zampini } 157597d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 157697d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 157727b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 157897d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 1579339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 1580339f8db1SStefano Zampini if (!sorted) { 1581339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 1582339f8db1SStefano Zampini } 1583339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 15844f1b2e48SStefano Zampini if (!nz) { 15854f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 15864f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 158740fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 158840fa8d13SStefano Zampini } 15894f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 15904f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 15914f1b2e48SStefano Zampini zerodiag_subs = NULL; 15924f1b2e48SStefano Zampini pcbddc->benign_n = 0; 15931f4df5f7SStefano Zampini n_interior_dofs = 0; 15941f4df5f7SStefano Zampini interior_dofs = NULL; 15951f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 15961f4df5f7SStefano Zampini PetscInt n,i,j; 15971f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 15981f4df5f7SStefano Zampini PetscInt *iwork; 15991f4df5f7SStefano Zampini 16001f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 16011f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 16021f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 16031f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 160490648384SStefano Zampini for (i=1;i<n_neigh;i++) 16051f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 16061f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 16071f4df5f7SStefano Zampini for (i=0;i<n;i++) 16081f4df5f7SStefano Zampini if (!iwork[i]) 16091f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 16101f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 16111f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 16121f4df5f7SStefano Zampini } 16134f1b2e48SStefano Zampini if (has_null_pressures) { 16144f1b2e48SStefano Zampini IS *subs; 16151f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 16161f4df5f7SStefano Zampini const PetscInt *idxs; 16171f4df5f7SStefano Zampini PetscScalar *array; 16181f4df5f7SStefano Zampini Vec *work; 16191f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 16204f1b2e48SStefano Zampini 16214f1b2e48SStefano Zampini subs = pcbddc->local_subs; 16224f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 16231f4df5f7SStefano 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) */ 16241f4df5f7SStefano Zampini if (pcbddc->current_level) { 16251f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 16261f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 16271f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 16281f4df5f7SStefano Zampini /* work[0] = 1_p */ 16291f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 16301f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 16311f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 16321f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 16331f4df5f7SStefano Zampini /* work[0] = 1_v */ 16341f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 16351f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 16361f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 16371f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 16381f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 16391f4df5f7SStefano Zampini } 16404f1b2e48SStefano Zampini if (nsubs > 1) { 16414f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 16424f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 16434f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 16444f1b2e48SStefano Zampini IS t_zerodiag_subs; 16454f1b2e48SStefano Zampini PetscInt nl; 16464f1b2e48SStefano Zampini 16474f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 16484f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 16494f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 16504f1b2e48SStefano Zampini if (nl) { 16514f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 16524f1b2e48SStefano Zampini 16531f4df5f7SStefano Zampini if (pcbddc->current_level) { 16541f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 16551f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 16561f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 16571f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 16581f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 16591f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 16601f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 16611f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 16621f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 16631f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 16641f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 16651f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 16661f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 16671f4df5f7SStefano Zampini valid = PETSC_FALSE; 16681f4df5f7SStefano Zampini break; 16691f4df5f7SStefano Zampini } 16701f4df5f7SStefano Zampini } 16711f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 16721f4df5f7SStefano Zampini } 16731f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 16741f4df5f7SStefano Zampini IS t_bc; 16751f4df5f7SStefano Zampini PetscInt nzb; 16761f4df5f7SStefano Zampini 16771f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 16781f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 16791f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 16801f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 16811f4df5f7SStefano Zampini } 16821f4df5f7SStefano Zampini if (valid && pressures) { 16834f1b2e48SStefano Zampini IS t_pressure_subs; 16844f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 16854f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 16864f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 16874f1b2e48SStefano Zampini } 16884f1b2e48SStefano Zampini if (valid) { 16894f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 16904f1b2e48SStefano Zampini pcbddc->benign_n++; 16914f1b2e48SStefano Zampini } else { 16924f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 16934f1b2e48SStefano Zampini } 16944f1b2e48SStefano Zampini } 16954f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 16964f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 16974f1b2e48SStefano Zampini } 16984f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 16994f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 17001f4df5f7SStefano Zampini 17011f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 17021f4df5f7SStefano Zampini PetscInt nzb; 17031f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 17041f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 17051f4df5f7SStefano Zampini } 17061f4df5f7SStefano Zampini if (valid && pressures) { 17074f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 17084f1b2e48SStefano Zampini } 17091f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 17101f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 17111f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 17121f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 17131f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 17141f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 17151f4df5f7SStefano Zampini valid = PETSC_FALSE; 17161f4df5f7SStefano Zampini break; 17171f4df5f7SStefano Zampini } 17181f4df5f7SStefano Zampini } 17191f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 17201f4df5f7SStefano Zampini } 17214f1b2e48SStefano Zampini if (valid) { 17224f1b2e48SStefano Zampini pcbddc->benign_n = 1; 1723ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 17244f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 17254f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 17264f1b2e48SStefano Zampini } 17274f1b2e48SStefano Zampini } 17281f4df5f7SStefano Zampini if (pcbddc->current_level) { 17291f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 17304f1b2e48SStefano Zampini } 17311f4df5f7SStefano Zampini } 17321f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 17334f1b2e48SStefano Zampini 17344f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 1735b9b0e38cSStefano Zampini PetscInt n; 1736b9b0e38cSStefano Zampini 17374f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 17384f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 1739b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 1740b9b0e38cSStefano Zampini if (n) { 17414f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 17424f1b2e48SStefano Zampini have_null = PETSC_FALSE; 17434f1b2e48SStefano Zampini } 1744b9b0e38cSStefano Zampini } 17454f1b2e48SStefano Zampini 17464f1b2e48SStefano Zampini /* final check for null pressures */ 17474f1b2e48SStefano Zampini if (zerodiag && pressures) { 17484f1b2e48SStefano Zampini PetscInt nz,np; 17494f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 17504f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 17514f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 17524f1b2e48SStefano Zampini } 17534f1b2e48SStefano Zampini 17544f1b2e48SStefano Zampini if (recompute_zerodiag) { 17554f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 17564f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 17574f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 17584f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 17594f1b2e48SStefano Zampini } else { 17604f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 17614f1b2e48SStefano Zampini 17624f1b2e48SStefano Zampini nzn = 0; 17634f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 17644f1b2e48SStefano Zampini PetscInt ns; 17654f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 17664f1b2e48SStefano Zampini nzn += ns; 17674f1b2e48SStefano Zampini } 17684f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 17694f1b2e48SStefano Zampini nzn = 0; 17704f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 17714f1b2e48SStefano Zampini PetscInt ns,*idxs; 17724f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 17734f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 17744f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 17754f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 17764f1b2e48SStefano Zampini nzn += ns; 17774f1b2e48SStefano Zampini } 17784f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 17794f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 17804f1b2e48SStefano Zampini } 17814f1b2e48SStefano Zampini have_null = PETSC_FALSE; 17824f1b2e48SStefano Zampini } 17834f1b2e48SStefano Zampini 1784669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 1785a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 1786a198735bSStefano Zampini Mat A,loc_divudotp; 1787a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 1788a198735bSStefano Zampini IS row,col,isused = NULL; 1789a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 1790a198735bSStefano Zampini 17911f4df5f7SStefano Zampini if (pressures) { 17921f4df5f7SStefano Zampini isused = pressures; 17931f4df5f7SStefano Zampini } else { 17941f4df5f7SStefano Zampini isused = zerodiag; 17951f4df5f7SStefano Zampini } 1796a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 1797669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 17981ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 17991ae86dd6SStefano 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"); 1800a198735bSStefano Zampini n_isused = 0; 1801a198735bSStefano Zampini if (isused) { 1802a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 1803a198735bSStefano Zampini } 1804a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1805a198735bSStefano Zampini st = st-n_isused; 18061ae86dd6SStefano Zampini if (n) { 1807a198735bSStefano Zampini const PetscInt *gidxs; 1808a198735bSStefano Zampini 1809a198735bSStefano Zampini ierr = MatGetSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 1810a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 1811a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 1812a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 1813a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 1814a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 18151ae86dd6SStefano Zampini } else { 1816a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 1817a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 1818a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 1819a198735bSStefano Zampini } 1820a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 1821a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 1822a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 1823a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 1824a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 1825a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 1826a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 1827a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 1828a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 1829a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 1830a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1831a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1832a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 1833a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 18341ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18351ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18361ae86dd6SStefano Zampini } 1837b3afcdbeSStefano Zampini 1838b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 18394f1b2e48SStefano Zampini if (has_null_pressures) { 18404f1b2e48SStefano Zampini IS zerodiagc; 18414f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 18424f1b2e48SStefano Zampini PetscInt i,s,*nnz; 18434f1b2e48SStefano Zampini 18444f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 1845339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 1846339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 1847339f8db1SStefano Zampini /* local change of basis for pressures */ 1848339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 184997d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 1850339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 1851339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1852339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 18534f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 18544f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 18554f1b2e48SStefano Zampini PetscInt nzs,j; 18564f1b2e48SStefano Zampini 18574f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 18584f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 18594f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 18604f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 18614f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 18624f1b2e48SStefano Zampini } 1863339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 1864339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1865339f8db1SStefano Zampini /* set identity on velocities */ 1866339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 1867339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 1868339f8db1SStefano Zampini } 18694f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 18704f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 18719f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 18724f1b2e48SStefano 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); 1873339f8db1SStefano Zampini /* set change on pressures */ 18744f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 18754f1b2e48SStefano Zampini PetscScalar *array; 18764f1b2e48SStefano Zampini PetscInt nzs; 18774f1b2e48SStefano Zampini 18784f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 18794f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 18804f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 1881339f8db1SStefano Zampini PetscScalar vals[2]; 1882339f8db1SStefano Zampini PetscInt cols[2]; 1883339f8db1SStefano Zampini 1884339f8db1SStefano Zampini cols[0] = idxs[i]; 18854f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 1886339f8db1SStefano Zampini vals[0] = 1.; 1887b0f5fe93SStefano Zampini vals[1] = 1.; 18884f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 1889339f8db1SStefano Zampini } 18904f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 18914f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 18924f1b2e48SStefano Zampini array[nzs-1] = 1.; 18934f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 18944f1b2e48SStefano Zampini /* store local idxs for p0 */ 18954f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 18964f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 1897339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 18984f1b2e48SStefano Zampini } 1899339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1900339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1901a3df083aSStefano Zampini /* project if needed */ 1902a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 19031dd7afcfSStefano Zampini Mat M; 19041dd7afcfSStefano Zampini 19051dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 1906339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 19071dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 19081dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1909a3df083aSStefano Zampini } 19104f1b2e48SStefano Zampini /* store global idxs for p0 */ 19114f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1912339f8db1SStefano Zampini } 1913ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 19144f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 1915b0f5fe93SStefano Zampini 1916b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 1917b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 191827b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 191927b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1920339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 1921339f8db1SStefano Zampini PetscFunctionReturn(0); 1922339f8db1SStefano Zampini } 1923339f8db1SStefano Zampini 1924339f8db1SStefano Zampini #undef __FUNCT__ 1925015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 1926015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 1927efc2fbd9SStefano Zampini { 1928efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1929de9d7bd0SStefano Zampini PetscScalar *array; 1930efc2fbd9SStefano Zampini PetscErrorCode ierr; 1931efc2fbd9SStefano Zampini 1932efc2fbd9SStefano Zampini PetscFunctionBegin; 1933efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 1934efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 19354f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1936efc2fbd9SStefano Zampini } 1937de9d7bd0SStefano Zampini if (get) { 1938efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 19394f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 19404f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 1941efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 1942de9d7bd0SStefano Zampini } else { 1943de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 1944de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1945de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1946de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 1947efc2fbd9SStefano Zampini } 1948efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1949efc2fbd9SStefano Zampini } 1950efc2fbd9SStefano Zampini 1951efc2fbd9SStefano Zampini #undef __FUNCT__ 1952c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 1953c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 1954c263805aSStefano Zampini { 1955c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1956c263805aSStefano Zampini PetscErrorCode ierr; 1957c263805aSStefano Zampini 1958c263805aSStefano Zampini PetscFunctionBegin; 1959c263805aSStefano Zampini /* TODO: add error checking 1960c263805aSStefano Zampini - avoid nested pop (or push) calls. 1961c263805aSStefano Zampini - cannot push before pop. 19621c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 1963c263805aSStefano Zampini */ 19644f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 1965efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1966efc2fbd9SStefano Zampini } 1967c263805aSStefano Zampini if (pop) { 1968a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 19694f1b2e48SStefano Zampini IS is_p0; 19704f1b2e48SStefano Zampini MatReuse reuse; 1971c263805aSStefano Zampini 1972c263805aSStefano Zampini /* extract B_0 */ 19734f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 19744f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 19754f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 19764f1b2e48SStefano Zampini } 19774f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 19784f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 1979c263805aSStefano Zampini /* remove rows and cols from local problem */ 1980c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 198197d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 19824f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 19834f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 1984a3df083aSStefano Zampini } else { 1985a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1986a3df083aSStefano Zampini PetscScalar *vals; 1987a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 1988a3df083aSStefano Zampini 1989a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 1990a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 1991a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 19920b5adadeSStefano Zampini PetscInt *nnz; 1993a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 1994a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 1995a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1996331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 1997331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1998331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 1999331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2000331e053bSStefano Zampini } 2001331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2002331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2003331e053bSStefano Zampini } 2004a3df083aSStefano Zampini 2005a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2006a3df083aSStefano Zampini PetscScalar *array; 2007a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2008a3df083aSStefano Zampini 2009a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2010a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2011a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2012a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2013a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2014a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2015a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2016a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2017a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2018a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2019a3df083aSStefano Zampini cum = 0; 2020a3df083aSStefano Zampini for (j=0;j<n;j++) { 202122db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2022a3df083aSStefano Zampini vals[cum] = array[j]; 2023a3df083aSStefano Zampini idxs_ins[cum] = j; 2024a3df083aSStefano Zampini cum++; 2025a3df083aSStefano Zampini } 2026a3df083aSStefano Zampini } 2027a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2028a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2029a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2030a3df083aSStefano Zampini } 2031a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2032a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2033a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2034a3df083aSStefano Zampini } 2035c263805aSStefano Zampini } else { /* push */ 2036a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 20374f1b2e48SStefano Zampini PetscInt i; 20384f1b2e48SStefano Zampini 20394f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 20404f1b2e48SStefano Zampini PetscScalar *B0_vals; 20414f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 20424f1b2e48SStefano Zampini 20434f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 20444f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 20457b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 20464f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 20474f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 20484f1b2e48SStefano Zampini } 2049c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2050c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2051a3df083aSStefano Zampini } else { 2052a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2053a3df083aSStefano Zampini } 2054c263805aSStefano Zampini } 2055c263805aSStefano Zampini PetscFunctionReturn(0); 2056c263805aSStefano Zampini } 2057c263805aSStefano Zampini 2058c263805aSStefano Zampini #undef __FUNCT__ 2059b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 206008122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2061b1b3d7a2SStefano Zampini { 2062b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 206308122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 206408122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 206508122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 206608122e43SStefano Zampini PetscScalar *work,lwork; 206708122e43SStefano Zampini PetscScalar *St,*S,*eigv; 206808122e43SStefano Zampini PetscScalar *Sarray,*Starray; 206908122e43SStefano Zampini PetscReal *eigs,thresh; 20701b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2071f6f667cfSStefano Zampini PetscBool allocated_S_St; 207208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 207308122e43SStefano Zampini PetscReal *rwork; 207408122e43SStefano Zampini #endif 2075b1b3d7a2SStefano Zampini PetscErrorCode ierr; 2076b1b3d7a2SStefano Zampini 2077b1b3d7a2SStefano Zampini PetscFunctionBegin; 2078b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 2079af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 2080af25d912SStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adaptive selection not yet implemented for general matrix pencils (herm %d, posdef %d)\n",sub_schurs->is_hermitian,sub_schurs->is_posdef); 208106a4e24aSStefano Zampini 2082fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2083fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2084fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2085fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 20861575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2087fd14bc51SStefano Zampini } 2088fd14bc51SStefano Zampini 2089e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 2090e496cd5dSStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d cc %d (%d,%d).\n",PetscGlobalRank,sub_schurs->n_subs,sub_schurs->is_hermitian,sub_schurs->is_posdef); 2091e496cd5dSStefano Zampini } 2092e496cd5dSStefano Zampini 209308122e43SStefano Zampini /* max size of subsets */ 209408122e43SStefano Zampini mss = 0; 209508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 209608122e43SStefano Zampini PetscInt subset_size; 2097862806e4SStefano Zampini 209808122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 209908122e43SStefano Zampini mss = PetscMax(mss,subset_size); 210008122e43SStefano Zampini } 210108122e43SStefano Zampini 210208122e43SStefano Zampini /* min/max and threshold */ 210308122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 2104f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 210508122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 2106f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 2107f6f667cfSStefano Zampini if (nmin) { 2108f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 2109f6f667cfSStefano Zampini } 211008122e43SStefano Zampini 211108122e43SStefano Zampini /* allocate lapack workspace */ 211208122e43SStefano Zampini cum = cum2 = 0; 211308122e43SStefano Zampini maxneigs = 0; 211408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 211508122e43SStefano Zampini PetscInt n,subset_size; 2116f6f667cfSStefano Zampini 211708122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 211808122e43SStefano Zampini n = PetscMin(subset_size,nmax); 21199162d606SStefano Zampini cum += subset_size; 21209162d606SStefano Zampini cum2 += subset_size*n; 212108122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 212208122e43SStefano Zampini } 212308122e43SStefano Zampini if (mss) { 21249ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 212508122e43SStefano Zampini PetscBLASInt B_itype = 1; 212608122e43SStefano Zampini PetscBLASInt B_N = mss; 21274c6709b3SStefano Zampini PetscReal zero = 0.0; 21284c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 212908122e43SStefano Zampini 213008122e43SStefano Zampini B_lwork = -1; 213108122e43SStefano Zampini S = NULL; 213208122e43SStefano Zampini St = NULL; 2133a58a30b4SStefano Zampini eigs = NULL; 2134a58a30b4SStefano Zampini eigv = NULL; 2135a58a30b4SStefano Zampini B_iwork = NULL; 2136a58a30b4SStefano Zampini B_ifail = NULL; 2137d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2138d1710679SStefano Zampini rwork = NULL; 2139d1710679SStefano Zampini #endif 21408bec7fa6SStefano Zampini thresh = 1.0; 214108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 214208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 214308122e43SStefano 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)); 214408122e43SStefano Zampini #else 214508122e43SStefano 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)); 214608122e43SStefano Zampini #endif 214708122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 214808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 214908122e43SStefano Zampini } else { 215008122e43SStefano Zampini /* TODO */ 215108122e43SStefano Zampini } 215208122e43SStefano Zampini } else { 215308122e43SStefano Zampini lwork = 0; 215408122e43SStefano Zampini } 215508122e43SStefano Zampini 215608122e43SStefano Zampini nv = 0; 2157d62866d3SStefano 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) */ 2158d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 215908122e43SStefano Zampini } 21604c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 2161f6f667cfSStefano Zampini if (allocated_S_St) { 2162f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 2163f6f667cfSStefano Zampini } 2164f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 216508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 216608122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 216708122e43SStefano Zampini #endif 21689162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 21699162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 21709162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 217108122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 21729162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 217308122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 217408122e43SStefano Zampini 217508122e43SStefano Zampini maxneigs = 0; 217672b8c272SStefano Zampini cum = cumarray = 0; 21779162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 21789162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 2179d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 218008122e43SStefano Zampini const PetscInt *idxs; 218108122e43SStefano Zampini 2182d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 218308122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 218408122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 218508122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 218608122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 21879162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 21889162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 218908122e43SStefano Zampini } 2190d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 219108122e43SStefano Zampini } 219208122e43SStefano Zampini 219308122e43SStefano Zampini if (mss) { /* multilevel */ 219408122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 219508122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 219608122e43SStefano Zampini } 219708122e43SStefano Zampini 2198ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 219908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 220008122e43SStefano Zampini const PetscInt *idxs; 22019d54b7f4SStefano Zampini PetscReal upper,lower; 2202862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 220308122e43SStefano Zampini PetscBLASInt B_N; 2204aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 220508122e43SStefano Zampini 22069d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 22079d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 22089d54b7f4SStefano Zampini lower = thresh; 22099d54b7f4SStefano Zampini } else { 22109d54b7f4SStefano Zampini upper = 1./thresh; 22119d54b7f4SStefano Zampini lower = 0.; 22129d54b7f4SStefano Zampini } 2213862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 2214ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 2215f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 2216f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 22179ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 2218aff50787SStefano Zampini PetscInt j,k; 2219aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 2220aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 2221aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 222208122e43SStefano Zampini } 222308122e43SStefano Zampini for (j=0;j<subset_size;j++) { 2224aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 2225aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 2226aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 2227aff50787SStefano Zampini } 222808122e43SStefano Zampini } 222908122e43SStefano Zampini } else { 223008122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 223108122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 223208122e43SStefano Zampini } 22338bec7fa6SStefano Zampini } else { 2234f6f667cfSStefano Zampini S = Sarray + cumarray; 2235f6f667cfSStefano Zampini St = Starray + cumarray; 22368bec7fa6SStefano Zampini } 2237aff50787SStefano Zampini /* see if we can save some work */ 2238b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 2239aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 2240aff50787SStefano Zampini } 2241aff50787SStefano Zampini 2242b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 2243aff50787SStefano Zampini B_neigs = 0; 2244aff50787SStefano Zampini } else { 22459ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 224608122e43SStefano Zampini PetscBLASInt B_itype = 1; 2247f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 22484c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 22499552c7c7SStefano Zampini PetscInt nmin_s; 2250b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 225108122e43SStefano Zampini 2252fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 22538bec7fa6SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %d/%d %d %d.\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]); 2254fd14bc51SStefano Zampini } 2255d16cbb6bSStefano Zampini 2256b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 2257b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 2258b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 2259b7ab4a40SStefano Zampini } 2260b7ab4a40SStefano Zampini 226108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2262b7ab4a40SStefano Zampini if (compute_range) { 2263d16cbb6bSStefano Zampini 2264d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 226508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 22669d54b7f4SStefano 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)); 226708122e43SStefano Zampini #else 22689d54b7f4SStefano 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)); 226908122e43SStefano Zampini #endif 2270b7ab4a40SStefano Zampini } else if (!same_data) { 2271d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 2272d16cbb6bSStefano Zampini B_IL = 1; 2273d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 22749d54b7f4SStefano 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)); 2275d16cbb6bSStefano Zampini #else 22769d54b7f4SStefano 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)); 2277d16cbb6bSStefano Zampini #endif 2278b7ab4a40SStefano Zampini } else { /* same_data is true, so get the adaptive function requested by the user */ 2279b7ab4a40SStefano Zampini PetscInt k; 2280b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 2281b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 2282b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 2283b7ab4a40SStefano Zampini nmin = nmax; 2284b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 2285b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 2286b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 2287b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 2288b7ab4a40SStefano Zampini } 2289d16cbb6bSStefano Zampini } 229008122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 229108122e43SStefano Zampini if (B_ierr) { 22926c4ed002SBarry 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); 22936c4ed002SBarry 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); 22946c4ed002SBarry 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); 229508122e43SStefano Zampini } 229608122e43SStefano Zampini 229708122e43SStefano Zampini if (B_neigs > nmax) { 2298fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2299fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 2300fd14bc51SStefano Zampini } 23019d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 230208122e43SStefano Zampini B_neigs = nmax; 230308122e43SStefano Zampini } 230408122e43SStefano Zampini 23059552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 23069552c7c7SStefano Zampini if (B_neigs < nmin_s) { 230708122e43SStefano Zampini PetscBLASInt B_neigs2; 230808122e43SStefano Zampini 23099d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2310f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 23119d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 23129d54b7f4SStefano Zampini } else { 23139d54b7f4SStefano Zampini B_IL = B_neigs + 1; 23149d54b7f4SStefano Zampini B_IU = nmin_s; 23159d54b7f4SStefano Zampini } 2316fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2317fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, less than minimum required %d. Asking for %d to %d incl (fortran like)\n",B_neigs,nmin,B_IL,B_IU); 2318fd14bc51SStefano Zampini } 23199ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 23201ae86dd6SStefano Zampini PetscInt j,k; 232108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 23221ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 23231ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 23241ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 232508122e43SStefano Zampini } 232608122e43SStefano Zampini } 232708122e43SStefano Zampini } else { 232808122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 232908122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 233008122e43SStefano Zampini } 233108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 233208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 23339d54b7f4SStefano 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)); 233408122e43SStefano Zampini #else 23359d54b7f4SStefano 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)); 233608122e43SStefano Zampini #endif 233708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 233808122e43SStefano Zampini B_neigs += B_neigs2; 233908122e43SStefano Zampini } 234008122e43SStefano Zampini if (B_ierr) { 23416c4ed002SBarry 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); 23426c4ed002SBarry 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); 23436c4ed002SBarry 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); 234408122e43SStefano Zampini } 2345fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2346ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 234708122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 234808122e43SStefano Zampini if (eigs[j] == 0.0) { 2349ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 235008122e43SStefano Zampini } else { 23519d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2352ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 23539d54b7f4SStefano Zampini } else { 23549d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 23559d54b7f4SStefano Zampini } 2356fd14bc51SStefano Zampini } 235708122e43SStefano Zampini } 235808122e43SStefano Zampini } 235908122e43SStefano Zampini } else { 236008122e43SStefano Zampini /* TODO */ 236108122e43SStefano Zampini } 2362aff50787SStefano Zampini } 23636c3e6151SStefano Zampini /* change the basis back to the original one */ 23646c3e6151SStefano Zampini if (sub_schurs->change) { 236572b8c272SStefano Zampini Mat change,phi,phit; 23666c3e6151SStefano Zampini 23676c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 23686c3e6151SStefano Zampini PetscInt ii; 23696c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 23706c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 23716c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 2372684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2373684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 2374684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 2375684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2376684229deSStefano Zampini #else 23776c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 2378684229deSStefano Zampini #endif 23796c3e6151SStefano Zampini } 23806c3e6151SStefano Zampini } 23816c3e6151SStefano Zampini } 238272b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 23836c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 238472b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 23856c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 23866c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 23876c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 23886c3e6151SStefano Zampini } 23898bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 23908bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 23919162d606SStefano Zampini if (B_neigs) { 23929162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum],eigv+eigs_start*subset_size,B_neigs*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 2393fd14bc51SStefano Zampini 2394fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 23959552c7c7SStefano Zampini PetscInt ii; 23969552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 2397ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 23989552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 2399ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2400ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2401ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2402ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2403ac47001eSStefano Zampini #else 2404ac47001eSStefano 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); 2405ac47001eSStefano Zampini #endif 24069552c7c7SStefano Zampini } 24079552c7c7SStefano Zampini } 2408fd14bc51SStefano Zampini } 24099162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 24109162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 24119162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 24129162d606SStefano Zampini cum++; 241308122e43SStefano Zampini } 241408122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 241508122e43SStefano Zampini /* shift for next computation */ 241608122e43SStefano Zampini cumarray += subset_size*subset_size; 241708122e43SStefano Zampini } 2418fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2419fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2420fd14bc51SStefano Zampini } 242108122e43SStefano Zampini 242208122e43SStefano Zampini if (mss) { 242308122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 242408122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 2425f6f667cfSStefano Zampini /* destroy matrices (junk) */ 2426f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 2427f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 242808122e43SStefano Zampini } 2429f6f667cfSStefano Zampini if (allocated_S_St) { 2430f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 2431f6f667cfSStefano Zampini } 2432f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 243308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 243408122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 243508122e43SStefano Zampini #endif 243608122e43SStefano Zampini if (pcbddc->dbg_flag) { 24371b968477SStefano Zampini PetscInt maxneigs_r; 2438b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 24399b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 244008122e43SStefano Zampini } 244108122e43SStefano Zampini PetscFunctionReturn(0); 244208122e43SStefano Zampini } 2443b1b3d7a2SStefano Zampini 2444674ae819SStefano Zampini #undef __FUNCT__ 2445c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 2446c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 2447c8587f34SStefano Zampini { 24488629588bSStefano Zampini PetscScalar *coarse_submat_vals; 2449c8587f34SStefano Zampini PetscErrorCode ierr; 2450c8587f34SStefano Zampini 2451c8587f34SStefano Zampini PetscFunctionBegin; 2452f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 24535e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 2454c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 2455c8587f34SStefano Zampini 2456684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 24570fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 2458684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 2459c8587f34SStefano Zampini 24608629588bSStefano Zampini /* 24618629588bSStefano Zampini Setup local correction and local part of coarse basis. 24628629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 24638629588bSStefano Zampini */ 246447f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 24658629588bSStefano Zampini 24668629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 24678629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 24688629588bSStefano Zampini 24698629588bSStefano Zampini /* free */ 24708629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 2471c8587f34SStefano Zampini PetscFunctionReturn(0); 2472c8587f34SStefano Zampini } 2473c8587f34SStefano Zampini 2474c8587f34SStefano Zampini #undef __FUNCT__ 2475674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 2476674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 2477674ae819SStefano Zampini { 2478674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2479674ae819SStefano Zampini PetscErrorCode ierr; 2480674ae819SStefano Zampini 2481674ae819SStefano Zampini PetscFunctionBegin; 2482674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 248330368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 2484674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 2485785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 2486674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 2487f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2488f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2489785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 249063602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 249163602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 2492674ae819SStefano Zampini PetscFunctionReturn(0); 2493674ae819SStefano Zampini } 2494674ae819SStefano Zampini 2495674ae819SStefano Zampini #undef __FUNCT__ 2496674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 2497674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 2498674ae819SStefano Zampini { 2499674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 25004f1b2e48SStefano Zampini PetscInt i; 2501674ae819SStefano Zampini PetscErrorCode ierr; 2502674ae819SStefano Zampini 2503674ae819SStefano Zampini PetscFunctionBegin; 2504a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 2505b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2506674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 250716909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 25081dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 2509674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2510669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 2511fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 2512a13144ffSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 2513674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 251471582508SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 25154f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 25164f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 25174f1b2e48SStefano Zampini } 25184f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 2519b334f244SStefano Zampini if (pcbddc->sub_schurs) { 2520b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 2521b334f244SStefano Zampini } 2522674ae819SStefano Zampini PetscFunctionReturn(0); 2523674ae819SStefano Zampini } 2524674ae819SStefano Zampini 2525674ae819SStefano Zampini #undef __FUNCT__ 2526674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 2527674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 2528674ae819SStefano Zampini { 2529674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2530674ae819SStefano Zampini PetscErrorCode ierr; 2531674ae819SStefano Zampini 2532674ae819SStefano Zampini PetscFunctionBegin; 2533674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 253458da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 2535ca92afb2SStefano Zampini PetscScalar *array; 253606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 253706656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 253858da7f69SStefano Zampini } 2539674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 2540674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 254115aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 254215aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 2543674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 2544674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 2545674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 254606656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 2547674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 2548674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 25498ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2550674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2551674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2552674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 2553f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 2554f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 2555f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2556f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2557727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 25580e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2559f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 256070cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 256181d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 25620369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 25631dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 25644f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 25658b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 2566ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 2567ca92afb2SStefano Zampini PetscInt i; 2568ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2569ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2570ca92afb2SStefano Zampini } 2571ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2572ca92afb2SStefano Zampini } 25734f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 2574674ae819SStefano Zampini PetscFunctionReturn(0); 2575674ae819SStefano Zampini } 2576674ae819SStefano Zampini 2577674ae819SStefano Zampini #undef __FUNCT__ 2578f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 2579f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 25806bfb1811SStefano Zampini { 25816bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 25826bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 25836bfb1811SStefano Zampini VecType impVecType; 25844f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 25856bfb1811SStefano Zampini PetscErrorCode ierr; 25866bfb1811SStefano Zampini 25876bfb1811SStefano Zampini PetscFunctionBegin; 25886c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 2589e7b262bdSStefano Zampini /* get sizes */ 25904f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 2591b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 25926bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 2593e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 2594e7b262bdSStefano Zampini /* R nodes */ 2595e7b262bdSStefano Zampini old_size = -1; 2596e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 2597e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 2598e7b262bdSStefano Zampini } 2599e7b262bdSStefano Zampini if (n_R != old_size) { 2600e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 2601e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 26026bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 26036bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 26046bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 26056bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 2606e7b262bdSStefano Zampini } 2607e7b262bdSStefano Zampini /* local primal dofs */ 2608e7b262bdSStefano Zampini old_size = -1; 2609e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 2610e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 2611e7b262bdSStefano Zampini } 2612e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 2613e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 261483b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 2615e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 26166bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 2617e7b262bdSStefano Zampini } 2618e7b262bdSStefano Zampini /* local explicit constraints */ 2619e7b262bdSStefano Zampini old_size = -1; 2620e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 2621e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 2622e7b262bdSStefano Zampini } 2623e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 2624e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 262583b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 262683b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 262783b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 262883b7ccabSStefano Zampini } 26296bfb1811SStefano Zampini PetscFunctionReturn(0); 26306bfb1811SStefano Zampini } 26316bfb1811SStefano Zampini 26326bfb1811SStefano Zampini #undef __FUNCT__ 263347f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 263447f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 263588ebb749SStefano Zampini { 263625084f0cSStefano Zampini PetscErrorCode ierr; 263725084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 263888ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 263988ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2640d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 264125084f0cSStefano Zampini /* submatrices of local problem */ 264280677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 264306656605SStefano Zampini /* submatrices of local coarse problem */ 264406656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 264525084f0cSStefano Zampini /* working matrices */ 264606656605SStefano Zampini Mat C_CR; 264725084f0cSStefano Zampini /* additional working stuff */ 264806656605SStefano Zampini PC pc_R; 26494f1b2e48SStefano Zampini Mat F; 26505cbda25cSStefano Zampini Vec dummy_vec; 2651a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 265225084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 265306656605SStefano Zampini PetscScalar *work; 265406656605SStefano Zampini PetscInt *idx_V_B; 2655ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 265606656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 2657ffd830a3SStefano Zampini 265825084f0cSStefano Zampini /* some shortcuts to scalars */ 265906656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 266088ebb749SStefano Zampini 266188ebb749SStefano Zampini PetscFunctionBegin; 26629a962809SStefano 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"); 2663ffd830a3SStefano Zampini 2664ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 2665b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 26664f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 2667b371cd4fSStefano Zampini n_B = pcis->n_B; 2668b371cd4fSStefano Zampini n_D = pcis->n - n_B; 266988ebb749SStefano Zampini n_R = pcis->n - n_vertices; 267088ebb749SStefano Zampini 267188ebb749SStefano Zampini /* vertices in boundary numbering */ 2672785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 26730e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 26746c4ed002SBarry Smith if (i != n_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D\n",n_vertices,i); 267588ebb749SStefano Zampini 267606656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 2677019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 267806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 267906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 268006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 268106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 268206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 268306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 268406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 268506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 268606656605SStefano Zampini 268706656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 268806656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 268906656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 269006656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 269106656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 2692ffd830a3SStefano Zampini lda_rhs = n_R; 2693a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 269406656605SStefano Zampini if (isLU || isILU || isCHOL) { 269506656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 2696b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 2697df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2698d62866d3SStefano Zampini MatFactorType type; 2699d62866d3SStefano Zampini 2700df4d28bfSStefano Zampini F = reuse_solver->F; 27016816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 2702d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 2703ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 270422db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 270506656605SStefano Zampini } else { 270606656605SStefano Zampini F = NULL; 270706656605SStefano Zampini } 270806656605SStefano Zampini 2709ffd830a3SStefano Zampini /* allocate workspace */ 2710ffd830a3SStefano Zampini n = 0; 2711ffd830a3SStefano Zampini if (n_constraints) { 2712ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 2713ffd830a3SStefano Zampini } 2714ffd830a3SStefano Zampini if (n_vertices) { 2715ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 2716ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 2717ffd830a3SStefano Zampini } 2718ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 2719ffd830a3SStefano Zampini 27205cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 27215cbda25cSStefano Zampini dummy_vec = NULL; 27225cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 27235cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 27245cbda25cSStefano Zampini } 27255cbda25cSStefano Zampini 272688ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 272788ebb749SStefano Zampini if (n_constraints) { 272872b8c272SStefano Zampini Mat M1,M2,M3,C_B; 272906656605SStefano Zampini IS is_aux; 273080677318SStefano Zampini PetscScalar *array,*array2; 273106656605SStefano Zampini 2732f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 273380677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 273488ebb749SStefano Zampini 273525084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 273625084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 27378ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 273872b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 273988ebb749SStefano Zampini 274080677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 274180677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 2742ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 274388ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 274406656605SStefano Zampini const PetscScalar *row_cmat_values; 274506656605SStefano Zampini const PetscInt *row_cmat_indices; 274606656605SStefano Zampini PetscInt size_of_constraint,j; 274788ebb749SStefano Zampini 274806656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 274906656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 2750ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 275106656605SStefano Zampini } 275206656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 275306656605SStefano Zampini } 2754ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 275506656605SStefano Zampini if (F) { 275606656605SStefano Zampini Mat B; 275706656605SStefano Zampini 2758ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 2759a3df083aSStefano Zampini if (need_benign_correction) { 2760df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2761a3df083aSStefano Zampini 276272b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 276372b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2764a3df083aSStefano Zampini } 276580677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 2766a3df083aSStefano Zampini if (need_benign_correction) { 2767a3df083aSStefano Zampini PetscScalar *marr; 2768df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2769a3df083aSStefano Zampini 2770a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 27715cbda25cSStefano Zampini if (lda_rhs != n_R) { 27725cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 27735cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 27745cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 27755cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 27765cbda25cSStefano Zampini } 27775cbda25cSStefano Zampini } else { 2778a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 2779a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 27805cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 2781a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2782a3df083aSStefano Zampini } 27835cbda25cSStefano Zampini } 2784a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 2785a3df083aSStefano Zampini } 278606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 278706656605SStefano Zampini } else { 278880677318SStefano Zampini PetscScalar *marr; 278980677318SStefano Zampini 279080677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 279106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 2792ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 2793ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 279406656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 279506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 279606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 279706656605SStefano Zampini } 279880677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 279906656605SStefano Zampini } 280080677318SStefano Zampini if (!pcbddc->switch_static) { 280180677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 280280677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 280380677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 280480677318SStefano Zampini for (i=0;i<n_constraints;i++) { 2805ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 280680677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 280780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 280880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 280980677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 281080677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 281180677318SStefano Zampini } 281280677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 281380677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 281472b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 281580677318SStefano Zampini } else { 2816ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2817ffd830a3SStefano Zampini IS dummy; 2818ffd830a3SStefano Zampini 2819ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 282072b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 2821ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 2822ffd830a3SStefano Zampini } else { 282380677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 282480677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 2825ffd830a3SStefano Zampini } 282625084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 282780677318SStefano Zampini } 282880677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 282980677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 283080677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 283106656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 283206656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 283380677318SStefano Zampini if (isCHOL) { 283480677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 283580677318SStefano Zampini } else { 283625084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 283780677318SStefano Zampini } 283880677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 283906656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 284025084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 284125084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 284225084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 284380677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 284472b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 284572b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 284606656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 284706656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 2848f4ddd8eeSStefano Zampini } 2849fc227af8SStefano Zampini 2850fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 285188ebb749SStefano Zampini if (n_vertices) { 285206656605SStefano Zampini IS is_aux; 28533a50541eSStefano Zampini 2854b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 28556816873aSStefano Zampini IS tis; 28566816873aSStefano Zampini 28576816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 28586816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 28596816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 28606816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 28616816873aSStefano Zampini } else { 28623a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 28636816873aSStefano Zampini } 28649577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 28659577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 286604708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 286725084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 286888ebb749SStefano Zampini } 286988ebb749SStefano Zampini 287088ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 2871f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 287206656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 287306656605SStefano Zampini if (pcbddc->coarse_phi_D) { 287406656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 287506656605SStefano Zampini } 2876f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 287706656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 287806656605SStefano Zampini PetscScalar *marray; 287906656605SStefano Zampini 288006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 288106656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 2882f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 2883f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 2884f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 2885f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 2886f4ddd8eeSStefano Zampini } 2887f4ddd8eeSStefano Zampini } 288806656605SStefano Zampini 2889f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 289006656605SStefano Zampini PetscScalar *marray; 289188ebb749SStefano Zampini 289206656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 28938eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 289406656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 289588ebb749SStefano Zampini } 28963301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 289706656605SStefano Zampini n *= 2; 289888ebb749SStefano Zampini } 289906656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 290006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 290106656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 29028eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 290306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 290406656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 290588ebb749SStefano Zampini } 29063301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 290706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 29088eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 290906656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 291006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 291188ebb749SStefano Zampini } 291288ebb749SStefano Zampini } else { 2913c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 2914c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 29151b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2916c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 2917c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 2918c0553b1fSStefano Zampini } 291988ebb749SStefano Zampini } 292006656605SStefano Zampini } 2921019a44ceSStefano Zampini 292206656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 29234f1b2e48SStefano Zampini p0_lidx_I = NULL; 29244f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 2925d12edf2fSStefano Zampini const PetscInt *idxs; 2926d12edf2fSStefano Zampini 2927d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 29284f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 29294f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 29304f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 29314f1b2e48SStefano Zampini } 2932d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 2933d12edf2fSStefano Zampini } 2934d16cbb6bSStefano Zampini 293506656605SStefano Zampini /* vertices */ 293606656605SStefano Zampini if (n_vertices) { 293716f15bc4SStefano Zampini 2938af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 293904708bb6SStefano Zampini 294016f15bc4SStefano Zampini if (n_R) { 294114393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 294206656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 294316f15bc4SStefano Zampini PetscScalar *x,*y; 294404708bb6SStefano Zampini PetscBool isseqaij; 294506656605SStefano Zampini 294621eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 294714393ed6SStefano Zampini if (need_benign_correction) { 294814393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 294914393ed6SStefano Zampini IS is_p0; 295014393ed6SStefano Zampini PetscInt *idxs_p0,n; 295114393ed6SStefano Zampini 295214393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 295314393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 295414393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 2955af25d912SStefano Zampini if (n != pcbddc->benign_n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in R numbering for benign p0! %d != %d\n",n,pcbddc->benign_n); 295614393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 295714393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 295814393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 295914393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 296014393ed6SStefano Zampini } 296114393ed6SStefano Zampini 2962ffd830a3SStefano Zampini if (lda_rhs == n_R) { 2963af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 2964ffd830a3SStefano Zampini } else { 2965ca92afb2SStefano Zampini PetscScalar *av,*array; 2966ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 2967ca92afb2SStefano Zampini PetscInt n; 2968ca92afb2SStefano Zampini PetscBool flg_row; 2969ffd830a3SStefano Zampini 2970ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 2971ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 29729d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 2973ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2974ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 2975ca92afb2SStefano Zampini for (i=0;i<n;i++) { 2976ca92afb2SStefano Zampini PetscInt j; 2977ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 2978ffd830a3SStefano Zampini } 2979ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2980ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 2981ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 2982ffd830a3SStefano Zampini } 2983ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 2984a3df083aSStefano Zampini if (need_benign_correction) { 2985df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2986a3df083aSStefano Zampini PetscScalar *marr; 2987a3df083aSStefano Zampini 2988a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 298914393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 299014393ed6SStefano Zampini 299114393ed6SStefano Zampini | 0 0 0 | (V) 299214393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 299314393ed6SStefano Zampini | 0 0 -1 | (p0) 299414393ed6SStefano Zampini 299514393ed6SStefano Zampini */ 2996df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 299714393ed6SStefano Zampini const PetscScalar *vals; 299814393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 299914393ed6SStefano Zampini PetscInt n,j,nz; 300014393ed6SStefano Zampini 3001df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3002df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 300314393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 300414393ed6SStefano Zampini for (j=0;j<n;j++) { 300514393ed6SStefano Zampini PetscScalar val = vals[j]; 300614393ed6SStefano Zampini PetscInt k,col = idxs[j]; 300714393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 300814393ed6SStefano Zampini } 300914393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3010df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 301114393ed6SStefano Zampini } 301272b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 301372b8c272SStefano Zampini } 301472b8c272SStefano Zampini if (F) { 301514393ed6SStefano Zampini /* need to correct the rhs */ 301672b8c272SStefano Zampini if (need_benign_correction) { 301772b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 301872b8c272SStefano Zampini PetscScalar *marr; 301972b8c272SStefano Zampini 302072b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 30215cbda25cSStefano Zampini if (lda_rhs != n_R) { 30225cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 30235cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 30245cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 30255cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 30265cbda25cSStefano Zampini } 30275cbda25cSStefano Zampini } else { 3028a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3029a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 30305cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3031a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3032a3df083aSStefano Zampini } 30335cbda25cSStefano Zampini } 3034a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 3035a3df083aSStefano Zampini } 303606656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 303714393ed6SStefano Zampini /* need to correct the solution */ 3038a3df083aSStefano Zampini if (need_benign_correction) { 3039df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3040a3df083aSStefano Zampini PetscScalar *marr; 3041a3df083aSStefano Zampini 3042a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 30435cbda25cSStefano Zampini if (lda_rhs != n_R) { 30445cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 30455cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 30465cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 30475cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 30485cbda25cSStefano Zampini } 30495cbda25cSStefano Zampini } else { 3050a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3051a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 30525cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3053a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3054a3df083aSStefano Zampini } 30555cbda25cSStefano Zampini } 3056a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 3057a3df083aSStefano Zampini } 305806656605SStefano Zampini } else { 305906656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 306006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 3061ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 3062ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 306306656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 306406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 306506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 306606656605SStefano Zampini } 306706656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 306806656605SStefano Zampini } 306980677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3070ffd830a3SStefano Zampini /* S_VV and S_CV */ 307106656605SStefano Zampini if (n_constraints) { 307206656605SStefano Zampini Mat B; 307380677318SStefano Zampini 3074ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 307580677318SStefano Zampini for (i=0;i<n_vertices;i++) { 3076ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3077ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 307880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 307980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 308080677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 308180677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 308280677318SStefano Zampini } 3083ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 308480677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 308580677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 3086ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 308780677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 308806656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 3089ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 3090ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 309106656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 309206656605SStefano Zampini } 309304708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 309404708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 3095511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 309604708bb6SStefano Zampini } 3097ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3098ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 3099ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3100ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 3101ffd830a3SStefano Zampini } 310206656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 310314393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 310414393ed6SStefano Zampini if (need_benign_correction) { 3105df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 310614393ed6SStefano Zampini PetscScalar *marr,*sums; 310714393ed6SStefano Zampini 310814393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 310914393ed6SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr); 3110df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 311114393ed6SStefano Zampini const PetscScalar *vals; 311214393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 311314393ed6SStefano Zampini PetscInt n,j,nz; 311414393ed6SStefano Zampini 3115df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3116df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 311714393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 311814393ed6SStefano Zampini PetscInt k; 311914393ed6SStefano Zampini sums[j] = 0.; 312014393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 312114393ed6SStefano Zampini } 312214393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 312314393ed6SStefano Zampini for (j=0;j<n;j++) { 312414393ed6SStefano Zampini PetscScalar val = vals[j]; 312514393ed6SStefano Zampini PetscInt k; 312614393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 312714393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 312814393ed6SStefano Zampini } 312914393ed6SStefano Zampini } 313014393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3131df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 313214393ed6SStefano Zampini } 313314393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 313414393ed6SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr); 313514393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 313614393ed6SStefano Zampini } 313780677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 313806656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 313906656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 314006656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 314106656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 314206656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 314306656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 314406656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3145d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 3146019a44ceSStefano Zampini } else { 3147d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3148d16cbb6bSStefano Zampini } 314921eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 3150d16cbb6bSStefano Zampini 315106656605SStefano Zampini /* coarse basis functions */ 315206656605SStefano Zampini for (i=0;i<n_vertices;i++) { 315316f15bc4SStefano Zampini PetscScalar *y; 315416f15bc4SStefano Zampini 3155ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 315606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 315706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 315806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 315906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 316006656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 316106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 316206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 316306656605SStefano Zampini 316406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 31654f1b2e48SStefano Zampini PetscInt j; 31664f1b2e48SStefano Zampini 316706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 316806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 316906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 317006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 317106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 31724f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 317306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 317406656605SStefano Zampini } 317506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 317606656605SStefano Zampini } 317704708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 317804708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 317906656605SStefano Zampini } 31805cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 318106656605SStefano Zampini 318206656605SStefano Zampini if (n_constraints) { 318306656605SStefano Zampini Mat B; 318406656605SStefano Zampini 3185ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 318606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 318780677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 318806656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 318906656605SStefano Zampini if (n_vertices) { 319080677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 319180677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 319280677318SStefano Zampini } else { 319380677318SStefano Zampini Mat S_VCt; 319480677318SStefano Zampini 3195ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3196ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 319772b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 3198ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 3199ffd830a3SStefano Zampini } 320080677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 320180677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 320280677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 320380677318SStefano Zampini } 320406656605SStefano Zampini } 320506656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 320606656605SStefano Zampini /* coarse basis functions */ 320706656605SStefano Zampini for (i=0;i<n_constraints;i++) { 320806656605SStefano Zampini PetscScalar *y; 320906656605SStefano Zampini 3210ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 321106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 321206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 321306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 321406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 321506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 321606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 321706656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 32184f1b2e48SStefano Zampini PetscInt j; 32194f1b2e48SStefano Zampini 322006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 322106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 322206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 322306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 322406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 32254f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 322606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 322706656605SStefano Zampini } 322806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 322906656605SStefano Zampini } 323006656605SStefano Zampini } 323180677318SStefano Zampini if (n_constraints) { 323280677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 323380677318SStefano Zampini } 32344f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 323572b8c272SStefano Zampini 323672b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 323772b8c272SStefano Zampini if (pcbddc->benign_n) { 323872b8c272SStefano Zampini Mat B0_B,B0_BPHI; 323972b8c272SStefano Zampini IS is_dummy; 324072b8c272SStefano Zampini PetscScalar *data; 324172b8c272SStefano Zampini PetscInt j; 324272b8c272SStefano Zampini 324372b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 324472b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 324572b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 324672b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 324786c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 324872b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 324972b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 325072b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 325172b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 325272b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 325372b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 325472b8c272SStefano Zampini } 325572b8c272SStefano Zampini } 325672b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 325772b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 325872b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 325972b8c272SStefano Zampini } 3260019a44ceSStefano Zampini 326106656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 32623301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3263ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 3264ffd830a3SStefano Zampini PetscScalar *marray; 326506656605SStefano Zampini 326606656605SStefano Zampini if (n_constraints) { 3267ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 326806656605SStefano Zampini 3269af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 327006656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 3271ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 327216f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 327306656605SStefano Zampini if (n_vertices) { 3274ffd830a3SStefano Zampini Mat S_VCT; 327506656605SStefano Zampini 327606656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 3277ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 327816f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 327906656605SStefano Zampini } 3280ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 32815b782168SStefano Zampini } else { 32825b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 328306656605SStefano Zampini } 328416f15bc4SStefano Zampini if (n_vertices && n_R) { 3285ffd830a3SStefano Zampini PetscScalar *av,*marray; 3286ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 3287ffd830a3SStefano Zampini PetscInt n; 3288ffd830a3SStefano Zampini PetscBool flg_row; 328906656605SStefano Zampini 3290ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 3291af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3292ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3293ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 3294ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3295ffd830a3SStefano Zampini for (i=0;i<n;i++) { 3296ffd830a3SStefano Zampini PetscInt j; 3297ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 3298ffd830a3SStefano Zampini } 3299ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 3300ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3301ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 330206656605SStefano Zampini } 330306656605SStefano Zampini 3304ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 3305ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3306ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 3307ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 3308ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 330906656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 331006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 331106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 331206656605SStefano Zampini } 3313ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 33145b782168SStefano Zampini if (B_C) { 3315ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 3316ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 3317ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 3318ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 3319ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 3320ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3321ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 332206656605SStefano Zampini } 3323ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 33245b782168SStefano Zampini } 332506656605SStefano Zampini /* coarse basis functions */ 332606656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 332706656605SStefano Zampini PetscScalar *y; 332806656605SStefano Zampini 3329ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 333006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 333106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 333206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 333306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 333406656605SStefano Zampini if (i<n_vertices) { 333506656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 333606656605SStefano Zampini } 333706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 333806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 333906656605SStefano Zampini 334006656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 334106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 334206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 334306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 334406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 334506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 334606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 334706656605SStefano Zampini } 334806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 334906656605SStefano Zampini } 3350ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 3351ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 335206656605SStefano Zampini } 3353d62866d3SStefano Zampini /* free memory */ 335488ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 335506656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 335606656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 335706656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 335806656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 3359d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3360d62866d3SStefano Zampini if (n_vertices) { 3361d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 3362d62866d3SStefano Zampini } 3363d62866d3SStefano Zampini if (n_constraints) { 3364d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 3365d62866d3SStefano Zampini } 336688ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 336788ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 336888ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 3369d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 337088ebb749SStefano Zampini Mat coarse_sub_mat; 337125084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 337288ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 337388ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 337488ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 33758bec7fa6SStefano Zampini Mat C_B,CPHI; 33768bec7fa6SStefano Zampini IS is_dummy; 33778bec7fa6SStefano Zampini Vec mones; 337888ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 337988ebb749SStefano Zampini PetscReal real_value; 338088ebb749SStefano Zampini 3381a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 3382a3df083aSStefano Zampini Mat A; 3383a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 3384a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 3385a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 3386a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 3387a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3388a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 3389a3df083aSStefano Zampini } else { 339088ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 339188ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 339288ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 339388ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3394a3df083aSStefano Zampini } 339588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 339688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 3397ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 339888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 339988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 340088ebb749SStefano Zampini } 340188ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 340288ebb749SStefano Zampini 340325084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 34043301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 340525084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3406ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 340788ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 340888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 340988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 341088ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 341188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 341288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 341388ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 341488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 341588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 341688ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 341788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 341888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 341988ebb749SStefano Zampini } else { 342088ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 342188ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 342288ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 342388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 342488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 342588ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 342688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 342788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 342888ebb749SStefano Zampini } 342988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 343088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 343188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 3432511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 34334f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3434fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 3435d12edf2fSStefano Zampini PetscScalar *data,*data2; 34364f1b2e48SStefano Zampini PetscInt j; 3437d12edf2fSStefano Zampini 34384f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 3439fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 3440d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 344186c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 3442d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 3443d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 34444f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 34454f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 3446d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 34474f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 34484f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 34494f1b2e48SStefano Zampini } 3450d12edf2fSStefano Zampini } 3451d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 3452d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 3453d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 3454d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 3455d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 3456d12edf2fSStefano Zampini } 3457d12edf2fSStefano Zampini #if 0 3458d12edf2fSStefano Zampini { 3459d12edf2fSStefano Zampini PetscViewer viewer; 3460d12edf2fSStefano Zampini char filename[256]; 3461ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 3462d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 3463d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3464ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 3465ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 3466ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 3467d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 346872b8c272SStefano Zampini if (save_change) { 346972b8c272SStefano Zampini Mat phi_B; 347072b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 347172b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 347272b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 347372b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 347472b8c272SStefano Zampini } else { 3475ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 3476ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 347772b8c272SStefano Zampini } 3478ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 3479ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 3480ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 3481ffd830a3SStefano Zampini } 3482ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 3483ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 3484ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 3485ffd830a3SStefano Zampini } 348672b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 3487ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 3488ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 3489ffd830a3SStefano Zampini } 3490d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3491d12edf2fSStefano Zampini } 3492d12edf2fSStefano Zampini #endif 349381d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 34948bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 34951575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 349606656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 34978bec7fa6SStefano Zampini 34988bec7fa6SStefano Zampini /* check constraints */ 3499a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 3500a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 35014f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 35028bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3503a00504b5SStefano Zampini } else { 3504a00504b5SStefano Zampini PetscScalar *data; 3505a00504b5SStefano Zampini Mat tmat; 3506a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 3507a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 3508a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 3509a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3510a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3511a00504b5SStefano Zampini } 35128bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 35138bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 35148bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 35158bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 3516bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 3517ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 3518bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3519bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 3520bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 3521bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 3522bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 352388ebb749SStefano Zampini } 35248bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 35258bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 35268bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 35278bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 352825084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 352988ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 353088ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 353188ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 353288ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 353388ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 353488ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 353588ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 353688ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 353788ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 353888ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 3539ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 354088ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 354188ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 354288ebb749SStefano Zampini } 354388ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 354488ebb749SStefano Zampini } 35458629588bSStefano Zampini /* get back data */ 35468629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 354788ebb749SStefano Zampini PetscFunctionReturn(0); 354888ebb749SStefano Zampini } 354988ebb749SStefano Zampini 355088ebb749SStefano Zampini #undef __FUNCT__ 3551d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 3552d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 3553aa0d41d4SStefano Zampini { 3554d65f70fdSStefano Zampini Mat *work_mat; 3555d65f70fdSStefano Zampini IS isrow_s,iscol_s; 3556d65f70fdSStefano Zampini PetscBool rsorted,csorted; 3557c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 3558aa0d41d4SStefano Zampini PetscErrorCode ierr; 3559aa0d41d4SStefano Zampini 3560aa0d41d4SStefano Zampini PetscFunctionBegin; 3561d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 3562d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 3563d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 3564d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 3565aa0d41d4SStefano Zampini 3566d65f70fdSStefano Zampini if (!rsorted) { 3567906d46d4SStefano Zampini const PetscInt *idxs; 3568906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 3569aa0d41d4SStefano Zampini 3570d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 3571d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 3572d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3573d65f70fdSStefano Zampini idxs_perm_r[i] = i; 3574aa0d41d4SStefano Zampini } 3575d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 3576d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 3577d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3578d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 3579aa0d41d4SStefano Zampini } 3580d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 3581d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 3582d65f70fdSStefano Zampini } else { 3583d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 3584d65f70fdSStefano Zampini isrow_s = isrow; 3585aa0d41d4SStefano Zampini } 3586906d46d4SStefano Zampini 3587d65f70fdSStefano Zampini if (!csorted) { 3588d65f70fdSStefano Zampini if (isrow == iscol) { 3589d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 3590d65f70fdSStefano Zampini iscol_s = isrow_s; 3591d65f70fdSStefano Zampini } else { 3592d65f70fdSStefano Zampini const PetscInt *idxs; 3593d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 3594906d46d4SStefano Zampini 3595d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 3596d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 3597d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3598d65f70fdSStefano Zampini idxs_perm_c[i] = i; 3599d65f70fdSStefano Zampini } 3600d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 3601d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 3602d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3603d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 3604d65f70fdSStefano Zampini } 3605d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 3606d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 3607d65f70fdSStefano Zampini } 3608d65f70fdSStefano Zampini } else { 3609d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 3610d65f70fdSStefano Zampini iscol_s = iscol; 3611d65f70fdSStefano Zampini } 3612d65f70fdSStefano Zampini 3613d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 3614d65f70fdSStefano Zampini 3615d65f70fdSStefano Zampini if (!rsorted || !csorted) { 3616906d46d4SStefano Zampini Mat new_mat; 3617d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 3618906d46d4SStefano Zampini 3619d65f70fdSStefano Zampini if (!rsorted) { 3620d65f70fdSStefano Zampini PetscInt *idxs_r,i; 3621d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 3622d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3623d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 3624906d46d4SStefano Zampini } 3625d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 3626d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 3627d65f70fdSStefano Zampini } else { 3628d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 3629906d46d4SStefano Zampini } 3630d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 3631d65f70fdSStefano Zampini 3632d65f70fdSStefano Zampini if (!csorted) { 3633d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 3634d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 3635d65f70fdSStefano Zampini is_perm_c = is_perm_r; 3636d65f70fdSStefano Zampini } else { 3637d65f70fdSStefano Zampini PetscInt *idxs_c,i; 3638d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 3639d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3640d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 3641d65f70fdSStefano Zampini } 3642d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 3643d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 3644d65f70fdSStefano Zampini } 3645d65f70fdSStefano Zampini } else { 3646d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 3647d65f70fdSStefano Zampini } 3648d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 3649d65f70fdSStefano Zampini 3650d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 3651d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 3652d65f70fdSStefano Zampini work_mat[0] = new_mat; 3653d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 3654d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 3655d65f70fdSStefano Zampini } 3656d65f70fdSStefano Zampini 3657d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 3658d65f70fdSStefano Zampini *B = work_mat[0]; 3659d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 3660d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 3661d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 3662d65f70fdSStefano Zampini PetscFunctionReturn(0); 3663d65f70fdSStefano Zampini } 3664d65f70fdSStefano Zampini 3665d65f70fdSStefano Zampini #undef __FUNCT__ 36665e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 36675e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 3668aa0d41d4SStefano Zampini { 3669aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 36705e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3671d65f70fdSStefano Zampini Mat new_mat; 36725e8657edSStefano Zampini IS is_local,is_global; 3673d65f70fdSStefano Zampini PetscInt local_size; 3674d65f70fdSStefano Zampini PetscBool isseqaij; 3675aa0d41d4SStefano Zampini PetscErrorCode ierr; 3676aa0d41d4SStefano Zampini 3677aa0d41d4SStefano Zampini PetscFunctionBegin; 3678aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 36795e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 36805e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 3681b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 3682aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 3683d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 3684aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 3685906d46d4SStefano Zampini 3686906d46d4SStefano Zampini /* check */ 3687906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3688906d46d4SStefano Zampini Vec x,x_change; 3689906d46d4SStefano Zampini PetscReal error; 3690906d46d4SStefano Zampini 36915e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 3692906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 36935e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 3694e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3695e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3696d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 3697e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3698e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3699906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3700906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3701906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3702906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 3703906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3704906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3705906d46d4SStefano Zampini } 3706906d46d4SStefano Zampini 370722d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 37089b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 370922d5777bSStefano Zampini if (isseqaij) { 3710a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3711a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 3712aa0d41d4SStefano Zampini } else { 3713a00504b5SStefano Zampini Mat work_mat; 37141cf9b237SStefano Zampini 3715a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3716aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 3717a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 37181d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 3719aa0d41d4SStefano Zampini } 37203301b35fSStefano Zampini if (matis->A->symmetric_set) { 37213301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 3722e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 37233301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 3724e496cd5dSStefano Zampini #endif 37253301b35fSStefano Zampini } 3726d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 3727aa0d41d4SStefano Zampini PetscFunctionReturn(0); 3728aa0d41d4SStefano Zampini } 3729aa0d41d4SStefano Zampini 3730aa0d41d4SStefano Zampini #undef __FUNCT__ 3731a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 37328ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 3733a64d13efSStefano Zampini { 3734a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3735a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3736d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 373753892102SStefano Zampini PetscInt *idx_R_local=NULL; 37383a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 37393a50541eSStefano Zampini PetscInt vbs,bs; 37406816873aSStefano Zampini PetscBT bitmask=NULL; 3741a64d13efSStefano Zampini PetscErrorCode ierr; 3742a64d13efSStefano Zampini 3743a64d13efSStefano Zampini PetscFunctionBegin; 3744b23d619eSStefano Zampini /* 3745b23d619eSStefano Zampini No need to setup local scatters if 3746b23d619eSStefano Zampini - primal space is unchanged 3747b23d619eSStefano Zampini AND 3748b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 3749b23d619eSStefano Zampini AND 3750b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 3751b23d619eSStefano Zampini */ 3752b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 3753f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 3754f4ddd8eeSStefano Zampini } 3755f4ddd8eeSStefano Zampini /* destroy old objects */ 3756f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3757f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3758f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3759a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 3760b371cd4fSStefano Zampini n_B = pcis->n_B; 3761b371cd4fSStefano Zampini n_D = pcis->n - n_B; 3762b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 37633a50541eSStefano Zampini 3764a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 37656816873aSStefano Zampini 376653892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 3767b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 3768854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 3769a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 3770a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 37710e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 3772a64d13efSStefano Zampini } 3773a64d13efSStefano Zampini 3774a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 37754641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 37766816873aSStefano Zampini idx_R_local[n_R++] = i; 3777a64d13efSStefano Zampini } 3778a64d13efSStefano Zampini } 3779df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 3780df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 37816816873aSStefano Zampini 3782df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3783df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 37846816873aSStefano Zampini } 37853a50541eSStefano Zampini 37863a50541eSStefano Zampini /* Block code */ 37873a50541eSStefano Zampini vbs = 1; 37883a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 37893a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 37903a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 37913a50541eSStefano Zampini PetscInt *vary; 3792b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 3793785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 37943a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 3795d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 3796d3df7717SStefano 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 */ 37970e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 3798d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 37993a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 38003a50541eSStefano Zampini is_blocked = PETSC_FALSE; 38013a50541eSStefano Zampini break; 38023a50541eSStefano Zampini } 38033a50541eSStefano Zampini } 3804d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 3805d3df7717SStefano Zampini } else { 3806d3df7717SStefano Zampini /* Verify directly the R set */ 3807d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 3808d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 3809d3df7717SStefano Zampini for (j=1; j<bs; j++) { 3810d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 3811d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 3812d3df7717SStefano Zampini break; 3813d3df7717SStefano Zampini } 3814d3df7717SStefano Zampini } 3815d3df7717SStefano Zampini } 3816d3df7717SStefano Zampini } 38173a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 38183a50541eSStefano Zampini vbs = bs; 38193a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 38203a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 38213a50541eSStefano Zampini } 38223a50541eSStefano Zampini } 38233a50541eSStefano Zampini } 38243a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 3825b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3826df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 382753892102SStefano Zampini 3828df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3829df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 383053892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 3831df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 383253892102SStefano Zampini } else { 38333a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 383453892102SStefano Zampini } 3835a64d13efSStefano Zampini 3836a64d13efSStefano Zampini /* print some info if requested */ 3837a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 3838a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3839a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 38401575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3841a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 3842a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 38434f1b2e48SStefano 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); 3844a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3845a64d13efSStefano Zampini } 3846a64d13efSStefano Zampini 3847a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 3848b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 38496816873aSStefano Zampini IS is_aux1,is_aux2; 38506816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 38516816873aSStefano Zampini 38523a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3853854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 3854854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 3855a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 38564641a718SStefano Zampini for (i=0; i<n_D; i++) { 38574641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 38584641a718SStefano Zampini } 3859a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3860a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 38614641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 38624641a718SStefano Zampini aux_array1[j++] = i; 3863a64d13efSStefano Zampini } 3864a64d13efSStefano Zampini } 3865a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 3866a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3867a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 38684641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 38694641a718SStefano Zampini aux_array2[j++] = i; 3870a64d13efSStefano Zampini } 3871a64d13efSStefano Zampini } 3872a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3873a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 3874a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 3875a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 3876a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 3877a64d13efSStefano Zampini 38788eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3879785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 3880a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 38814641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 38824641a718SStefano Zampini aux_array1[j++] = i; 3883a64d13efSStefano Zampini } 3884a64d13efSStefano Zampini } 3885a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 3886a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 3887a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 3888a64d13efSStefano Zampini } 38894641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 38903a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3891d62866d3SStefano Zampini } else { 3892df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 38936816873aSStefano Zampini IS tis; 38946816873aSStefano Zampini PetscInt schur_size; 38956816873aSStefano Zampini 3896df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 38976816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 3898df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 38996816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 39006816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 39016816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 39026816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 39036816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 3904d62866d3SStefano Zampini } 3905d62866d3SStefano Zampini } 3906a64d13efSStefano Zampini PetscFunctionReturn(0); 3907a64d13efSStefano Zampini } 3908a64d13efSStefano Zampini 3909304d26faSStefano Zampini 3910304d26faSStefano Zampini #undef __FUNCT__ 3911304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 3912684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 3913304d26faSStefano Zampini { 3914304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3915304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3916304d26faSStefano Zampini PC pc_temp; 3917304d26faSStefano Zampini Mat A_RR; 3918f4ddd8eeSStefano Zampini MatReuse reuse; 3919304d26faSStefano Zampini PetscScalar m_one = -1.0; 3920304d26faSStefano Zampini PetscReal value; 392104708bb6SStefano Zampini PetscInt n_D,n_R; 3922c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 3923304d26faSStefano Zampini PetscErrorCode ierr; 3924e604994aSStefano Zampini /* prefixes stuff */ 3925312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 3926e604994aSStefano Zampini size_t len; 3927304d26faSStefano Zampini 3928304d26faSStefano Zampini PetscFunctionBegin; 3929304d26faSStefano Zampini 3930e604994aSStefano Zampini /* compute prefixes */ 3931e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 3932e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 3933e604994aSStefano Zampini if (!pcbddc->current_level) { 3934e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3935e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3936e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 3937e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 3938e604994aSStefano Zampini } else { 3939e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 3940312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 3941e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 3942e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 3943312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 3944312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 394534d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 394634d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 3947e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 3948e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 3949e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 3950e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 3951e604994aSStefano Zampini } 3952e604994aSStefano Zampini 3953304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 3954684f6988SStefano Zampini if (dirichlet) { 3955d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3956450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 39579a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 3958450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 3959a3df083aSStefano Zampini Mat A_IIn; 3960a3df083aSStefano Zampini 3961a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 3962a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 3963a3df083aSStefano Zampini pcis->A_II = A_IIn; 3964a3df083aSStefano Zampini } 3965450f8f5eSStefano Zampini } 39663301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 39673301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 3968964fefecSStefano Zampini } 3969ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 3970964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 3971304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 3972304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 3973304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 3974304d26faSStefano Zampini /* default */ 3975304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 3976e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 39779577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 3978304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 39799577ea80SStefano Zampini if (issbaij) { 39809577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 39819577ea80SStefano Zampini } else { 3982304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 39839577ea80SStefano Zampini } 3984304d26faSStefano Zampini /* Allow user's customization */ 3985304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 3986304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 3987304d26faSStefano Zampini } 3988d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 3989b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3990df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3991d62866d3SStefano Zampini 3992df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 3993d5574798SStefano Zampini } 3994304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 3995304d26faSStefano Zampini if (!n_D) { 3996304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 3997304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 3998304d26faSStefano Zampini } 3999304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 4000304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 4001304d26faSStefano Zampini /* set ksp_D into pcis data */ 4002304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 4003304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 4004304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 4005684f6988SStefano Zampini } 4006304d26faSStefano Zampini 4007304d26faSStefano Zampini /* NEUMANN PROBLEM */ 4008684f6988SStefano Zampini A_RR = 0; 4009684f6988SStefano Zampini if (neumann) { 4010d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 401104708bb6SStefano Zampini PetscInt ibs,mbs; 401204708bb6SStefano Zampini PetscBool issbaij; 401304708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4014f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 40158ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 4016f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 4017f4ddd8eeSStefano Zampini PetscInt nn_R; 401881d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 4019f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4020f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 4021f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 4022f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 4023f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4024f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4025f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 4026727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 4027f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4028f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4029f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 4030f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 4031f4ddd8eeSStefano Zampini } 4032f4ddd8eeSStefano Zampini } 4033f4ddd8eeSStefano Zampini /* last check */ 4034d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 4035f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4036f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4037f4ddd8eeSStefano Zampini } 4038f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 4039f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4040f4ddd8eeSStefano Zampini } 4041a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 4042af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 4043af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 404404708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 404504708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 404604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 404704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 404804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 4049af732b37SStefano Zampini } else { 4050511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 40516816873aSStefano Zampini } 405204708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 405304708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 405404708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 405504708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 405604708bb6SStefano Zampini } else { 4057511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 405804708bb6SStefano Zampini } 405904708bb6SStefano Zampini } 4060a00504b5SStefano Zampini /* extract A_RR */ 4061b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4062a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4063a00504b5SStefano Zampini 4064a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 406516e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4066a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 406716e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 406816e386b8SStefano Zampini } else { 4069a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 4070a00504b5SStefano Zampini } 4071a00504b5SStefano Zampini } else { 4072a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4073a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 4074a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4075a00504b5SStefano Zampini } 4076a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 4077f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 407816e386b8SStefano Zampini } 40793301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 40803301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 40816816873aSStefano Zampini } 4082f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 4083304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 4084304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 4085304d26faSStefano Zampini /* default */ 4086304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 4087e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 4088304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 40899577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 40909577ea80SStefano Zampini if (issbaij) { 40919577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 40929577ea80SStefano Zampini } else { 4093304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 40949577ea80SStefano Zampini } 4095304d26faSStefano Zampini /* Allow user's customization */ 4096304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 4097304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4098304d26faSStefano Zampini } 4099304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4100304d26faSStefano Zampini if (!n_R) { 4101304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 4102304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4103304d26faSStefano Zampini } 41045cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 4105df4d28bfSStefano Zampini /* Reuse solver if it is present */ 4106b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4107df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4108d62866d3SStefano Zampini 4109df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 4110d62866d3SStefano Zampini } 4111304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 4112304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 4113684f6988SStefano Zampini } 4114304d26faSStefano Zampini 4115684f6988SStefano Zampini if (pcbddc->dbg_flag) { 4116684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 41171575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4118684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4119684f6988SStefano Zampini } 4120c7017625SStefano Zampini 4121c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 4122c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 4123c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 4124c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 4125c7017625SStefano Zampini } 4126c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 4127c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 4128c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 4129c7017625SStefano Zampini } 4130c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 4131c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 4132c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 4133c7017625SStefano Zampini } 4134c7017625SStefano Zampini 4135c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 4136c7017625SStefano Zampini if (pcbddc->dbg_flag) { 4137684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 41380fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 41390fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 41400fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 41410fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 41420fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 4143e604994aSStefano 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); 4144c7017625SStefano Zampini if (check_corr[0]) { 4145c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 4146c7017625SStefano Zampini } 4147304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4148304d26faSStefano Zampini } 4149684f6988SStefano Zampini if (neumann) { /* Neumann */ 41500fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 41510fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 41520fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 41530fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 41540fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 4155e604994aSStefano 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); 4156c7017625SStefano Zampini if (check_corr[1]) { 4157c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 4158c7017625SStefano Zampini } 4159304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4160304d26faSStefano Zampini } 4161684f6988SStefano Zampini } 41625cbda25cSStefano Zampini /* free Neumann problem's matrix */ 41635cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4164304d26faSStefano Zampini PetscFunctionReturn(0); 4165304d26faSStefano Zampini } 4166304d26faSStefano Zampini 4167304d26faSStefano Zampini #undef __FUNCT__ 4168ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 416980677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 4170674ae819SStefano Zampini { 4171674ae819SStefano Zampini PetscErrorCode ierr; 4172674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4173be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4174b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 4175674ae819SStefano Zampini 4176674ae819SStefano Zampini PetscFunctionBegin; 4177b334f244SStefano Zampini if (!reuse_solver) { 417880677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 417920c7b377SStefano Zampini } 418080677318SStefano Zampini if (!pcbddc->switch_static) { 418180677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 418280677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 418380677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 418420c7b377SStefano Zampini } 4185b334f244SStefano Zampini if (!reuse_solver) { 418680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 418780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 418820c7b377SStefano Zampini } else { 4189df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4190be83ff47SStefano Zampini 4191df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4192df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 419320c7b377SStefano Zampini } 4194be83ff47SStefano Zampini } else { 419580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 419680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 419780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 419880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 419980677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 420080677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 420180677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 420280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 420380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4204674ae819SStefano Zampini } 4205674ae819SStefano Zampini } 4206b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 420780677318SStefano Zampini if (applytranspose) { 420880677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 420980677318SStefano Zampini } else { 421080677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 421180677318SStefano Zampini } 4212be83ff47SStefano Zampini } else { 4213df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4214be83ff47SStefano Zampini 4215be83ff47SStefano Zampini if (applytranspose) { 4216df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4217be83ff47SStefano Zampini } else { 4218df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4219be83ff47SStefano Zampini } 4220be83ff47SStefano Zampini } 422180677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 422280677318SStefano Zampini if (!pcbddc->switch_static) { 4223b334f244SStefano Zampini if (!reuse_solver) { 422480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 422580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4226be83ff47SStefano Zampini } else { 4227df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4228be83ff47SStefano Zampini 4229df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4230df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4231be83ff47SStefano Zampini } 423280677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 423380677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 423480677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 423580677318SStefano Zampini } 423680677318SStefano Zampini } else { 423780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 423880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 423980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 424080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 424180677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 424280677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 424380677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 424480677318SStefano Zampini } 424580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 424680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 424780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 424880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4249674ae819SStefano Zampini } 4250674ae819SStefano Zampini PetscFunctionReturn(0); 4251674ae819SStefano Zampini } 4252674ae819SStefano Zampini 4253dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 4254674ae819SStefano Zampini #undef __FUNCT__ 4255674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 4256dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 4257674ae819SStefano Zampini { 4258674ae819SStefano Zampini PetscErrorCode ierr; 4259674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4260674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 4261674ae819SStefano Zampini const PetscScalar zero = 0.0; 4262674ae819SStefano Zampini 4263674ae819SStefano Zampini PetscFunctionBegin; 4264dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 42654fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4266dc359a40SStefano Zampini if (applytranspose) { 4267674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 42688eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 4269dc359a40SStefano Zampini } else { 4270674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 4271674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 427215aaf578SStefano Zampini } 42734fee134fSStefano Zampini } else { 42744fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 42754fee134fSStefano Zampini } 4276efc2fbd9SStefano Zampini 4277efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 42784f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4279efc2fbd9SStefano Zampini PetscScalar *array; 42804f1b2e48SStefano Zampini PetscInt j; 4281efc2fbd9SStefano Zampini 4282efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 42834f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 4284efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4285efc2fbd9SStefano Zampini } 4286efc2fbd9SStefano Zampini 428712edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 428812edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 428912edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 429012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 429112edc857SStefano Zampini 42929f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 429312edc857SStefano Zampini if (pcbddc->coarse_ksp) { 429451694757SStefano Zampini Mat coarse_mat; 4295964fefecSStefano Zampini Vec rhs,sol; 429651694757SStefano Zampini MatNullSpace nullsp; 429727b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 4298964fefecSStefano Zampini 429927b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 430027b6a85dSStefano Zampini PC coarse_pc; 430127b6a85dSStefano Zampini 430227b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 430327b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 430427b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 430527b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 430627b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 430727b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 43083bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 430927b6a85dSStefano Zampini } 431027b6a85dSStefano Zampini } 4311964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 4312964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 431351694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 431451694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 431551694757SStefano Zampini if (nullsp) { 431651694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 431751694757SStefano Zampini } 431812edc857SStefano Zampini if (applytranspose) { 43199a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 4320964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 43212701bc32SStefano Zampini } else { 43221f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 43232701bc32SStefano Zampini PC coarse_pc; 43242701bc32SStefano Zampini 43252701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 43262701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 43273e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 43282701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 432912edc857SStefano Zampini } else { 4330964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 433112edc857SStefano Zampini } 43322701bc32SStefano Zampini } 43331d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 433427b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 433527b6a85dSStefano Zampini PC coarse_pc; 433627b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 433727b6a85dSStefano Zampini 433827b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 433927b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 434027b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 43413bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 434227b6a85dSStefano Zampini } 434351694757SStefano Zampini if (nullsp) { 434451694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 434551694757SStefano Zampini } 434612edc857SStefano Zampini } 4347674ae819SStefano Zampini 4348674ae819SStefano Zampini /* Local solution on R nodes */ 43494fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 435080677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 43519f00e9b4SStefano Zampini } 43529f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 43539f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 435412edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4355674ae819SStefano Zampini 43564fee134fSStefano Zampini /* Sum contributions from the two levels */ 43574fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4358dc359a40SStefano Zampini if (applytranspose) { 4359dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 4360dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4361dc359a40SStefano Zampini } else { 4362674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 43638eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4364dc359a40SStefano Zampini } 4365efc2fbd9SStefano Zampini /* store p0 */ 43664f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4367efc2fbd9SStefano Zampini PetscScalar *array; 43684f1b2e48SStefano Zampini PetscInt j; 4369efc2fbd9SStefano Zampini 4370efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 43714f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 4372efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4373efc2fbd9SStefano Zampini } 43744fee134fSStefano Zampini } else { /* expand the coarse solution */ 43754fee134fSStefano Zampini if (applytranspose) { 43764fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 43774fee134fSStefano Zampini } else { 43784fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 43794fee134fSStefano Zampini } 43804fee134fSStefano Zampini } 4381674ae819SStefano Zampini PetscFunctionReturn(0); 4382674ae819SStefano Zampini } 4383674ae819SStefano Zampini 4384674ae819SStefano Zampini #undef __FUNCT__ 4385674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 438612edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 4387674ae819SStefano Zampini { 4388674ae819SStefano Zampini PetscErrorCode ierr; 4389674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 439058da7f69SStefano Zampini PetscScalar *array; 439112edc857SStefano Zampini Vec from,to; 4392674ae819SStefano Zampini 4393674ae819SStefano Zampini PetscFunctionBegin; 439412edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 439512edc857SStefano Zampini from = pcbddc->coarse_vec; 439612edc857SStefano Zampini to = pcbddc->vec1_P; 439712edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 439812edc857SStefano Zampini Vec tvec; 439958da7f69SStefano Zampini 440058da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 440158da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 440212edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 440358da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 440458da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 440558da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 440612edc857SStefano Zampini } 440712edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 440812edc857SStefano Zampini from = pcbddc->vec1_P; 440912edc857SStefano Zampini to = pcbddc->coarse_vec; 441012edc857SStefano Zampini } 441112edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 4412674ae819SStefano Zampini PetscFunctionReturn(0); 4413674ae819SStefano Zampini } 4414674ae819SStefano Zampini 4415674ae819SStefano Zampini #undef __FUNCT__ 4416674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 441712edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 4418674ae819SStefano Zampini { 4419674ae819SStefano Zampini PetscErrorCode ierr; 4420674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 442158da7f69SStefano Zampini PetscScalar *array; 442212edc857SStefano Zampini Vec from,to; 4423674ae819SStefano Zampini 4424674ae819SStefano Zampini PetscFunctionBegin; 442512edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 442612edc857SStefano Zampini from = pcbddc->coarse_vec; 442712edc857SStefano Zampini to = pcbddc->vec1_P; 442812edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 442912edc857SStefano Zampini from = pcbddc->vec1_P; 443012edc857SStefano Zampini to = pcbddc->coarse_vec; 443112edc857SStefano Zampini } 443212edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 443312edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 443412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 443512edc857SStefano Zampini Vec tvec; 443658da7f69SStefano Zampini 443712edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 443858da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 443958da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 444058da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 444158da7f69SStefano Zampini } 444258da7f69SStefano Zampini } else { 444358da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 444458da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 444512edc857SStefano Zampini } 444612edc857SStefano Zampini } 4447674ae819SStefano Zampini PetscFunctionReturn(0); 4448674ae819SStefano Zampini } 4449674ae819SStefano Zampini 4450984c4197SStefano Zampini /* uncomment for testing purposes */ 4451984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 4452674ae819SStefano Zampini #undef __FUNCT__ 4453674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 4454674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 4455674ae819SStefano Zampini { 4456674ae819SStefano Zampini PetscErrorCode ierr; 4457674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4458674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4459674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4460984c4197SStefano Zampini /* one and zero */ 4461984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 4462984c4197SStefano Zampini /* space to store constraints and their local indices */ 44639162d606SStefano Zampini PetscScalar *constraints_data; 44649162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 44659162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 44669162d606SStefano Zampini PetscInt *constraints_n; 4467984c4197SStefano Zampini /* iterators */ 4468b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 4469984c4197SStefano Zampini /* BLAS integers */ 4470e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 4471e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 4472c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 4473727cdba6SStefano Zampini /* reuse */ 44740e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 44750e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 4476984c4197SStefano Zampini /* change of basis */ 4477b3d85658SStefano Zampini PetscBool qr_needed; 44789162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 4479984c4197SStefano Zampini /* auxiliary stuff */ 448064efe560SStefano Zampini PetscInt *nnz,*is_indices; 44818a0068c3SStefano Zampini PetscInt ncc; 4482984c4197SStefano Zampini /* some quantities */ 448345a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 4484a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 4485984c4197SStefano Zampini 4486674ae819SStefano Zampini PetscFunctionBegin; 44878e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 44888e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 44898e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 449016909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 4491088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 4492088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 44930e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 44940e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 44950e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 44960e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 44970e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 4498088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 4499cf5a6209SStefano Zampini 4500cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 45019162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 4502cf5a6209SStefano Zampini MatNullSpace nearnullsp; 4503cf5a6209SStefano Zampini const Vec *nearnullvecs; 4504cf5a6209SStefano Zampini Vec *localnearnullsp; 4505cf5a6209SStefano Zampini PetscScalar *array; 4506cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 4507cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 4508674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 4509b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 4510674ae819SStefano Zampini PetscScalar *work; 4511674ae819SStefano Zampini PetscReal *singular_vals; 4512674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4513674ae819SStefano Zampini PetscReal *rwork; 4514674ae819SStefano Zampini #endif 4515674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4516674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 4517674ae819SStefano Zampini #else 4518964fefecSStefano Zampini PetscBLASInt dummy_int=1; 4519964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 4520674ae819SStefano Zampini #endif 4521674ae819SStefano Zampini 4522674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 4523d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 4524e4d548c7SStefano Zampini /* print some info */ 45251f4df5f7SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs) { 4526e4d548c7SStefano Zampini PetscInt nv; 4527e4d548c7SStefano Zampini 4528c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 4529e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 4530e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4531e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 4532e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 4533e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 4534e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 4535e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4536e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4537e4d548c7SStefano Zampini } 4538e4d548c7SStefano Zampini 4539d06fc5fdSStefano Zampini /* free unneeded index sets */ 4540d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 4541d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 4542674ae819SStefano Zampini } 4543d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 4544d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 4545d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 4546d06fc5fdSStefano Zampini } 4547d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 4548d06fc5fdSStefano Zampini n_ISForEdges = 0; 4549d06fc5fdSStefano Zampini } 4550d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 4551d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 4552d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 4553d06fc5fdSStefano Zampini } 4554d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 4555d06fc5fdSStefano Zampini n_ISForFaces = 0; 4556d06fc5fdSStefano Zampini } 455770022509SStefano Zampini 4558674ae819SStefano Zampini /* check if near null space is attached to global mat */ 4559674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 4560674ae819SStefano Zampini if (nearnullsp) { 4561674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 4562f4ddd8eeSStefano Zampini /* remove any stored info */ 4563f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 4564f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 4565f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 4566f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 4567f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 4568473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 4569f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 4570f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 4571f4ddd8eeSStefano Zampini } 4572984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 4573984c4197SStefano Zampini nnsp_size = 0; 4574674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 4575674ae819SStefano Zampini } 4576984c4197SStefano Zampini /* get max number of constraints on a single cc */ 4577984c4197SStefano Zampini max_constraints = nnsp_size; 4578984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 4579984c4197SStefano Zampini 4580674ae819SStefano Zampini /* 4581674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 45829162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 45839162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 45849162d606SStefano Zampini There can be multiple constraints per connected component 4585674ae819SStefano Zampini */ 4586674ae819SStefano Zampini n_vertices = 0; 4587674ae819SStefano Zampini if (ISForVertices) { 4588674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 4589674ae819SStefano Zampini } 45909162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 45919162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 45929162d606SStefano Zampini 45939162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 45949162d606SStefano Zampini total_counts *= max_constraints; 4595674ae819SStefano Zampini total_counts += n_vertices; 45964641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 45979162d606SStefano Zampini 4598674ae819SStefano Zampini total_counts = 0; 4599674ae819SStefano Zampini max_size_of_constraint = 0; 4600674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 46019162d606SStefano Zampini IS used_is; 4602674ae819SStefano Zampini if (i<n_ISForEdges) { 46039162d606SStefano Zampini used_is = ISForEdges[i]; 4604674ae819SStefano Zampini } else { 46059162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 4606674ae819SStefano Zampini } 46079162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 4608674ae819SStefano Zampini total_counts += j; 4609674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 4610674ae819SStefano Zampini } 46119162d606SStefano 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); 46129162d606SStefano Zampini 4613984c4197SStefano Zampini /* get local part of global near null space vectors */ 4614785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 4615984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 4616984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 4617e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4618e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4619984c4197SStefano Zampini } 4620674ae819SStefano Zampini 4621242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 4622242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 4623a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 4624242a89d7SStefano Zampini 4625984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 4626a773dcb8SStefano Zampini if (!skip_lapack) { 4627674ae819SStefano Zampini PetscScalar temp_work; 4628911cabfeSStefano Zampini 4629674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4630984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 4631785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 4632785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 4633785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 4634674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4635785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 4636674ae819SStefano Zampini #endif 4637674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 4638c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 4639c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 4640674ae819SStefano Zampini lwork = -1; 4641674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4642674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 4643c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 4644674ae819SStefano Zampini #else 4645c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 4646674ae819SStefano Zampini #endif 4647674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4648984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 4649674ae819SStefano Zampini #else /* on missing GESVD */ 4650674ae819SStefano Zampini /* SVD */ 4651674ae819SStefano Zampini PetscInt max_n,min_n; 4652674ae819SStefano Zampini max_n = max_size_of_constraint; 4653984c4197SStefano Zampini min_n = max_constraints; 4654984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 4655674ae819SStefano Zampini min_n = max_size_of_constraint; 4656984c4197SStefano Zampini max_n = max_constraints; 4657674ae819SStefano Zampini } 4658785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 4659674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4660785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 4661674ae819SStefano Zampini #endif 4662674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 4663674ae819SStefano Zampini lwork = -1; 4664e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 4665e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 4666b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 4667674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4668674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 46699162d606SStefano 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)); 4670674ae819SStefano Zampini #else 46719162d606SStefano 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)); 4672674ae819SStefano Zampini #endif 4673674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4674984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 4675984c4197SStefano Zampini #endif /* on missing GESVD */ 4676674ae819SStefano Zampini /* Allocate optimal workspace */ 4677674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 4678854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 4679674ae819SStefano Zampini } 4680674ae819SStefano Zampini /* Now we can loop on constraining sets */ 4681674ae819SStefano Zampini total_counts = 0; 46829162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 46839162d606SStefano Zampini constraints_data_ptr[0] = 0; 4684674ae819SStefano Zampini /* vertices */ 46859162d606SStefano Zampini if (n_vertices) { 4686674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 46879162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 4688674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 46899162d606SStefano Zampini constraints_n[total_counts] = 1; 46909162d606SStefano Zampini constraints_data[total_counts] = 1.0; 46919162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 46929162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 4693674ae819SStefano Zampini total_counts++; 4694674ae819SStefano Zampini } 4695674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4696674ae819SStefano Zampini n_vertices = total_counts; 4697674ae819SStefano Zampini } 4698984c4197SStefano Zampini 4699674ae819SStefano Zampini /* edges and faces */ 47009162d606SStefano Zampini total_counts_cc = total_counts; 4701911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 47029162d606SStefano Zampini IS used_is; 47039162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 47049162d606SStefano Zampini 4705911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 47069162d606SStefano Zampini used_is = ISForEdges[ncc]; 4707984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 4708674ae819SStefano Zampini } else { 47099162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 4710984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 4711674ae819SStefano Zampini } 4712674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 47139162d606SStefano Zampini 47149162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 47159162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4716984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 4717984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 4718674ae819SStefano Zampini if (nnsp_has_cnst) { 47195b08dc53SStefano Zampini PetscScalar quad_value; 47209162d606SStefano Zampini 47219162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 47229162d606SStefano Zampini idxs_copied = PETSC_TRUE; 47239162d606SStefano Zampini 4724a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 4725674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 4726a773dcb8SStefano Zampini } else { 4727a773dcb8SStefano Zampini quad_value = 1.0; 4728a773dcb8SStefano Zampini } 4729674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 47309162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 4731674ae819SStefano Zampini } 47329162d606SStefano Zampini temp_constraints++; 4733674ae819SStefano Zampini total_counts++; 4734674ae819SStefano Zampini } 4735674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 4736984c4197SStefano Zampini PetscReal real_value; 47379162d606SStefano Zampini PetscScalar *ptr_to_data; 47389162d606SStefano Zampini 4739984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 47409162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 4741674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 47429162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 4743674ae819SStefano Zampini } 4744984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 4745984c4197SStefano Zampini /* check if array is null on the connected component */ 4746e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 47479162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 47485b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 4749674ae819SStefano Zampini temp_constraints++; 4750674ae819SStefano Zampini total_counts++; 47519162d606SStefano Zampini if (!idxs_copied) { 47529162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 47539162d606SStefano Zampini idxs_copied = PETSC_TRUE; 4754674ae819SStefano Zampini } 4755674ae819SStefano Zampini } 47569162d606SStefano Zampini } 47579162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 475845a1bb75SStefano Zampini valid_constraints = temp_constraints; 4759eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 4760a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 47619162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 47629162d606SStefano Zampini 47639162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 4764a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 47659162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 4766a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 47679162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 4768a773dcb8SStefano Zampini } else { /* perform SVD */ 4769984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 47709162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 4771674ae819SStefano Zampini 4772674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4773984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 4774984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 4775984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 4776984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 4777984c4197SStefano Zampini from that computed using LAPACKgesvd 4778984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 4779984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 4780984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 4781674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 4782e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 4783984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4784674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 4785674ae819SStefano Zampini for (k=0;k<j+1;k++) { 47869162d606SStefano 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)); 4787674ae819SStefano Zampini } 4788674ae819SStefano Zampini } 4789e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 4790e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 4791e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 4792674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 4793c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 4794674ae819SStefano Zampini #else 4795c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 4796674ae819SStefano Zampini #endif 4797674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4798984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 4799984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 4800674ae819SStefano Zampini j = 0; 4801984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 4802674ae819SStefano Zampini total_counts = total_counts-j; 480345a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 4804e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 4805c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 4806c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 4807c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 4808c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4809c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 4810c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 4811674ae819SStefano Zampini if (j<temp_constraints) { 4812984c4197SStefano Zampini PetscInt ii; 4813984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 4814674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 48159162d606SStefano 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)); 4816674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4817984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 4818674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 48199162d606SStefano 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]; 4820674ae819SStefano Zampini } 4821674ae819SStefano Zampini } 4822674ae819SStefano Zampini } 4823674ae819SStefano Zampini #else /* on missing GESVD */ 4824e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 4825e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 4826b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4827674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4828674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 48299162d606SStefano 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)); 4830674ae819SStefano Zampini #else 48319162d606SStefano 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)); 4832674ae819SStefano Zampini #endif 4833984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 4834674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4835984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 4836e310c8b4SStefano Zampini k = temp_constraints; 4837e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 4838674ae819SStefano Zampini j = 0; 4839e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 484045a1bb75SStefano Zampini valid_constraints = k-j; 4841911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 4842984c4197SStefano Zampini #endif /* on missing GESVD */ 4843674ae819SStefano Zampini } 4844a773dcb8SStefano Zampini } 48459162d606SStefano Zampini /* update pointers information */ 48469162d606SStefano Zampini if (valid_constraints) { 48479162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 48489162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 48499162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 48509162d606SStefano Zampini /* set change_of_basis flag */ 485145a1bb75SStefano Zampini if (boolforchange) { 4852b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 48539162d606SStefano Zampini } 4854b3d85658SStefano Zampini total_counts_cc++; 485545a1bb75SStefano Zampini } 485645a1bb75SStefano Zampini } 4857984c4197SStefano Zampini /* free workspace */ 48588f1c130eSStefano Zampini if (!skip_lapack) { 4859984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4860984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4861984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 4862984c4197SStefano Zampini #endif 4863984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 4864984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4865984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 4866984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 4867984c4197SStefano Zampini #endif 4868984c4197SStefano Zampini } 4869984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 4870984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 4871984c4197SStefano Zampini } 4872984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 4873cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 4874cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 4875cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 4876cf5a6209SStefano Zampini } 4877cf5a6209SStefano Zampini if (n_ISForFaces) { 4878cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 4879cf5a6209SStefano Zampini } 4880cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 4881cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 4882cf5a6209SStefano Zampini } 4883cf5a6209SStefano Zampini if (n_ISForEdges) { 4884cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 4885cf5a6209SStefano Zampini } 4886cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 488708122e43SStefano Zampini } else { 488808122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4889984c4197SStefano Zampini 489008122e43SStefano Zampini total_counts = 0; 489108122e43SStefano Zampini n_vertices = 0; 4892d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 4893d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 489408122e43SStefano Zampini } 489508122e43SStefano Zampini max_constraints = 0; 48969162d606SStefano Zampini total_counts_cc = 0; 489708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 489808122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 48999162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 490008122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 490108122e43SStefano Zampini } 49029162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 49039162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 49049162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 49059162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 490674d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 49079162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 49089162d606SStefano Zampini total_counts_cc = 0; 49099162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 49109162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 49119162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 491208122e43SStefano Zampini } 491308122e43SStefano Zampini } 49149162d606SStefano Zampini #if 0 49159162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 49169162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 49179162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 49189162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 49199162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 49209162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 49219162d606SStefano Zampini } 49229162d606SStefano Zampini printf("\n"); 49239162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 49249162d606SStefano Zampini } 49251b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 49268bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 49271b968477SStefano Zampini } 49281b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 49298bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] sub %d, edge %d, n %d\n",PetscGlobalRank,i,(PetscBool)PetscBTLookup(sub_schurs->is_edge,i),pcbddc->adaptive_constraints_n[i+n_vertices]); 49301b968477SStefano Zampini } 493108122e43SStefano Zampini #endif 493208122e43SStefano Zampini 49338bec7fa6SStefano Zampini max_size_of_constraint = 0; 49349162d606SStefano 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]); 49359162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 493608122e43SStefano Zampini /* Change of basis */ 4937b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 493808122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 493908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 494008122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 4941b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 494208122e43SStefano Zampini } 494308122e43SStefano Zampini } 494408122e43SStefano Zampini } 494508122e43SStefano Zampini } 4946984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 49474f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 494808122e43SStefano Zampini 49499162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 49509162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 49516c4ed002SBarry Smith if (i != constraints_idxs_ptr[total_counts_cc]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %D != %D\n",constraints_idxs_ptr[total_counts_cc],i); 4952674ae819SStefano Zampini 4953674ae819SStefano Zampini /* Create constraint matrix */ 4954674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 495516f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 4956984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 4957984c4197SStefano Zampini 4958984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 4959a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 4960a717540cSStefano Zampini qr_needed = PETSC_FALSE; 496174d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 4962984c4197SStefano Zampini total_primal_vertices=0; 4963b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 49649162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 49659162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 496672b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 49679162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 4968b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 496964efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 49709162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 49719162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 4972a717540cSStefano Zampini } 4973b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 497491af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 4975a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 4976a717540cSStefano Zampini qr_needed = PETSC_TRUE; 4977a717540cSStefano Zampini } 4978fa434743SStefano Zampini } else { 4979b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 4980fa434743SStefano Zampini } 4981a717540cSStefano Zampini } 4982b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 4983b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 4984674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 498570022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 4986b3d85658SStefano Zampini 49874f1b2e48SStefano 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); 49880e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 49890e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 4990984c4197SStefano Zampini 4991984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 499274d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 4993785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 4994984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 499574d5cdf7SStefano Zampini 4996984c4197SStefano Zampini j = total_primal_vertices; 499774d5cdf7SStefano Zampini total_counts = total_primal_vertices; 4998b3d85658SStefano Zampini cum = total_primal_vertices; 49999162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 50004641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 5001b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 5002b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 5003b3d85658SStefano Zampini cum++; 50049162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 500574d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 500674d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 500774d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 500874d5cdf7SStefano Zampini } 50099162d606SStefano Zampini j += constraints_n[i]; 5010674ae819SStefano Zampini } 5011674ae819SStefano Zampini } 5012674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 5013674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 5014088faed8SStefano Zampini 5015674ae819SStefano Zampini /* set values in constraint matrix */ 5016984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 50170e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5018674ae819SStefano Zampini } 5019984c4197SStefano Zampini total_counts = total_primal_vertices; 50209162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 50214641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 50229162d606SStefano Zampini PetscInt *cols; 50239162d606SStefano Zampini 50249162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 50259162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 50269162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 50279162d606SStefano Zampini PetscInt row = total_counts+k; 50289162d606SStefano Zampini PetscScalar *vals; 50299162d606SStefano Zampini 50309162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 50319162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 50329162d606SStefano Zampini } 50339162d606SStefano Zampini total_counts += constraints_n[i]; 5034674ae819SStefano Zampini } 5035674ae819SStefano Zampini } 5036674ae819SStefano Zampini /* assembling */ 5037674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5038674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5039088faed8SStefano Zampini 5040984c4197SStefano Zampini /* 50416a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5042984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 5043f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 5044984c4197SStefano Zampini */ 5045674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 5046674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 5047026de310SStefano Zampini /* dual and primal dofs on a single cc */ 5048984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 5049984c4197SStefano Zampini /* working stuff for GEQRF */ 505081d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 5051984c4197SStefano Zampini PetscBLASInt lqr_work; 5052984c4197SStefano Zampini /* working stuff for UNGQR */ 5053984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 5054984c4197SStefano Zampini PetscBLASInt lgqr_work; 5055984c4197SStefano Zampini /* working stuff for TRTRS */ 5056984c4197SStefano Zampini PetscScalar *trs_rhs; 50573f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 5058984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 5059984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 5060984c4197SStefano Zampini PetscScalar *start_vals; 5061984c4197SStefano Zampini /* working stuff for values insertion */ 50624641a718SStefano Zampini PetscBT is_primal; 506364efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 5064906d46d4SStefano Zampini /* matrix sizes */ 5065906d46d4SStefano Zampini PetscInt global_size,local_size; 5066906d46d4SStefano Zampini /* temporary change of basis */ 5067906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 5068cf5a6209SStefano Zampini /* extra space for debugging */ 5069cf5a6209SStefano Zampini PetscScalar *dbg_work; 5070984c4197SStefano Zampini 5071906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 5072906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 507316f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 5074bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 5075906d46d4SStefano Zampini /* nonzeros for local mat */ 5076bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 50771dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5078bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 50791dd7afcfSStefano Zampini } else { 50801dd7afcfSStefano Zampini const PetscInt *ii; 50811dd7afcfSStefano Zampini PetscInt n; 50821dd7afcfSStefano Zampini PetscBool flg_row; 50831dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 50841dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 50851dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 50861dd7afcfSStefano Zampini } 50879162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 5088a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 50899162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 5090a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 50919162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 5092a717540cSStefano Zampini } else { 50939162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 50949162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 5095a717540cSStefano Zampini } 5096a717540cSStefano Zampini } 5097a717540cSStefano Zampini } 5098906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 5099bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 51001dd7afcfSStefano Zampini /* Set interior change in the matrix */ 51011dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5102bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 5103906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 5104a717540cSStefano Zampini } 51051dd7afcfSStefano Zampini } else { 51061dd7afcfSStefano Zampini const PetscInt *ii,*jj; 51071dd7afcfSStefano Zampini PetscScalar *aa; 51081dd7afcfSStefano Zampini PetscInt n; 51091dd7afcfSStefano Zampini PetscBool flg_row; 51101dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 51111dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 51121dd7afcfSStefano Zampini for (i=0;i<n;i++) { 51131dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 51141dd7afcfSStefano Zampini } 51151dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 51161dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 51171dd7afcfSStefano Zampini } 5118a717540cSStefano Zampini 5119a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5120a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5121a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5122a717540cSStefano Zampini } 5123a717540cSStefano Zampini 5124a717540cSStefano Zampini 5125a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 5126a717540cSStefano Zampini /* 5127a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 5128a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 5129a717540cSStefano Zampini 5130a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 5131a717540cSStefano Zampini 5132a6b551f4SStefano 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) 5133a6b551f4SStefano Zampini 5134a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 5135a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 5136a717540cSStefano Zampini | ... | 5137a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 5138a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 5139a717540cSStefano Zampini 5140a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 5141a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 5142a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 5143a6b551f4SStefano Zampini 5144a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 5145a717540cSStefano Zampini */ 5146a717540cSStefano Zampini if (qr_needed) { 5147984c4197SStefano Zampini /* space to store Q */ 5148854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 5149984c4197SStefano Zampini /* first we issue queries for optimal work */ 51503f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 51513f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 51523f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5153984c4197SStefano Zampini lqr_work = -1; 51543f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 5155984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 5156984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 5157785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 5158984c4197SStefano Zampini lgqr_work = -1; 51593f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 51603f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 51613f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 51623f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 51633f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 51643f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 5165984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 5166984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 5167785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 5168984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 5169785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 5170984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 5171785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 5172a717540cSStefano Zampini /* allocating workspace for check */ 5173a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5174cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 5175a717540cSStefano Zampini } 5176a717540cSStefano Zampini } 5177984c4197SStefano Zampini /* array to store whether a node is primal or not */ 51784641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 5179473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 51800e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 51816c4ed002SBarry Smith if (i != total_primal_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %D != %D\n",total_primal_vertices,i); 518239e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 518339e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 518439e2fb2aSStefano Zampini } 518539e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 5186984c4197SStefano Zampini 5187a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 51889162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 51899162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 51904641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 5191984c4197SStefano Zampini /* get constraint info */ 51929162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 5193984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 5194984c4197SStefano Zampini 5195984c4197SStefano Zampini if (pcbddc->dbg_flag) { 51969162d606SStefano 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); 5197674ae819SStefano Zampini } 5198984c4197SStefano Zampini 5199fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 5200a717540cSStefano Zampini 5201a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 5202a717540cSStefano Zampini if (pcbddc->dbg_flag) { 52039162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5204a717540cSStefano Zampini } 5205984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 52069162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5207984c4197SStefano Zampini 5208984c4197SStefano Zampini /* compute QR decomposition of constraints */ 52093f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 52103f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 52113f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5212674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 52133f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 5214984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 5215674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5216984c4197SStefano Zampini 5217984c4197SStefano Zampini /* explictly compute R^-T */ 5218984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 5219984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 52203f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 52213f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 52223f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 52233f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 5224984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 52253f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 5226984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 5227984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5228984c4197SStefano Zampini 5229a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 52303f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 52313f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 52323f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 52333f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5234984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 52353f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 5236984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 5237984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5238984c4197SStefano Zampini 5239984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 5240984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 5241984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 52423f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 52433f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 52443f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 52453f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 52463f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 52473f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5248984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 52499162d606SStefano 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)); 5250984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 52519162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5252984c4197SStefano Zampini 5253984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 52549162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 5255984c4197SStefano Zampini /* insert cols for primal dofs */ 5256984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 5257984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 52589162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5259906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5260984c4197SStefano Zampini } 5261984c4197SStefano Zampini /* insert cols for dual dofs */ 5262984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 52639162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 5264984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 52659162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5266906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5267984c4197SStefano Zampini j++; 5268674ae819SStefano Zampini } 5269674ae819SStefano Zampini } 5270984c4197SStefano Zampini 5271984c4197SStefano Zampini /* check change of basis */ 5272984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5273984c4197SStefano Zampini PetscInt ii,jj; 5274984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 5275c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 5276c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5277c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 5278c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5279c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 5280c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 5281984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5282cf5a6209SStefano 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)); 5283984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5284984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5285984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5286cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 5287cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) valid_qr = PETSC_FALSE; 5288674ae819SStefano Zampini } 5289674ae819SStefano Zampini } 5290984c4197SStefano Zampini if (!valid_qr) { 529122d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 5292984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5293984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5294cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 5295cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not orthogonal to constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 5296674ae819SStefano Zampini } 5297cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 5298cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not unitary w.r.t constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 5299984c4197SStefano Zampini } 5300984c4197SStefano Zampini } 5301984c4197SStefano Zampini } 5302674ae819SStefano Zampini } else { 530322d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 5304674ae819SStefano Zampini } 5305674ae819SStefano Zampini } 5306a717540cSStefano Zampini } else { /* simple transformation block */ 5307a717540cSStefano Zampini PetscInt row,col; 5308a6b551f4SStefano Zampini PetscScalar val,norm; 5309a6b551f4SStefano Zampini 5310a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 53119162d606SStefano 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)); 5312a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 53139162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 53149162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5315bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 53169162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 5317906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 53189162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 5319a717540cSStefano Zampini } else { 5320a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 53219162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5322a717540cSStefano Zampini if (row != col) { 53239162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 5324a717540cSStefano Zampini } else { 53259162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 5326a717540cSStefano Zampini } 5327906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 5328a717540cSStefano Zampini } 5329a717540cSStefano Zampini } 5330a717540cSStefano Zampini } 533198a51de6SStefano Zampini if (pcbddc->dbg_flag) { 533222d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 5333a717540cSStefano Zampini } 5334674ae819SStefano Zampini } 5335984c4197SStefano Zampini } else { 5336984c4197SStefano Zampini if (pcbddc->dbg_flag) { 53379162d606SStefano 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); 5338674ae819SStefano Zampini } 5339674ae819SStefano Zampini } 5340674ae819SStefano Zampini } 5341a717540cSStefano Zampini 5342a717540cSStefano Zampini /* free workspace */ 5343a717540cSStefano Zampini if (qr_needed) { 5344984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5345cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 5346984c4197SStefano Zampini } 5347984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 5348984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 5349984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 5350984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 5351984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 5352674ae819SStefano Zampini } 5353a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 5354906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5355906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5356906d46d4SStefano Zampini 5357906d46d4SStefano Zampini /* assembling of global change of variable */ 535888c03ad3SStefano Zampini if (!pcbddc->fake_change) { 5359bbb9e6c6SStefano Zampini Mat tmat; 536016f15bc4SStefano Zampini PetscInt bs; 536116f15bc4SStefano Zampini 5362906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 5363906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 5364bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 5365bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 5366bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5367bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 536816f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 536916f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 5370906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 5371bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 5372bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5373bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 5374bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5375bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5376e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5377e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5378bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 5379bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 538088c03ad3SStefano Zampini 5381906d46d4SStefano Zampini /* check */ 5382906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 5383906d46d4SStefano Zampini PetscReal error; 5384906d46d4SStefano Zampini Vec x,x_change; 5385906d46d4SStefano Zampini 5386906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 5387906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 5388906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 5389906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 5390e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5391e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5392bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 5393e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5394e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5395906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 5396906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 5397906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 5398906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5399bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 5400906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 5401906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 5402906d46d4SStefano Zampini } 5403b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 5404b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 5405b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5406bf3a8328SStefano Zampini 54079a962809SStefano Zampini if (pcbddc->use_change_of_basis && pcbddc->adaptive_userdefined) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot mix automatic change of basis, adaptive selection and user-defined constraints");CHKERRQ(ierr); 5408b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 5409ac632422SStefano Zampini Mat S_new,tmat; 5410bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 5411bbb9e6c6SStefano Zampini 5412bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 54136816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 5414bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5415bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 5416bf3a8328SStefano Zampini IS is_V; 5417b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 5418b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 5419b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 5420b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 5421b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 5422bf3a8328SStefano Zampini } 5423bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 5424ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 5425b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 5426ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 5427bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5428bf3a8328SStefano Zampini const PetscScalar *array; 5429bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 5430bf3a8328SStefano Zampini PetscInt i,n_V; 5431bf3a8328SStefano Zampini 5432b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 5433b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 5434b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 5435b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 5436b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 5437b087196eSStefano Zampini for (i=0;i<n_V;i++) { 5438b087196eSStefano Zampini PetscScalar val; 5439b087196eSStefano Zampini PetscInt idx; 5440b087196eSStefano Zampini 5441b087196eSStefano Zampini idx = idxs_V[i]; 5442b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 5443b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 5444b087196eSStefano Zampini } 5445b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5446b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5447bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 5448bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 5449bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 5450bf3a8328SStefano Zampini } 5451ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 5452ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 5453ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 5454ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 5455b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 5456ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 5457bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5458b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 5459bf3a8328SStefano Zampini } 5460ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 5461ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 5462ac632422SStefano Zampini } 5463b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 546488c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 5465b96c3477SStefano Zampini } 5466c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 5467b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 5468c9db6a07SStefano Zampini PetscInt i; 5469c9db6a07SStefano Zampini 5470c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5471c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 5472c9db6a07SStefano Zampini } 5473c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 5474c9db6a07SStefano Zampini } 5475b96c3477SStefano Zampini } 547616909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 547716909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 547816909a7fSStefano Zampini } else { 5479906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 548016909a7fSStefano Zampini } 54811dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 548227b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 548372b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 548472b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 548572b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 548672b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 548772b8c272SStefano Zampini } 54881dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 548927b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 5490b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 5491b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 5492906d46d4SStefano Zampini } else { 54931dd7afcfSStefano Zampini Mat benign_global = NULL; 549427b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 54951dd7afcfSStefano Zampini Mat tmat; 54961dd7afcfSStefano Zampini 54971dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 54981dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 54991dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 55001dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 55011dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 55021dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 55031dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 55041dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 55051dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 55061dd7afcfSStefano Zampini if (pcbddc->benign_change) { 55071dd7afcfSStefano Zampini Mat M; 55081dd7afcfSStefano Zampini 55091dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 55101dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 55111dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 55121dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 5513906d46d4SStefano Zampini } else { 55141dd7afcfSStefano Zampini Mat eye; 55151dd7afcfSStefano Zampini PetscScalar *array; 55161dd7afcfSStefano Zampini 55171dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 55181dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 55191dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 55201dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 5521906d46d4SStefano Zampini } 55221dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 55231dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55241dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55251dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 55261dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 55271dd7afcfSStefano Zampini } 55281dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 55291dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 55301dd7afcfSStefano Zampini } 55311dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 55321dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 55331dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 553427b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 55351dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 55361dd7afcfSStefano Zampini } 55371dd7afcfSStefano Zampini } 553816909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 553916909a7fSStefano Zampini IS is_global; 554016909a7fSStefano Zampini const PetscInt *gidxs; 554116909a7fSStefano Zampini 554216909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 554316909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 554416909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 554516909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 554616909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 554716909a7fSStefano Zampini } 55481dd7afcfSStefano Zampini } 55491dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 55501dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 5551b9b85e73SStefano Zampini } 5552a717540cSStefano Zampini 555372b8c272SStefano Zampini if (!pcbddc->fake_change) { 55544f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 55554f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 55564f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 55574f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 5558019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 5559019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 5560019a44ceSStefano Zampini pcbddc->local_primal_size++; 5561019a44ceSStefano Zampini } 5562019a44ceSStefano Zampini 5563019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 5564727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 5565727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 55669f47a83aSStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_node,olocal_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 5567c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 55680e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 55699f47a83aSStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_mult,olocal_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 5570727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 5571727cdba6SStefano Zampini } 55720e6343abSStefano Zampini } 5573727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 5574b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 557572b8c272SStefano Zampini } 557672b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 5577727cdba6SStefano Zampini 5578a717540cSStefano Zampini /* flush dbg viewer */ 5579b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 5580b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5581b8ffe317SStefano Zampini } 5582a717540cSStefano Zampini 5583e310c8b4SStefano Zampini /* free workspace */ 5584a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 55854641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 558608122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 55879162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 55889162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 558908122e43SStefano Zampini } else { 55909162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 55919162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 55929162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 559308122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 559408122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 55959162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 55969162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 559708122e43SStefano Zampini } 5598674ae819SStefano Zampini PetscFunctionReturn(0); 5599674ae819SStefano Zampini } 5600674ae819SStefano Zampini 5601674ae819SStefano Zampini #undef __FUNCT__ 5602674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 5603674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 5604674ae819SStefano Zampini { 560571582508SStefano Zampini ISLocalToGlobalMapping map; 5606674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5607674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 560814f95afaSStefano Zampini PetscInt ierr,i,N; 5609674ae819SStefano Zampini 5610674ae819SStefano Zampini PetscFunctionBegin; 5611c8272957SStefano Zampini if (pcbddc->graphanalyzed && !pcbddc->recompute_topography) PetscFunctionReturn(0); 56128e61c736SStefano Zampini /* Reset previously computed graph */ 56138e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 5614674ae819SStefano Zampini /* Init local Graph struct */ 56157fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 561671582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 5617*be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 5618674ae819SStefano Zampini 5619575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 56209a962809SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid size of local CSR graph! Found %d, expected %d\n",pcbddc->mat_graph->nvtxs_csr,pcbddc->mat_graph->nvtxs); 56219577ea80SStefano Zampini 5622674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 5623d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 56244d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 56254d379d7bSStefano Zampini PetscInt nvtxs; 5626e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 5627674ae819SStefano Zampini 56282fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 56292fffb893SStefano Zampini if (flg_row) { 56304d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 5631b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 56322fffb893SStefano Zampini } 56332fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 5634674ae819SStefano Zampini } 56359b28b941SStefano Zampini if (pcbddc->dbg_flag) { 56369b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5637674ae819SStefano Zampini } 5638674ae819SStefano Zampini 5639674ae819SStefano Zampini /* Setup of Graph */ 56404b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 564114f95afaSStefano 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); 5642674ae819SStefano Zampini 56434f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 56444f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 56454f1b2e48SStefano Zampini PetscInt *local_subs; 56464f1b2e48SStefano Zampini 56474f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 56484f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 56494f1b2e48SStefano Zampini const PetscInt *idxs; 56504f1b2e48SStefano Zampini PetscInt nl,j; 56514f1b2e48SStefano Zampini 56524f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 56534f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 565471582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 56554f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 56564f1b2e48SStefano Zampini } 56574f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 56584f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 56594f1b2e48SStefano Zampini } 56604f1b2e48SStefano Zampini 5661674ae819SStefano Zampini /* Graph's connected components analysis */ 5662674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 566371582508SStefano Zampini 566471582508SStefano Zampini /* set flag indicating analysis has been done */ 566571582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 5666674ae819SStefano Zampini PetscFunctionReturn(0); 5667674ae819SStefano Zampini } 5668674ae819SStefano Zampini 56699a7d3425SStefano Zampini #undef __FUNCT__ 56709a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 56719a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 56729a7d3425SStefano Zampini { 56739a7d3425SStefano Zampini PetscInt i,j; 56749a7d3425SStefano Zampini PetscScalar *alphas; 56759a7d3425SStefano Zampini PetscErrorCode ierr; 56769a7d3425SStefano Zampini 56779a7d3425SStefano Zampini PetscFunctionBegin; 5678785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 56799a7d3425SStefano Zampini for (i=0;i<n;i++) { 56809a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 5681669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 5682669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 5683669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 56849a7d3425SStefano Zampini } 56859a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 56869a7d3425SStefano Zampini PetscFunctionReturn(0); 56879a7d3425SStefano Zampini } 56889a7d3425SStefano Zampini 5689e7931f94SStefano Zampini #undef __FUNCT__ 569070cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 569157de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 5692e7931f94SStefano Zampini { 569357de7509SStefano Zampini Mat A; 5694e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 5695e7931f94SStefano Zampini PetscMPIInt size,rank,color; 569652e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 569752e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 569827b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 569957de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 570027b6a85dSStefano Zampini PetscInt xadj_count, *count; 570127b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 570227b6a85dSStefano Zampini PetscSubcomm psubcomm; 570327b6a85dSStefano Zampini MPI_Comm subcomm; 570452e5ac9dSStefano Zampini PetscErrorCode ierr; 5705a57a6d2fSStefano Zampini 5706e7931f94SStefano Zampini PetscFunctionBegin; 570757de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 570857de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 570957de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 571057de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 571157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 571257de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 571357de7509SStefano Zampini 571457de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 571557de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 571657de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 571757de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 571857de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 571957de7509SStefano Zampini im_active = !!(n); 572057de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 572157de7509SStefano Zampini void_procs = size - active_procs; 572257de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 572357de7509SStefano Zampini if (void_procs) { 572457de7509SStefano Zampini PetscInt ncand; 572557de7509SStefano Zampini 572657de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 572757de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 572857de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 572957de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 573057de7509SStefano Zampini if (!procs_candidates[i]) { 573157de7509SStefano Zampini procs_candidates[ncand++] = i; 573257de7509SStefano Zampini } 573357de7509SStefano Zampini } 573457de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 573557de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 573657de7509SStefano Zampini } 573757de7509SStefano Zampini 573814f0bfb9SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix 573914f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 574014f0bfb9SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1) { 574114f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 574214f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 574314f0bfb9SStefano Zampini else dest = rank; 574457de7509SStefano Zampini if (im_active) { 574557de7509SStefano Zampini issize = 1; 574657de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 574714f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 574857de7509SStefano Zampini } else { 574914f0bfb9SStefano Zampini isidx = dest; 575057de7509SStefano Zampini } 575157de7509SStefano Zampini } else { 575257de7509SStefano Zampini issize = 0; 575357de7509SStefano Zampini isidx = -1; 575457de7509SStefano Zampini } 575557de7509SStefano Zampini *n_subdomains = active_procs; 575657de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 5757daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 575857de7509SStefano Zampini PetscFunctionReturn(0); 575957de7509SStefano Zampini } 5760c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 5761c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 576227b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 5763e7931f94SStefano Zampini 5764e7931f94SStefano Zampini /* Get info on mapping */ 57653bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 57663bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 5767e7931f94SStefano Zampini 5768e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 5769785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 5770e7931f94SStefano Zampini xadj[0] = 0; 5771e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 5772785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 5773785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 577427b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 577527b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 577627b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 577727b6a85dSStefano Zampini count[shared[i][j]] += 1; 5778e7931f94SStefano Zampini 577927b6a85dSStefano Zampini xadj_count = 0; 57802b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 578127b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 578227b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 5783d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 5784d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 5785d023bfaeSStefano Zampini xadj_count++; 578627b6a85dSStefano Zampini break; 578727b6a85dSStefano Zampini } 5788e7931f94SStefano Zampini } 5789e7931f94SStefano Zampini } 5790d023bfaeSStefano Zampini xadj[1] = xadj_count; 579127b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 57923bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 5793e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 5794e7931f94SStefano Zampini 57953837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 5796e7931f94SStefano Zampini 579727b6a85dSStefano Zampini /* Restrict work on active processes only */ 579827b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 579927b6a85dSStefano Zampini if (void_procs) { 580027b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 580127b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 580227b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 580327b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 580427b6a85dSStefano Zampini } else { 580527b6a85dSStefano Zampini psubcomm = NULL; 580627b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 580727b6a85dSStefano Zampini } 580827b6a85dSStefano Zampini 580927b6a85dSStefano Zampini v_wgt = NULL; 581027b6a85dSStefano Zampini if (!color) { 5811e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 5812e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 5813e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5814c8587f34SStefano Zampini } else { 581552e5ac9dSStefano Zampini Mat subdomain_adj; 581652e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 581752e5ac9dSStefano Zampini MatPartitioning partitioner; 581827b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 581952e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 582057de7509SStefano Zampini PetscMPIInt size; 5821b0c7d250SStefano Zampini PetscBool aggregate; 5822b0c7d250SStefano Zampini 582327b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 582427b6a85dSStefano Zampini if (void_procs) { 582527b6a85dSStefano Zampini PetscInt prank = rank; 5826785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 582727b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 5828e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 5829e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 5830c8587f34SStefano Zampini } 5831e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 583227b6a85dSStefano Zampini } else { 583327b6a85dSStefano Zampini oldranks = NULL; 583427b6a85dSStefano Zampini } 5835b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 583627b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 5837b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 5838b0c7d250SStefano Zampini PetscMPIInt nrank; 5839b0c7d250SStefano Zampini PetscScalar *vals; 5840b0c7d250SStefano Zampini 584127b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 5842b0c7d250SStefano Zampini lrows = 0; 5843b0c7d250SStefano Zampini if (nrank<redprocs) { 5844b0c7d250SStefano Zampini lrows = size/redprocs; 5845b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 5846b0c7d250SStefano Zampini } 584727b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 5848b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 5849b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5850b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5851b0c7d250SStefano Zampini row = nrank; 5852b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 5853b0c7d250SStefano Zampini cols = adjncy; 5854b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 5855b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 5856b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 5857b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5858b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 585952e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 586052e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 586152e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5862b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 586327b6a85dSStefano Zampini if (use_vwgt) { 586427b6a85dSStefano Zampini Vec v; 586527b6a85dSStefano Zampini const PetscScalar *array; 586627b6a85dSStefano Zampini PetscInt nl; 586727b6a85dSStefano Zampini 586827b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 586927b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 587027b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 587127b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 587227b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 587327b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 587427b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 587522db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 587627b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 587727b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 587827b6a85dSStefano Zampini } 5879b0c7d250SStefano Zampini } else { 588027b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 588127b6a85dSStefano Zampini if (use_vwgt) { 588227b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 588327b6a85dSStefano Zampini v_wgt[0] = local_size; 588427b6a85dSStefano Zampini } 5885b0c7d250SStefano Zampini } 588622b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 5887e7931f94SStefano Zampini 5888e7931f94SStefano Zampini /* Partition */ 588927b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 5890e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 589127b6a85dSStefano Zampini if (v_wgt) { 5892e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 5893c8587f34SStefano Zampini } 589457de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 589557de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 5896e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 5897e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 589822b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 5899e7931f94SStefano Zampini 590052e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 59016583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 590252e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 590352e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 590457de7509SStefano Zampini if (!aggregate) { 590557de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 590627b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 590727b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 590827b6a85dSStefano Zampini #endif 590957de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 591027b6a85dSStefano Zampini } else if (oldranks) { 5911b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 591227b6a85dSStefano Zampini } else { 591327b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 591457de7509SStefano Zampini } 591528143c3dSStefano Zampini } else { 5916b0c7d250SStefano Zampini PetscInt idxs[1]; 5917b0c7d250SStefano Zampini PetscMPIInt tag; 5918b0c7d250SStefano Zampini MPI_Request *reqs; 5919b0c7d250SStefano Zampini 5920b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 5921b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 5922b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 592327b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 592428143c3dSStefano Zampini } 592527b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 5926b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5927b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 592857de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 592927b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 593027b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 593127b6a85dSStefano Zampini #endif 593257de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 593327b6a85dSStefano Zampini } else if (oldranks) { 5934b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 593527b6a85dSStefano Zampini } else { 593627b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 5937e7931f94SStefano Zampini } 593857de7509SStefano Zampini } 593952e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5940e7931f94SStefano Zampini /* clean up */ 5941e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 594252e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 5943e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 5944e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 5945e7931f94SStefano Zampini } 594627b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 594757de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 5948e7931f94SStefano Zampini 5949e7931f94SStefano Zampini /* assemble parallel IS for sends */ 5950e7931f94SStefano Zampini i = 1; 595127b6a85dSStefano Zampini if (!color) i=0; 595257de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 5953e7931f94SStefano Zampini PetscFunctionReturn(0); 5954e7931f94SStefano Zampini } 5955e7931f94SStefano Zampini 5956e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 5957e7931f94SStefano Zampini 5958e7931f94SStefano Zampini #undef __FUNCT__ 5959e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 59601ae86dd6SStefano Zampini PetscErrorCode MatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, PetscBool restrict_full, PetscBool reuse, Mat *mat_n, PetscInt nis, IS isarray[], PetscInt nvecs, Vec nnsp_vec[]) 5961e7931f94SStefano Zampini { 596270cf5478SStefano Zampini Mat local_mat; 5963e7931f94SStefano Zampini IS is_sends_internal; 59649d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 59651ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 59669d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 5967e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 5968e7931f94SStefano Zampini PetscInt* l2gmap_indices; 5969e7931f94SStefano Zampini const PetscInt* is_indices; 5970e7931f94SStefano Zampini MatType new_local_type; 5971e7931f94SStefano Zampini /* buffers */ 5972e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 597328143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 59749d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 5975e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 59761ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 5977e7931f94SStefano Zampini /* MPI */ 597828143c3dSStefano Zampini MPI_Comm comm,comm_n; 597928143c3dSStefano Zampini PetscSubcomm subcomm; 5980e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 598128143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 598228143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 59831ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 59841ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 59851ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 5986e7931f94SStefano Zampini PetscErrorCode ierr; 5987e7931f94SStefano Zampini 5988e7931f94SStefano Zampini PetscFunctionBegin; 598957de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5990e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 599128143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 599257de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 599357de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 599457de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 599557de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 599657de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 59971ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 59981ae86dd6SStefano Zampini if (nvecs) { 59991ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 60001ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 60011ae86dd6SStefano Zampini } 600257de7509SStefano Zampini /* further checks */ 6003e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6004e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 6005e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 6006e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 6007e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 600857de7509SStefano Zampini if (reuse && *mat_n) { 600970cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 601057de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 601170cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 601228143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 601370cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 601470cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 601570cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 601670cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 601770cf5478SStefano Zampini } 6018e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 6019e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 602057de7509SStefano Zampini 6021e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 6022e7931f94SStefano Zampini if (!is_sends) { 602328143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 602457de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 6025c8587f34SStefano Zampini } else { 6026e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 6027e7931f94SStefano Zampini is_sends_internal = is_sends; 6028c8587f34SStefano Zampini } 6029e7931f94SStefano Zampini 6030e7931f94SStefano Zampini /* get comm */ 6031a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 6032e7931f94SStefano Zampini 6033e7931f94SStefano Zampini /* compute number of sends */ 6034e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 6035e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 6036e7931f94SStefano Zampini 6037e7931f94SStefano Zampini /* compute number of receives */ 6038e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 6039785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 6040e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 6041e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6042e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 6043e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 6044e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 6045e7931f94SStefano Zampini 604628143c3dSStefano Zampini /* restrict comm if requested */ 604728143c3dSStefano Zampini subcomm = 0; 604828143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 604928143c3dSStefano Zampini if (restrict_comm) { 6050779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 6051779c1cceSStefano Zampini 605228143c3dSStefano Zampini color = 0; 605353a05cb3SStefano Zampini if (restrict_full) { 605453a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 605553a05cb3SStefano Zampini } else { 605653a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 605753a05cb3SStefano Zampini } 6058b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 605928143c3dSStefano Zampini subcommsize = commsize - subcommsize; 606028143c3dSStefano Zampini /* check if reuse has been requested */ 606157de7509SStefano Zampini if (reuse) { 606228143c3dSStefano Zampini if (*mat_n) { 606328143c3dSStefano Zampini PetscMPIInt subcommsize2; 606428143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 606528143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 606628143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 606728143c3dSStefano Zampini } else { 606828143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 606928143c3dSStefano Zampini } 607028143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 6071779c1cceSStefano Zampini PetscMPIInt rank; 6072779c1cceSStefano Zampini 6073779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 607428143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 607528143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 607628143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 6077306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 607828143c3dSStefano Zampini } 607928143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 608028143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 608128143c3dSStefano Zampini } else { 608228143c3dSStefano Zampini comm_n = comm; 608328143c3dSStefano Zampini } 608428143c3dSStefano Zampini 6085e7931f94SStefano Zampini /* prepare send/receive buffers */ 6086785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 6087e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 6088785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 6089e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 609028143c3dSStefano Zampini if (nis) { 6091854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 609228143c3dSStefano Zampini } 6093e7931f94SStefano Zampini 609428143c3dSStefano Zampini /* Get data from local matrices */ 60956c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 6096e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 6097e7931f94SStefano Zampini /* 6098e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 6099e7931f94SStefano Zampini send_buffer_idxs should contain: 6100e7931f94SStefano Zampini - MatType_PRIVATE type 6101e7931f94SStefano Zampini - PetscInt size_of_l2gmap 6102e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 6103e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 6104e7931f94SStefano Zampini */ 61056c4ed002SBarry Smith else { 6106e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 61073bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 6108854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 6109e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 6110e7931f94SStefano Zampini send_buffer_idxs[1] = i; 61113bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6112e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 61133bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6114e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 6115e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6116e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 6117e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 6118c8587f34SStefano Zampini } 6119c8587f34SStefano Zampini } 6120e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 612128143c3dSStefano Zampini /* additional is (if any) */ 612228143c3dSStefano Zampini if (nis) { 612328143c3dSStefano Zampini PetscMPIInt psum; 612428143c3dSStefano Zampini PetscInt j; 612528143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 612628143c3dSStefano Zampini PetscInt plen; 612728143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 612828143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 612928143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 613028143c3dSStefano Zampini } 6131854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 613228143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 613328143c3dSStefano Zampini PetscInt plen; 613428143c3dSStefano Zampini const PetscInt *is_array_idxs; 613528143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 613628143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 613728143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 613828143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 613928143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 614028143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 614128143c3dSStefano Zampini } 614228143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 614328143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 614428143c3dSStefano Zampini } 614528143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 614628143c3dSStefano Zampini } 614728143c3dSStefano Zampini 6148e7931f94SStefano Zampini buf_size_idxs = 0; 6149e7931f94SStefano Zampini buf_size_vals = 0; 615028143c3dSStefano Zampini buf_size_idxs_is = 0; 61511ae86dd6SStefano Zampini buf_size_vecs = 0; 6152e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6153e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 6154e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 615528143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 61561ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 6157e7931f94SStefano Zampini } 6158785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 6159785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 616095ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 61611ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 6162e7931f94SStefano Zampini 6163e7931f94SStefano Zampini /* get new tags for clean communications */ 6164e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 6165e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 616628143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 61671ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 6168e7931f94SStefano Zampini 6169e7931f94SStefano Zampini /* allocate for requests */ 6170785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 6171785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 617295ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 61731ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 6174785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 6175785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 617695ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 61771ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 6178e7931f94SStefano Zampini 6179e7931f94SStefano Zampini /* communications */ 6180e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6181e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 618228143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 61831ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 6184e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6185e7931f94SStefano Zampini source_dest = onodes[i]; 6186e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 6187e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 6188e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6189e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 619028143c3dSStefano Zampini if (nis) { 619157de7509SStefano Zampini source_dest = onodes_is[i]; 619228143c3dSStefano Zampini ierr = MPI_Irecv(ptr_idxs_is,olengths_idxs_is[i],MPIU_INT,source_dest,tag_idxs_is,comm,&recv_req_idxs_is[i]);CHKERRQ(ierr); 619328143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 619428143c3dSStefano Zampini } 61951ae86dd6SStefano Zampini if (nvecs) { 61961ae86dd6SStefano Zampini source_dest = onodes[i]; 61971ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 61981ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 61991ae86dd6SStefano Zampini } 6200e7931f94SStefano Zampini } 6201e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6202e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 6203e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 6204e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 620528143c3dSStefano Zampini if (nis) { 620628143c3dSStefano Zampini ierr = MPI_Isend(send_buffer_idxs_is,ilengths_idxs_is[source_dest],MPIU_INT,source_dest,tag_idxs_is,comm,&send_req_idxs_is[i]);CHKERRQ(ierr); 620728143c3dSStefano Zampini } 62081ae86dd6SStefano Zampini if (nvecs) { 62091ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 62101ae86dd6SStefano Zampini ierr = MPI_Isend(send_buffer_vecs,ilengths_idxs[source_dest]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&send_req_vecs[i]);CHKERRQ(ierr); 62111ae86dd6SStefano Zampini } 6212e7931f94SStefano Zampini } 6213e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6214e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 6215e7931f94SStefano Zampini 6216e7931f94SStefano Zampini /* assemble new l2g map */ 6217e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6218e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 62199d30be91SStefano Zampini new_local_rows = 0; 6220e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 62219d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6222e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6223e7931f94SStefano Zampini } 62249d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 6225e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 62269d30be91SStefano Zampini new_local_rows = 0; 6227e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 62289d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 62299d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6230e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6231e7931f94SStefano Zampini } 62329d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 62339d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 6234e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 6235e7931f94SStefano Zampini 6236e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 6237e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 6238e7931f94SStefano 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) */ 6239e7931f94SStefano Zampini if (n_recvs) { 624028143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 6241e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6242e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6243e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 6244e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 6245e7931f94SStefano Zampini break; 6246e7931f94SStefano Zampini } 6247e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6248e7931f94SStefano Zampini } 6249e7931f94SStefano Zampini switch (new_local_type_private) { 625028143c3dSStefano Zampini case MATDENSE_PRIVATE: 625128143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 6252e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6253e7931f94SStefano Zampini bs = 1; 625428143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 625528143c3dSStefano Zampini new_local_type = MATSEQDENSE; 625628143c3dSStefano Zampini bs = 1; 625728143c3dSStefano Zampini } 6258e7931f94SStefano Zampini break; 6259e7931f94SStefano Zampini case MATAIJ_PRIVATE: 6260e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6261e7931f94SStefano Zampini bs = 1; 6262e7931f94SStefano Zampini break; 6263e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 6264e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 6265e7931f94SStefano Zampini break; 6266e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 6267e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 6268e7931f94SStefano Zampini break; 6269e7931f94SStefano Zampini default: 62709d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 6271e7931f94SStefano Zampini break; 6272e7931f94SStefano Zampini } 627328143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 627428143c3dSStefano Zampini new_local_type = MATSEQDENSE; 627528143c3dSStefano Zampini bs = 1; 6276e7931f94SStefano Zampini } 6277e7931f94SStefano Zampini 627870cf5478SStefano Zampini /* create MATIS object if needed */ 627957de7509SStefano Zampini if (!reuse) { 6280e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 6281e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 628270cf5478SStefano Zampini } else { 628370cf5478SStefano Zampini /* it also destroys the local matrices */ 628457de7509SStefano Zampini if (*mat_n) { 628570cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 628657de7509SStefano Zampini } else { /* this is a fake object */ 628757de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 628857de7509SStefano Zampini } 628970cf5478SStefano Zampini } 629070cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 6291e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 62929d30be91SStefano Zampini 62939d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 62949d30be91SStefano Zampini 62959d30be91SStefano Zampini /* Global to local map of received indices */ 62969d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 62979d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 62989d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 62999d30be91SStefano Zampini 63009d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 63019d30be91SStefano Zampini buf_size_idxs = 0; 63029d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 63039d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 63049d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 63059d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 63069d30be91SStefano Zampini } 63079d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 63089d30be91SStefano Zampini 63099d30be91SStefano Zampini /* set preallocation */ 63109d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 63119d30be91SStefano Zampini if (!newisdense) { 63129d30be91SStefano Zampini PetscInt *new_local_nnz=0; 63139d30be91SStefano Zampini 63149d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 63159d30be91SStefano Zampini if (n_recvs) { 63169d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 63179d30be91SStefano Zampini } 63189d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 63199d30be91SStefano Zampini PetscInt j; 63209d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 63219d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 63229d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 63239d30be91SStefano Zampini } 63249d30be91SStefano Zampini } else { 63259d30be91SStefano Zampini /* TODO */ 63269d30be91SStefano Zampini } 63279d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 63289d30be91SStefano Zampini } 63299d30be91SStefano Zampini if (new_local_nnz) { 63309d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 63319d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 63329d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 63339d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 63349d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 63359d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 63369d30be91SStefano Zampini } else { 63379d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 63389d30be91SStefano Zampini } 63399d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 63409d30be91SStefano Zampini } else { 63419d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 63429d30be91SStefano Zampini } 6343e7931f94SStefano Zampini 6344e7931f94SStefano Zampini /* set values */ 6345e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 63469d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 6347e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6348e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 6349e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 63509d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 6351e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6352e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6353e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 635428143c3dSStefano Zampini } else { 635528143c3dSStefano Zampini /* TODO */ 6356e7931f94SStefano Zampini } 6357e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6358e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 6359e7931f94SStefano Zampini } 6360e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6361e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 636270cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 636370cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 63649d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 6365e7931f94SStefano Zampini 6366dfd14d43SStefano Zampini #if 0 636728143c3dSStefano Zampini if (!restrict_comm) { /* check */ 6368e7931f94SStefano Zampini Vec lvec,rvec; 6369e7931f94SStefano Zampini PetscReal infty_error; 6370e7931f94SStefano Zampini 63712a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 6372e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 6373e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 6374e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 637570cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 6376e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 6377e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 6378e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 6379e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 6380e7931f94SStefano Zampini } 638128143c3dSStefano Zampini #endif 6382e7931f94SStefano Zampini 638328143c3dSStefano Zampini /* assemble new additional is (if any) */ 638428143c3dSStefano Zampini if (nis) { 638528143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 638628143c3dSStefano Zampini 638728143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6388854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 638928143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 639028143c3dSStefano Zampini psum = 0; 639128143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 639228143c3dSStefano Zampini for (j=0;j<nis;j++) { 639328143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 639428143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 639528143c3dSStefano Zampini psum += plen; 639628143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 639728143c3dSStefano Zampini } 639828143c3dSStefano Zampini } 6399854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 6400854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 640128143c3dSStefano Zampini for (i=1;i<nis;i++) { 640228143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 640328143c3dSStefano Zampini } 640428143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 640528143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 640628143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 640728143c3dSStefano Zampini for (j=0;j<nis;j++) { 640828143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 640928143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 641028143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 641128143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 641228143c3dSStefano Zampini } 641328143c3dSStefano Zampini } 641428143c3dSStefano Zampini for (i=0;i<nis;i++) { 641528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 641628143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 641728143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 641828143c3dSStefano Zampini } 641928143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 642028143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 642128143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 642228143c3dSStefano Zampini } 6423e7931f94SStefano Zampini /* free workspace */ 642428143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 6425e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6426e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 6427e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6428e7931f94SStefano Zampini if (isdense) { 6429e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6430e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 6431e7931f94SStefano Zampini } else { 6432e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 6433e7931f94SStefano Zampini } 643428143c3dSStefano Zampini if (nis) { 643528143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 643628143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 643728143c3dSStefano Zampini } 64381ae86dd6SStefano Zampini 64391ae86dd6SStefano Zampini if (nvecs) { 64401ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 64411ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 64421ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 64431ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 64441ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 64451ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 64461ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 64471ae86dd6SStefano Zampini /* set values */ 64481ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 64491ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 64501ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 64511ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 64521ae86dd6SStefano Zampini PetscInt j; 64531ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 64541ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 64551ae86dd6SStefano Zampini } 64561ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 64571ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 64581ae86dd6SStefano Zampini } 64591ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 64601ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 64611ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 64621ae86dd6SStefano Zampini } 64631ae86dd6SStefano Zampini 64641ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 64651ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 6466e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 6467e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 64681ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 646928143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 6470e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 6471e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 64721ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 647328143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 6474e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 6475e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 6476e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 6477e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 6478e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 647928143c3dSStefano Zampini if (nis) { 648028143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 648128143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 648228143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 648328143c3dSStefano Zampini } 648428143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 648528143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 648628143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 648728143c3dSStefano Zampini for (i=0;i<nis;i++) { 648828143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 648928143c3dSStefano Zampini } 64901ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 64911ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 64921ae86dd6SStefano Zampini } 649353a05cb3SStefano Zampini *mat_n = NULL; 649428143c3dSStefano Zampini } 6495e7931f94SStefano Zampini PetscFunctionReturn(0); 6496e7931f94SStefano Zampini } 6497a57a6d2fSStefano Zampini 649812edc857SStefano Zampini /* temporary hack into ksp private data structure */ 6499af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 650012edc857SStefano Zampini 6501c8587f34SStefano Zampini #undef __FUNCT__ 6502c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 6503c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 6504c8587f34SStefano Zampini { 6505c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6506c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 650720a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 65081ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 65099881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 651020a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 65116e683305SStefano Zampini IS coarse_is,*isarray; 65126e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 651330368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 6514f9eb5b7dSStefano Zampini PC pc_temp; 6515c8587f34SStefano Zampini PCType coarse_pc_type; 6516c8587f34SStefano Zampini KSPType coarse_ksp_type; 6517f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 65184f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 65196e683305SStefano Zampini Mat t_coarse_mat_is; 652057de7509SStefano Zampini PetscInt ncoarse; 652168457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 652222bc73bbSStefano Zampini PetscScalar *array; 652357de7509SStefano Zampini MatReuse coarse_mat_reuse; 652457de7509SStefano Zampini PetscBool restr, full_restr, have_void; 65259881197aSStefano Zampini PetscErrorCode ierr; 6526fdc09c96SStefano Zampini 6527c8587f34SStefano Zampini PetscFunctionBegin; 6528c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 652968457ee5SStefano 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 */ 6530fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 65315a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 6532fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 6533f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 6534f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 6535f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 6536fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 653751bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 653851bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 6539dc4bcba2SStefano Zampini PC pc; 6540dc4bcba2SStefano Zampini PetscBool isbddc; 6541dc4bcba2SStefano Zampini 6542dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 6543dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 6544dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 6545dc4bcba2SStefano Zampini if (isbddc) { 654663c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 654763c961adSStefano Zampini } else { 6548727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 654963c961adSStefano Zampini } 6550fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 6551fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 6552fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 6553f4ddd8eeSStefano Zampini } 6554fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 6555fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 6556f4ddd8eeSStefano Zampini } 655770cf5478SStefano Zampini /* reset any subassembling information */ 655857de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 655970cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 656057de7509SStefano Zampini } 65616e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 6562fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 6563f4ddd8eeSStefano Zampini } 656457de7509SStefano Zampini /* assemble coarse matrix */ 656557de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 656657de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 656757de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 656857de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 656918a45a71SStefano Zampini } else { 657057de7509SStefano Zampini coarse_mat = NULL; 657157de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 65726e683305SStefano Zampini } 6573e7931f94SStefano Zampini 6574abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 6575abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 6576abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 6577abbbba34SStefano Zampini 6578abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 657922bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 658022bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 658122bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 658222bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 6583e176bc59SStefano 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); 65846e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 65856e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 65866e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6587abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 6588abbbba34SStefano Zampini 658957de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 659057de7509SStefano Zampini im_active = !!(pcis->n); 659157de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 659257de7509SStefano Zampini 659314f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 659457de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 659557de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 659657de7509SStefano Zampini coarse_mat_is = NULL; 659757de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 659857de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 659957de7509SStefano Zampini full_restr = PETSC_TRUE; 66001ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 660157de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 660257de7509SStefano Zampini if (multilevel_requested) { 660357de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 660457de7509SStefano Zampini restr = PETSC_FALSE; 660557de7509SStefano Zampini full_restr = PETSC_FALSE; 660657de7509SStefano Zampini } else { 660757de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 660857de7509SStefano Zampini restr = PETSC_TRUE; 660957de7509SStefano Zampini full_restr = PETSC_TRUE; 661057de7509SStefano Zampini } 66114b2aedd3SStefano Zampini if (!pcbddc->coarse_size) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 661257de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 661357de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 6614a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 661557de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 6616a198735bSStefano Zampini } else { 6617a198735bSStefano Zampini PetscMPIInt size,rank; 6618a198735bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 6619a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 6620a198735bSStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 6621a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 6622a198735bSStefano Zampini } 662357de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 662457de7509SStefano Zampini PetscInt psum; 662557de7509SStefano Zampini PetscMPIInt size; 662657de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 662757de7509SStefano Zampini else psum = 0; 662857de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 662957de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 663057de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 663157de7509SStefano Zampini } 663257de7509SStefano Zampini /* determine if we can go multilevel */ 663357de7509SStefano Zampini if (multilevel_requested) { 663457de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 663557de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 663657de7509SStefano Zampini } 663757de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 663857de7509SStefano Zampini 6639e4d548c7SStefano Zampini /* dump subassembling pattern */ 6640e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 6641e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 6642e4d548c7SStefano Zampini } 6643e4d548c7SStefano Zampini 66446e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 664527b6a85dSStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal)) { /* protects from unneded computations */ 66466e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 66476e683305SStefano Zampini const PetscInt *idxs; 66486e683305SStefano Zampini ISLocalToGlobalMapping tmap; 66496e683305SStefano Zampini 66506e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 66510be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 66526e683305SStefano Zampini /* allocate space for temporary storage */ 6653854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 6654854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 66556e683305SStefano Zampini /* allocate for IS array */ 66566e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 66576e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 665827b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 665930368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 6660854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 66616e683305SStefano Zampini /* dofs splitting */ 66626e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 66636e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 66646e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 66656e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 66666e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 66676e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 66686e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 666930368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 66706e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 66716e683305SStefano Zampini } 66726e683305SStefano Zampini /* neumann boundaries */ 66736e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 66746e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 66756e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 66766e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 66776e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 66786e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 66796e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 668030368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 66816e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 66826e683305SStefano Zampini } 66836e683305SStefano Zampini /* free memory */ 66846e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 66856e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 66866e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 66876e683305SStefano Zampini } else { 66886e683305SStefano Zampini nis = 0; 66896e683305SStefano Zampini nisdofs = 0; 66906e683305SStefano Zampini nisneu = 0; 669130368db7SStefano Zampini nisvert = 0; 66926e683305SStefano Zampini isarray = NULL; 66936e683305SStefano Zampini } 66946e683305SStefano Zampini /* destroy no longer needed map */ 66956e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 66966e683305SStefano Zampini 669757de7509SStefano Zampini /* subassemble */ 669857de7509SStefano Zampini if (multilevel_allowed) { 66991ae86dd6SStefano Zampini Vec vp[1]; 67001ae86dd6SStefano Zampini PetscInt nvecs = 0; 670157de7509SStefano Zampini PetscBool reuse,reuser; 67021ae86dd6SStefano Zampini 670357de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 670457de7509SStefano Zampini else reuse = PETSC_FALSE; 670557de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 67061ae86dd6SStefano Zampini vp[0] = NULL; 67071ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 67081ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 67091ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 67101ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 67111ae86dd6SStefano Zampini nvecs = 1; 67121ae86dd6SStefano Zampini 67131ae86dd6SStefano Zampini if (pcbddc->divudotp) { 6714a198735bSStefano Zampini Mat B,loc_divudotp; 67151ae86dd6SStefano Zampini Vec v,p; 67161ae86dd6SStefano Zampini IS dummy; 67171ae86dd6SStefano Zampini PetscInt np; 67181ae86dd6SStefano Zampini 6719a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 6720a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 67211ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 6722a198735bSStefano Zampini ierr = MatGetSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 67231ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 67241ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 67251ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 67261ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 67271ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 67281ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 67291ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 67301ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 67311ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 67321ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 67331ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 67341ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 673574e2c79eSStefano Zampini } 67361ae86dd6SStefano Zampini } 67371ae86dd6SStefano Zampini if (reuser) { 67381ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 673974e2c79eSStefano Zampini } else { 67401ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray,nvecs,vp);CHKERRQ(ierr); 67411ae86dd6SStefano Zampini } 67421ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 67431ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 67441ae86dd6SStefano Zampini PetscInt nl; 67451ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 67461ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 67471ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 67481ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 67491ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 67501ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 67511ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 67521ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 6753a198735bSStefano Zampini } else { 6754a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 67551ae86dd6SStefano Zampini } 67561ae86dd6SStefano Zampini } else { 67571ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray,0,NULL);CHKERRQ(ierr); 67586e683305SStefano Zampini } 675957de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 676057de7509SStefano Zampini PetscMPIInt size; 676157de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size); 676257de7509SStefano Zampini if (!multilevel_allowed) { 676357de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 67646e683305SStefano Zampini } else { 676557de7509SStefano Zampini Mat A; 6766779c1cceSStefano Zampini 676757de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 676857de7509SStefano Zampini if (coarse_mat_is) { 676957de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 677057de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 677157de7509SStefano Zampini coarse_mat = coarse_mat_is; 677257de7509SStefano Zampini } 677357de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 677457de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 677557de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 6776779c1cceSStefano Zampini } 6777779c1cceSStefano Zampini } 677857de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 677957de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 67806e683305SStefano Zampini 67816e683305SStefano Zampini /* create local to global scatters for coarse problem */ 678268457ee5SStefano Zampini if (compute_vecs) { 67836e683305SStefano Zampini PetscInt lrows; 67846e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 678557de7509SStefano Zampini if (coarse_mat) { 678657de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 67876e683305SStefano Zampini } else { 67886e683305SStefano Zampini lrows = 0; 67896e683305SStefano Zampini } 67906e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 67916e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 67926e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 67936e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 67946e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 67956e683305SStefano Zampini } 67966e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 6797c8587f34SStefano Zampini 6798f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 6799f9eb5b7dSStefano Zampini if (multilevel_allowed) { 6800f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 6801f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 6802f9eb5b7dSStefano Zampini } else { 6803f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 6804f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 6805c8587f34SStefano Zampini } 6806c8587f34SStefano Zampini 68076e683305SStefano Zampini /* print some info if requested */ 68086e683305SStefano Zampini if (pcbddc->dbg_flag) { 68096e683305SStefano Zampini if (!multilevel_allowed) { 68106e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 68116e683305SStefano Zampini if (multilevel_requested) { 68126e683305SStefano 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); 68136e683305SStefano Zampini } else if (pcbddc->max_levels) { 68146e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 68156e683305SStefano Zampini } 68166e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 68176e683305SStefano Zampini } 68186e683305SStefano Zampini } 68196e683305SStefano Zampini 6820f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 682157de7509SStefano Zampini if (coarse_mat) { 68226a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 68236e683305SStefano Zampini if (pcbddc->dbg_flag) { 682457de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 68256e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 68266e683305SStefano Zampini } 6827f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 6828312be037SStefano Zampini char prefix[256],str_level[16]; 6829e604994aSStefano Zampini size_t len; 683057de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 6831422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 6832c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 6833f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 683457de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 6835c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 68366e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 6837c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 6838c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 6839e604994aSStefano Zampini /* prefix */ 6840e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 6841e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 6842e604994aSStefano Zampini if (!pcbddc->current_level) { 6843e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 6844e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 6845c8587f34SStefano Zampini } else { 6846e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 6847312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 6848312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 684934d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 6850312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 6851e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 6852e604994aSStefano Zampini } 6853e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 68543e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 68553e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 68563e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 68573e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 6858f9eb5b7dSStefano Zampini /* allow user customization */ 6859f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 68603e3c6dadSStefano Zampini } 68613e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 686251bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 68633e3c6dadSStefano Zampini if (nisdofs) { 68643e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 68653e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 68663e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 68673e3c6dadSStefano Zampini } 68683e3c6dadSStefano Zampini } 68693e3c6dadSStefano Zampini if (nisneu) { 68703e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 68713e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 6872312be037SStefano Zampini } 687330368db7SStefano Zampini if (nisvert) { 687430368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 687530368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 687630368db7SStefano Zampini } 6877f9eb5b7dSStefano Zampini 6878f9eb5b7dSStefano Zampini /* get some info after set from options */ 6879f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 6880f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 68814f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 68826e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 6883f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 6884f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 6885f9eb5b7dSStefano Zampini } 688639f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 68874f3a063dSStefano Zampini if (isredundant) { 68884f3a063dSStefano Zampini KSP inner_ksp; 68894f3a063dSStefano Zampini PC inner_pc; 68904f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 68914f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 68924f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 68934f3a063dSStefano Zampini } 6894f9eb5b7dSStefano Zampini 689557de7509SStefano Zampini /* parameters which miss an API */ 689657de7509SStefano Zampini if (isbddc) { 6897720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 6898720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 689957de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 690027b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 690127b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 6902a198735bSStefano Zampini Mat coarsedivudotp_is; 6903a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 6904a198735bSStefano Zampini IS row,col; 6905a198735bSStefano Zampini const PetscInt *gidxs; 6906a198735bSStefano Zampini PetscInt n,st,M,N; 6907a198735bSStefano Zampini 6908a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 6909a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 6910a198735bSStefano Zampini st = st-n; 6911a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 6912a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 6913a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 6914a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 6915a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 6916a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 6917a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 6918a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 6919a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 6920a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 6921a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 6922a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 6923a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 6924a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 6925a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 6926a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 6927a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 6928a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 6929a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 6930a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 69318ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 6932a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 6933720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 693459e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 6935720d30f9SStefano Zampini } 6936d4d8cf7bSStefano Zampini } 69379881197aSStefano Zampini 69383301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 69395a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 69403301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 69413301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 69423301b35fSStefano Zampini } 69433301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 69443301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 69453301b35fSStefano Zampini } 69463301b35fSStefano Zampini if (pc->pmat->spd_set) { 69473301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 69483301b35fSStefano Zampini } 694927b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 695027b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 695127b6a85dSStefano Zampini } 69526e683305SStefano Zampini /* set operators */ 69535f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 69546e683305SStefano Zampini if (pcbddc->dbg_flag) { 69556e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 69566e683305SStefano Zampini } 69576e683305SStefano Zampini } 69586e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 6959b1ecc7b1SStefano Zampini #if 0 6960b9b85e73SStefano Zampini { 6961b9b85e73SStefano Zampini PetscViewer viewer; 6962b9b85e73SStefano Zampini char filename[256]; 6963b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 6964b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 69656a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 6966b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 6967f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 6968b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 6969b9b85e73SStefano Zampini } 6970b9b85e73SStefano Zampini #endif 6971f9eb5b7dSStefano Zampini 697298a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 697398a51de6SStefano Zampini Vec crhs,csol; 697404708bb6SStefano Zampini 6975f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 6976f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 6977f347579bSStefano Zampini if (!csol) { 69782a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 6979f9eb5b7dSStefano Zampini } 6980f347579bSStefano Zampini if (!crhs) { 69812a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 6982f347579bSStefano Zampini } 6983b0f5fe93SStefano Zampini } 69841ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 6985b0f5fe93SStefano Zampini 6986b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 6987b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 6988b0f5fe93SStefano Zampini 6989b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 69904f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 69914f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 69924f1b2e48SStefano Zampini } 6993b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 6994b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 6995b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6996b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6997b0f5fe93SStefano Zampini if (coarse_mat) { 6998b0f5fe93SStefano Zampini Vec nullv; 6999b0f5fe93SStefano Zampini PetscScalar *array,*array2; 7000b0f5fe93SStefano Zampini PetscInt nl; 7001b0f5fe93SStefano Zampini 7002b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 7003b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 7004b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7005b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 7006b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 7007b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 7008b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7009b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 7010b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 7011b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 7012b0f5fe93SStefano Zampini } 7013b0f5fe93SStefano Zampini } 7014b0f5fe93SStefano Zampini 7015b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 7016b0f5fe93SStefano Zampini PetscBool ispreonly; 7017b0f5fe93SStefano Zampini 7018b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7019b0f5fe93SStefano Zampini PetscBool isnull; 7020b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 7021bef83e63SStefano Zampini if (isnull) { 7022b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 7023b0f5fe93SStefano Zampini } 7024bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 7025b0f5fe93SStefano Zampini } 7026b0f5fe93SStefano Zampini /* setup coarse ksp */ 7027b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 7028cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 7029cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 70306e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 7031c8587f34SStefano Zampini KSP check_ksp; 70322b510759SStefano Zampini KSPType check_ksp_type; 7033c8587f34SStefano Zampini PC check_pc; 70346e683305SStefano Zampini Vec check_vec,coarse_vec; 70356a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 70362b510759SStefano Zampini PetscInt its; 70376e683305SStefano Zampini PetscBool compute_eigs; 70386e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 70396e683305SStefano Zampini PetscInt neigs; 70408e185a42SStefano Zampini const char *prefix; 7041c8587f34SStefano Zampini 70422b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 70436e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 7044422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 704523ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7046f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 7047e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 7048e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 7049e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 70502b510759SStefano Zampini if (ispreonly) { 70512b510759SStefano Zampini check_ksp_type = KSPPREONLY; 70526e683305SStefano Zampini compute_eigs = PETSC_FALSE; 70532b510759SStefano Zampini } else { 7054cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 70556e683305SStefano Zampini compute_eigs = PETSC_TRUE; 7056c8587f34SStefano Zampini } 7057c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 70586e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 70596e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 70606e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 7061a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 7062a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 7063a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 7064a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 7065c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 7066c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 7067c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 7068c8587f34SStefano Zampini /* create random vec */ 70692701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 7070c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 70716e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 7072c8587f34SStefano Zampini /* solve coarse problem */ 70736e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 7074cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 70756e683305SStefano Zampini if (compute_eigs) { 7076854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 7077854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 70786e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 70791ae86dd6SStefano Zampini if (neigs) { 70806e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 70816e683305SStefano Zampini lambda_min = eigs_r[0]; 70826e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 70832701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 70842701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 7085cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 7086cbcc2c2aSStefano Zampini } 7087c8587f34SStefano Zampini } 7088c8587f34SStefano Zampini } 70891ae86dd6SStefano Zampini } 7090cbcc2c2aSStefano Zampini 7091c8587f34SStefano Zampini /* check coarse problem residual error */ 70926e683305SStefano Zampini if (pcbddc->dbg_flag) { 70936e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 70946e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 70956e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 7096c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 70976e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 70986e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 7099779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 71006e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 71016e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 71026e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 71036e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 7104b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7105b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 7106b0f5fe93SStefano Zampini } 71076e683305SStefano Zampini if (compute_eigs) { 71086e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 7109deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 7110c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 71116e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 71126e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem eigenvalues (estimated with %d iterations of %s): %1.6e %1.6e (%1.6e %1.6e)\n",its,check_ksp_type,lambda_min,lambda_max,lambda_min_s,lambda_max_s);CHKERRQ(ierr); 71136e683305SStefano Zampini for (i=0;i<neigs;i++) { 71146e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 7115c8587f34SStefano Zampini } 71166e683305SStefano Zampini } 71176e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 71186e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 71196e683305SStefano Zampini } 7120e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 71212701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 7122c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 71236e683305SStefano Zampini if (compute_eigs) { 71246e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 71256e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 7126c8587f34SStefano Zampini } 71276e683305SStefano Zampini } 71286e683305SStefano Zampini } 7129bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 7130cbcc2c2aSStefano Zampini /* print additional info */ 7131cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 71326e683305SStefano Zampini /* waits until all processes reaches this point */ 71336e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 7134cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 7135cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7136cbcc2c2aSStefano Zampini } 7137cbcc2c2aSStefano Zampini 71382b510759SStefano Zampini /* free memory */ 7139fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 7140c8587f34SStefano Zampini PetscFunctionReturn(0); 7141c8587f34SStefano Zampini } 7142674ae819SStefano Zampini 7143f34684f1SStefano Zampini #undef __FUNCT__ 7144f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 7145f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 7146f34684f1SStefano Zampini { 7147f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7148f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 7149f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 7150dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 7151dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 715273be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 7153dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 7154f34684f1SStefano Zampini PetscErrorCode ierr; 7155f34684f1SStefano Zampini 7156f34684f1SStefano Zampini PetscFunctionBegin; 7157f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 71586c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 7159dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 71603bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 7161dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7162dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 71636583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 7164dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 7165dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 7166dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 71676c4ed002SBarry 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); 7168dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 7169dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7170dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 7171dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7172dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7173f34684f1SStefano Zampini 7174f34684f1SStefano Zampini /* check numbering */ 7175f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 7176019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 7177dc456d91SStefano Zampini PetscInt i; 7178b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 7179f34684f1SStefano Zampini 7180f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7181f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 7182f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 71831575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7184019a44ceSStefano Zampini /* counter */ 7185019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7186019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 7187019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7188019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7189019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7190019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7191f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 7192f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 7193727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 7194f34684f1SStefano Zampini } 7195f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7196f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7197f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7198e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7199e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7200e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7201e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7202f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7203019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7204f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7205019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 72062c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 720775c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 7208b9b85e73SStefano Zampini set_error = PETSC_TRUE; 72092c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 72102c66d082SStefano 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); 7211f34684f1SStefano Zampini } 7212f34684f1SStefano Zampini } 7213019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7214b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 7215f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7216f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7217f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 7218f34684f1SStefano Zampini } 7219f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7220f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7221e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7222e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7223f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 7224f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 7225b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 7226ca8b9ea9SStefano Zampini PetscInt *gidxs; 7227ca8b9ea9SStefano Zampini 7228ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 72293bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 7230f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 7231f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7232f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 7233f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 72344bc2dc4bSStefano 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); 7235f34684f1SStefano Zampini } 7236f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7237ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 7238f34684f1SStefano Zampini } 7239f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 72401575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7241302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 7242f34684f1SStefano Zampini } 72438bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 7244f34684f1SStefano Zampini /* get back data */ 7245f34684f1SStefano Zampini *coarse_size_n = coarse_size; 7246f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 7247674ae819SStefano Zampini PetscFunctionReturn(0); 7248674ae819SStefano Zampini } 7249674ae819SStefano Zampini 7250e456f2a8SStefano Zampini #undef __FUNCT__ 7251e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 7252a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 7253e456f2a8SStefano Zampini { 7254e456f2a8SStefano Zampini IS localis_t; 7255a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 7256e456f2a8SStefano Zampini PetscScalar *vals; 7257e456f2a8SStefano Zampini PetscErrorCode ierr; 7258e456f2a8SStefano Zampini 7259e456f2a8SStefano Zampini PetscFunctionBegin; 7260a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 7261e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 7262854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 7263e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 7264e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7265a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 7266a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 72671035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 7268a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 72691035eff8SStefano Zampini } 7270a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 7271e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7272e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 7273a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 7274a7dc3881SStefano Zampini /* now compute set in local ordering */ 7275a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7276a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7277a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7278a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 7279a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7280ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7281e456f2a8SStefano Zampini lsize++; 7282e456f2a8SStefano Zampini } 7283e456f2a8SStefano Zampini } 7284854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 7285a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7286ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7287e456f2a8SStefano Zampini idxs[lsize++] = i; 7288e456f2a8SStefano Zampini } 7289e456f2a8SStefano Zampini } 7290a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7291a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 7292e456f2a8SStefano Zampini *localis = localis_t; 7293e456f2a8SStefano Zampini PetscFunctionReturn(0); 7294e456f2a8SStefano Zampini } 7295906d46d4SStefano Zampini 7296b96c3477SStefano Zampini #undef __FUNCT__ 7297b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 729808122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 7299b96c3477SStefano Zampini { 7300a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7301b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7302b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 7303a64f4aa4SStefano Zampini Mat S_j; 7304b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 7305b96c3477SStefano Zampini PetscBool free_used_adj; 7306b96c3477SStefano Zampini PetscErrorCode ierr; 7307b96c3477SStefano Zampini 7308b96c3477SStefano Zampini PetscFunctionBegin; 7309b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 7310b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 731108122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 7312b96c3477SStefano Zampini used_xadj = NULL; 7313b96c3477SStefano Zampini used_adjncy = NULL; 7314b96c3477SStefano Zampini } else { 731508122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 731608122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 731708122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 731808122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 7319b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 7320b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 7321b96c3477SStefano Zampini } else { 73222fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 7323b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 7324b96c3477SStefano Zampini PetscInt nvtxs; 7325b96c3477SStefano Zampini 73262fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 73272fffb893SStefano Zampini if (flg_row) { 7328b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 7329b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 7330b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 7331b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 73322fffb893SStefano Zampini } else { 73332fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 73342fffb893SStefano Zampini used_xadj = NULL; 73352fffb893SStefano Zampini used_adjncy = NULL; 73362fffb893SStefano Zampini } 73372fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 7338b96c3477SStefano Zampini } 7339b96c3477SStefano Zampini } 7340d5574798SStefano Zampini 7341d5574798SStefano Zampini /* setup sub_schurs data */ 7342a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 7343df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 7344df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 7345a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 734691af6908SStefano 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); 7347a64f4aa4SStefano Zampini } else { 73486816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 73494d7f8f00SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE; 7350a3df083aSStefano Zampini PetscInt benign_n; 735172b8c272SStefano Zampini Mat change = NULL; 73529d54b7f4SStefano Zampini Vec scaling = NULL; 735372b8c272SStefano Zampini IS change_primal = NULL; 7354a3df083aSStefano Zampini 73555feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 73565feab87aSStefano Zampini PetscInt n_vertices; 73575feab87aSStefano Zampini 73585feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 73592034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 73605feab87aSStefano Zampini } 736104708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 736204708bb6SStefano Zampini if (!isseqaij) { 736304708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 736404708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 736504708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 736604708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 736704708bb6SStefano Zampini } else { 7368511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 736904708bb6SStefano Zampini } 737004708bb6SStefano Zampini } 7371a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 7372a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 7373ca92afb2SStefano Zampini } else { 7374a3df083aSStefano Zampini benign_n = 0; 7375ca92afb2SStefano Zampini } 7376b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 7377b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 7378b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 737972b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 738022db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 7381b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 738222db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 7383b7ab4a40SStefano Zampini } 7384b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 7385b7ab4a40SStefano 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 */ 7386b7ab4a40SStefano Zampini if (need_change) { 738788c03ad3SStefano Zampini PC_IS *pcisf; 738888c03ad3SStefano Zampini PC_BDDC *pcbddcf; 738988c03ad3SStefano Zampini PC pcf; 739088c03ad3SStefano Zampini 7391e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 739288c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 739388c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 739488c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 739588c03ad3SStefano Zampini /* hacks */ 739688c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 739772b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 739872b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 739972b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 740072b8c272SStefano Zampini pcisf->n = pcis->n; 740172b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 740288c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 740388c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 740488c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 740588c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 740688c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 740788c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 740872b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 740988c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 741088c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 741172b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 741272b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 741372b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 741472b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 741572b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 741688c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 741772b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 741888c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 741988c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 742088c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 742188c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 742288c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 742388c03ad3SStefano Zampini pcf->ops->destroy = NULL; 742488c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 742588c03ad3SStefano Zampini } 74269d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 742791af6908SStefano 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); 742872b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 742972b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 7430ca92afb2SStefano Zampini } 7431d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 7432b96c3477SStefano Zampini 7433b96c3477SStefano Zampini /* free adjacency */ 7434b96c3477SStefano Zampini if (free_used_adj) { 7435b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 7436b96c3477SStefano Zampini } 7437b96c3477SStefano Zampini PetscFunctionReturn(0); 7438b96c3477SStefano Zampini } 7439b96c3477SStefano Zampini 7440b96c3477SStefano Zampini #undef __FUNCT__ 7441b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 744208122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 7443b96c3477SStefano Zampini { 7444b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7445b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7446b96c3477SStefano Zampini PCBDDCGraph graph; 7447b96c3477SStefano Zampini PetscErrorCode ierr; 7448b96c3477SStefano Zampini 7449b96c3477SStefano Zampini PetscFunctionBegin; 7450b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 745108122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 74523301b35fSStefano Zampini IS verticesIS,verticescomm; 74533301b35fSStefano Zampini PetscInt vsize,*idxs; 7454b96c3477SStefano Zampini 7455b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 74563301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 74573301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 74583301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 74593301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 7460c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 7461b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 7462*be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 7463441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 74643301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 7465b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 7466b96c3477SStefano Zampini } else { 7467b96c3477SStefano Zampini graph = pcbddc->mat_graph; 7468b96c3477SStefano Zampini } 7469e4d548c7SStefano Zampini /* print some info */ 7470e4d548c7SStefano Zampini if (pcbddc->dbg_flag) { 7471e4d548c7SStefano Zampini IS vertices; 7472e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 7473c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 7474e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 7475e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 7476e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7477e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 7478e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 7479e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 7480e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 7481e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7482e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7483c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 7484e4d548c7SStefano Zampini } 7485b96c3477SStefano Zampini 7486b96c3477SStefano Zampini /* sub_schurs init */ 7487b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 7488b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 7489b334f244SStefano Zampini } 7490b334f244SStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 7491a64f4aa4SStefano Zampini 7492b96c3477SStefano Zampini /* free graph struct */ 749308122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 7494b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 7495b96c3477SStefano Zampini } 7496b96c3477SStefano Zampini PetscFunctionReturn(0); 7497b96c3477SStefano Zampini } 7498fa34dd3eSStefano Zampini 7499fa34dd3eSStefano Zampini #undef __FUNCT__ 7500fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 7501fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 7502fa34dd3eSStefano Zampini { 7503fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7504fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7505fa34dd3eSStefano Zampini PetscErrorCode ierr; 7506fa34dd3eSStefano Zampini 7507fa34dd3eSStefano Zampini PetscFunctionBegin; 7508fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 7509fa34dd3eSStefano Zampini IS zerodiag = NULL; 75104f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 7511fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 75124f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 751375c01103SStefano Zampini PetscReal norm; 7514fa34dd3eSStefano Zampini PetscInt i; 7515fa34dd3eSStefano Zampini 7516fa34dd3eSStefano Zampini /* B0 and B0_B */ 7517fa34dd3eSStefano Zampini if (zerodiag) { 7518fa34dd3eSStefano Zampini IS dummy; 7519fa34dd3eSStefano Zampini 75204f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 75214f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 7522fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 7523fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 7524fa34dd3eSStefano Zampini } 7525fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 7526fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 7527fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 7528fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7529fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7530fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7531fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7532fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 7533fa34dd3eSStefano Zampini /* S_j */ 7534fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 7535fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 7536fa34dd3eSStefano Zampini 7537fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 7538fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 7539fa34dd3eSStefano Zampini /* continuous in primal space */ 7540fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 7541fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7542fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7543fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 75444f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 75454f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 7546fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 7547fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7548fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7549fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7550fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7551fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7552fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 7553fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 7554fa34dd3eSStefano Zampini 7555fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 7556fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 7557fa34dd3eSStefano Zampini /* local with Schur */ 7558fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 7559fa34dd3eSStefano Zampini if (zerodiag) { 7560fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 75614f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 7562fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 7563fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 7564fa34dd3eSStefano Zampini } 7565fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 7566fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7567fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7568fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7569fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 7570fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 7571fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 7572fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7573fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 7574fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7575fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7576fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7577fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7578fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7579fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 7580fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 7581fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 7582fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7583fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7584fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7585fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7586fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7587fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 7588fa34dd3eSStefano Zampini if (zerodiag) { 7589fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 7590fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 75914f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 7592fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 7593fa34dd3eSStefano Zampini } 7594fa34dd3eSStefano Zampini /* BDDC */ 7595fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 7596fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 7597fa34dd3eSStefano Zampini 7598fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 7599fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 7600fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 7601fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 76024f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 76034f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 7604fa34dd3eSStefano Zampini } 76054f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 7606fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 7607fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 7608fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 7609fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 7610fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 7611fa34dd3eSStefano Zampini } 7612fa34dd3eSStefano Zampini PetscFunctionReturn(0); 7613fa34dd3eSStefano Zampini } 7614