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; 1104e64d54eSstefano_zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe; 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; 1184e64d54eSstefano_zampini PetscBT btv,bte,btvc,btb,btvcand,btvi; 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 i,j,extmem,cum,maxsize,rst,nee,nquads=2; 125a13144ffSStefano Zampini PetscInt *extrow,*extrowcum,*marks,*emarks,*vmarks,*gidxs; 126a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 127a13144ffSStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,ismpiaij; 128a13144ffSStefano Zampini PetscErrorCode ierr; 129a13144ffSStefano Zampini 130a13144ffSStefano Zampini PetscFunctionBegin; 131a13144ffSStefano Zampini /* test variable order code and print debug info TODO: to be removed */ 132a13144ffSStefano Zampini print = PETSC_FALSE; 133a13144ffSStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_print_nedelec",&print,NULL);CHKERRQ(ierr); 134a13144ffSStefano Zampini ierr = PetscOptionsGetInt(NULL,NULL,"-pc_bddc_nedelec_order",&pcbddc->nedorder,NULL);CHKERRQ(ierr); 135a13144ffSStefano Zampini 136a13144ffSStefano Zampini /* Return to caller if there are no edges in the decomposition */ 137a13144ffSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 138a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&el2g,NULL);CHKERRQ(ierr); 139a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(el2g,&ne);CHKERRQ(ierr); 140a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 141a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 142a13144ffSStefano Zampini for (i=0;i<ne;i++) { 143a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 144a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 145a13144ffSStefano Zampini break; 146a13144ffSStefano Zampini } 147a13144ffSStefano Zampini } 148a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 149a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 150a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 151a13144ffSStefano Zampini 152a13144ffSStefano Zampini /* Get relevant objects */ 153a13144ffSStefano Zampini G = pcbddc->discretegradient; 154a13144ffSStefano Zampini order = pcbddc->nedorder; 155a13144ffSStefano Zampini conforming = pcbddc->conforming; 156a13144ffSStefano Zampini 157a13144ffSStefano Zampini /* Compute local and global sizes of egde dofs and nodal dofs */ 158a13144ffSStefano Zampini ierr = MatGetSize(G,&Ne,&Nv);CHKERRQ(ierr); 159a13144ffSStefano Zampini ierr = MatGetLocalSize(G,&Le,&Lv);CHKERRQ(ierr); 160a13144ffSStefano Zampini 161a13144ffSStefano Zampini /* Sanity checks */ 162a13144ffSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 163a13144ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)G,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr); 164a13144ffSStefano 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); 165a13144ffSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 166a13144ffSStefano 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); 167a13144ffSStefano 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); 168a13144ffSStefano Zampini ierr = MatGetSize(pc->pmat,&i,NULL);CHKERRQ(ierr); 169a13144ffSStefano 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); 170a13144ffSStefano Zampini ierr = MatGetLocalSize(pc->pmat,&i,NULL);CHKERRQ(ierr); 171a13144ffSStefano 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); 172a13144ffSStefano Zampini 173a13144ffSStefano Zampini /* Drop connections for interior edges (this modifies G) */ 174a13144ffSStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 175a13144ffSStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->counter,tvec,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 176a13144ffSStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->counter,tvec,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 177a13144ffSStefano Zampini ierr = PetscMalloc1(Le,&marks);CHKERRQ(ierr); 178a13144ffSStefano Zampini ierr = VecGetOwnershipRange(tvec,&rst,NULL);CHKERRQ(ierr); 179a13144ffSStefano Zampini ierr = VecGetArrayRead(tvec,(const PetscScalar**)&vals);CHKERRQ(ierr); 180a13144ffSStefano Zampini cum = 0; 181a13144ffSStefano Zampini for (i=0;i<Le;i++) if (PetscRealPart(vals[i]) < 1.5) marks[cum++] = i+rst; 182a13144ffSStefano Zampini ierr = VecRestoreArrayRead(tvec,(const PetscScalar**)&vals);CHKERRQ(ierr); 183a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 184a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 185a13144ffSStefano Zampini ierr = MatZeroRows(G,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 186a13144ffSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 187a13144ffSStefano Zampini 188a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 189a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 190a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 191a13144ffSStefano Zampini ierr = MatGetSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 192a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 193a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 194a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 195a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 196a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 197a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 198a13144ffSStefano Zampini if (print) { 199a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 200a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 201a13144ffSStefano Zampini } 202a13144ffSStefano Zampini 203a13144ffSStefano Zampini /* SF for nodal communications */ 204a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 205a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 206a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 207a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 208a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 209a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 210a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 211a13144ffSStefano Zampini ierr = PetscMalloc2(nv,&sfvleaves,Lv,&sfvroots);CHKERRQ(ierr); 212a13144ffSStefano Zampini 213a13144ffSStefano Zampini /* Destroy temporary G created in MATIS format */ 214a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 215a13144ffSStefano Zampini 216a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 2174e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 2184e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 219a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 220a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 221a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 222a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 223a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 224a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 225a13144ffSStefano Zampini ierr = ISGetLocalSize(pcbddc->DirichletBoundariesLocal,&cum);CHKERRQ(ierr); 226a13144ffSStefano Zampini ierr = ISGetIndices(pcbddc->DirichletBoundariesLocal,&idxs);CHKERRQ(ierr); 227a13144ffSStefano Zampini for (i=0;i<cum;i++) { 228a13144ffSStefano Zampini if (idxs[i] >= 0) { 229a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 230a13144ffSStefano Zampini } 231a13144ffSStefano Zampini } 232a13144ffSStefano Zampini ierr = ISRestoreIndices(pcbddc->DirichletBoundariesLocal,&idxs);CHKERRQ(ierr); 233a13144ffSStefano Zampini } 234a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 235a13144ffSStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&cum);CHKERRQ(ierr); 236a13144ffSStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 237a13144ffSStefano Zampini for (i=0;i<cum;i++) { 238a13144ffSStefano Zampini if (idxs[i] >= 0) { 239a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 240a13144ffSStefano Zampini } 241a13144ffSStefano Zampini } 242a13144ffSStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 243a13144ffSStefano Zampini } 244a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 245a13144ffSStefano Zampini /* need to remove coarse faces' dofs to ensure the 246a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 247a13144ffSStefano Zampini ierr = PetscCalloc1(ne,&marks);CHKERRQ(ierr); 248a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 249a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 250a13144ffSStefano Zampini PetscInt j; 251a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) marks[shared[i][j]]++; 252a13144ffSStefano Zampini } 253a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 254a13144ffSStefano Zampini cum = 0; 2554e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 256dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 257a13144ffSStefano Zampini for (i=0;i<ne;i++) { 258dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 259dec27d64SStefano Zampini if (!marks[i] || (marks[i] == 1 && !PetscBTLookup(btb,i))) { 260a13144ffSStefano Zampini marks[cum++] = i; 261dec27d64SStefano Zampini continue; 262dec27d64SStefano Zampini } 263dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 264dec27d64SStefano Zampini if (!conforming && ii[i+1]-ii[i] != order + 1) { 265a13144ffSStefano Zampini marks[cum++] = i; 266a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 267a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 268a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 269a13144ffSStefano Zampini } 270a13144ffSStefano Zampini } 271dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 272dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 273dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 274dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 275a13144ffSStefano Zampini } 276dec27d64SStefano Zampini } 277dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 2784e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 2794e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 280a13144ffSStefano Zampini /* identify splitpoints and corner candidates: TODO variable order */ 2814e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 282a13144ffSStefano Zampini if (print) { 2834e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 2844e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 2854e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 286a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 287a13144ffSStefano Zampini } 288a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 289dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 290a13144ffSStefano Zampini for (i=0;i<nv;i++) { 291dec27d64SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i]; 292dec27d64SStefano Zampini if (!order) { 293dec27d64SStefano Zampini PetscReal vorder = 0.; 294dec27d64SStefano Zampini 295dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 296dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 297dec27d64SStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%d)",vorder,test); 298dec27d64SStefano Zampini ord = 1; 299dec27d64SStefano Zampini } 300a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 301dec27d64SStefano Zampini if (test%ord) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected number of edge dofs %d connected with nodal dof %d with order %d",test,i,ord); 302a13144ffSStefano Zampini #endif 303dec27d64SStefano Zampini if (test >= 3*ord) { /* splitpoints */ 304a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d\n",i); 305a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 306dec27d64SStefano Zampini } else if (test == ord) { 307a13144ffSStefano Zampini if (order == 1) { 308a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 309a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 310a13144ffSStefano Zampini } else { 311a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 312a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 313a13144ffSStefano Zampini } 314a13144ffSStefano Zampini } 315a13144ffSStefano Zampini } 316dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 317a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 318a13144ffSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 319a13144ffSStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 320a13144ffSStefano Zampini 321a13144ffSStefano Zampini /* Get the local G^T explicitly */ 322a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 3234e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 324a13144ffSStefano Zampini if (print) { 325a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"initial_lGt");CHKERRQ(ierr); 326a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 327a13144ffSStefano Zampini } 328a13144ffSStefano Zampini 3294e64d54eSstefano_zampini /* Mark interior nodal dofs */ 330a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 3314e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 332a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 333a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 3344e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 335a13144ffSStefano Zampini } 336a13144ffSStefano Zampini } 337a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 338a13144ffSStefano Zampini 339a13144ffSStefano Zampini /* communicate corners and splitpoints */ 340a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 341a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 342a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 343a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 344a13144ffSStefano Zampini 345a13144ffSStefano Zampini if (print) { 346a13144ffSStefano Zampini IS tbz; 347a13144ffSStefano Zampini 348a13144ffSStefano Zampini cum = 0; 349a13144ffSStefano Zampini for (i=0;i<nv;i++) 350a13144ffSStefano Zampini if (sfvleaves[i]) 351a13144ffSStefano Zampini vmarks[cum++] = i; 352a13144ffSStefano Zampini 353a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 354a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 355a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 356a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 357a13144ffSStefano Zampini } 358a13144ffSStefano Zampini 359a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 360a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 361a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 362a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 363a13144ffSStefano Zampini 3644e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 3654e64d54eSstefano_zampini and interior nodal dofs */ 366a13144ffSStefano Zampini cum = 0; 367a13144ffSStefano Zampini for (i=0;i<nv;i++) { 368a13144ffSStefano Zampini if (sfvleaves[i]) { 369a13144ffSStefano Zampini vmarks[cum++] = i; 370a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 371a13144ffSStefano Zampini } 3724e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 373a13144ffSStefano Zampini } 3744e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 375a13144ffSStefano Zampini if (print) { 376a13144ffSStefano Zampini IS tbz; 377a13144ffSStefano Zampini 378a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 3794e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 380a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 381a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 382a13144ffSStefano Zampini } 383a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 384a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 385a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 386a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 387a13144ffSStefano Zampini 388a13144ffSStefano Zampini /* Recompute G */ 389a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 390a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 391a13144ffSStefano Zampini if (print) { 392a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 393a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 394a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 395a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 396a13144ffSStefano Zampini } 397a13144ffSStefano Zampini 398a13144ffSStefano Zampini /* Get primal dofs (if any) */ 399a13144ffSStefano Zampini cum = 0; 400a13144ffSStefano Zampini for (i=0;i<ne;i++) { 401a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 402a13144ffSStefano Zampini } 403a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 404a13144ffSStefano Zampini if (print) { 405a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 406a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 407a13144ffSStefano Zampini } 408a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 409a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 410a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 411a13144ffSStefano Zampini 412a13144ffSStefano Zampini /* Compute edge connectivity */ 413a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 414a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 415a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 416*d904f53bSStefano Zampini if (done && i && ii && jj) { /* when lG is empty, don't pass pointers */ 417a13144ffSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,ne,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 418*d904f53bSStefano Zampini } 419a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 420a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 421a13144ffSStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 422a13144ffSStefano Zampini 423a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 424a13144ffSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 425a13144ffSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&eedges,&primals);CHKERRQ(ierr); 426a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 427a13144ffSStefano Zampini 428a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 429a13144ffSStefano Zampini maxsize = 0; 430a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 431a13144ffSStefano Zampini for (i=0;i<nee;i++) { 432a13144ffSStefano Zampini PetscInt size,mark = i+1; 433a13144ffSStefano Zampini 434a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 435a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 436a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 437a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 438a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 439a13144ffSStefano Zampini } 440a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 441a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 442a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 443a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 444a13144ffSStefano Zampini if (print) { 445a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 446a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 447a13144ffSStefano Zampini } 448a13144ffSStefano Zampini 449a13144ffSStefano Zampini /* Find coarse edge endpoints */ 450a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 451a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 452a13144ffSStefano Zampini for (i=0;i<nee;i++) { 453a13144ffSStefano Zampini PetscInt mark = i+1,size; 454a13144ffSStefano Zampini 455a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 456a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 457a13144ffSStefano Zampini if (print) { 458a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 459a13144ffSStefano Zampini ISView(eedges[i],NULL); 460a13144ffSStefano Zampini } 461a13144ffSStefano Zampini for (j=0;j<size;j++) { 462a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 463a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 464a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 465a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 466a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 467a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 468a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 469a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," candidate? %d\n",(PetscBool)(PetscBTLookup(btvcand,jj[k]))); 470a13144ffSStefano Zampini PetscInt k2; 471a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 472a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 473a13144ffSStefano 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]]); 474a13144ffSStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || 475a13144ffSStefano Zampini pcbddc->mat_graph->special_dof[jjt[k2]] == PCBDDCGRAPH_DIRICHLET_MARK) { 476a13144ffSStefano Zampini corner = PETSC_TRUE; 477a13144ffSStefano Zampini break; 478a13144ffSStefano Zampini } 479a13144ffSStefano Zampini } 480a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 481a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 482a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 483a13144ffSStefano Zampini } else { 484a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 485a13144ffSStefano Zampini } 486a13144ffSStefano Zampini } 487a13144ffSStefano Zampini } 488a13144ffSStefano Zampini } 489a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 490a13144ffSStefano Zampini } 491a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 492a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 493a13144ffSStefano Zampini 494a13144ffSStefano Zampini /* Reset marked primal dofs */ 495a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 496a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 497a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 498a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 499a13144ffSStefano Zampini 500a13144ffSStefano Zampini /* Compute extended cols indices */ 501a13144ffSStefano Zampini ierr = MatGetRowIJ(lG ,0,PETSC_FALSE,PETSC_FALSE,&i, &ii, &jj,&done);CHKERRQ(ierr); 502a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 503a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 504a13144ffSStefano Zampini i *= maxsize; 505a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extcols);CHKERRQ(ierr); 506a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&emarks);CHKERRQ(ierr); 507a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 508a13144ffSStefano Zampini eerr = PETSC_FALSE; 509a13144ffSStefano Zampini for (i=0;i<nee;i++) { 510a13144ffSStefano Zampini PetscInt size; 511a13144ffSStefano Zampini 512a13144ffSStefano Zampini cum = 0; 513a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 514a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 515a13144ffSStefano Zampini for (j=0;j<size;j++) { 516a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 517a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 518a13144ffSStefano Zampini } 519a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 520a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 521a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 522a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 523a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 524a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 525a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 526a13144ffSStefano Zampini if (cum != size -1) { 527a13144ffSStefano Zampini emarks[i] = 1; 528a13144ffSStefano Zampini if (print) { 529a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 530a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 531a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 532a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 533a13144ffSStefano Zampini } 534a13144ffSStefano Zampini eerr = PETSC_TRUE; 535a13144ffSStefano Zampini } 536a13144ffSStefano Zampini } 5374e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 538a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 539a13144ffSStefano Zampini if (done) { 540a13144ffSStefano Zampini PetscInt *newprimals; 541a13144ffSStefano Zampini 542a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 543a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 544a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 545a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 546a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 547a13144ffSStefano Zampini for (i=0;i<nee;i++) { 548a13144ffSStefano Zampini if (emarks[i]) { 549a13144ffSStefano Zampini PetscInt size,mark = i+1; 550a13144ffSStefano Zampini 551a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 552a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 553a13144ffSStefano Zampini for (j=0;j<size;j++) { 5544e64d54eSstefano_zampini /* newprimals[cum++] = idxs[j]; */ 555a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 556a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 557a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 558a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 559a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 560a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 561a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 562a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 563a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 564a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 565a13144ffSStefano Zampini newprimals[cum++] = ee2; 566a13144ffSStefano Zampini /* finally set the new corners */ 567a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 568a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 569a13144ffSStefano Zampini } 570a13144ffSStefano Zampini } 571a13144ffSStefano Zampini } 572a13144ffSStefano Zampini } 573a13144ffSStefano Zampini } 574a13144ffSStefano Zampini } 575a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 576a13144ffSStefano Zampini } 577a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 578a13144ffSStefano Zampini } 579a13144ffSStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&eedges,&primals);CHKERRQ(ierr); 580a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 581a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 582a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 583a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 584a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 585a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 586a13144ffSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&eedges,&primals);CHKERRQ(ierr); 587a13144ffSStefano Zampini 588a13144ffSStefano Zampini /* Mark again */ 589a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 590a13144ffSStefano Zampini for (i=0;i<nee;i++) { 591a13144ffSStefano Zampini PetscInt size,mark = i+1; 592a13144ffSStefano Zampini 593a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 594a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 595a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 596a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 597a13144ffSStefano Zampini } 598a13144ffSStefano Zampini if (print) { 599a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 600a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 601a13144ffSStefano Zampini } 602a13144ffSStefano Zampini 603a13144ffSStefano Zampini /* Recompute extended cols */ 604a13144ffSStefano Zampini eerr = PETSC_FALSE; 605a13144ffSStefano Zampini for (i=0;i<nee;i++) { 606a13144ffSStefano Zampini PetscInt size; 607a13144ffSStefano Zampini 608a13144ffSStefano Zampini cum = 0; 609a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 610a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 611a13144ffSStefano Zampini for (j=0;j<size;j++) { 612a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 613a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 614a13144ffSStefano Zampini if (!PetscBTLookup(btv,jj[k])) { 615a13144ffSStefano Zampini extrow[cum++] = jj[k]; 616a13144ffSStefano Zampini } 617a13144ffSStefano Zampini } 618a13144ffSStefano Zampini } 619a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 620a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 621a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 622a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 623a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 624a13144ffSStefano Zampini if (cum != size -1) { 625a13144ffSStefano Zampini if (print) { 626a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 627a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 628a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 629a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 630a13144ffSStefano Zampini } 631a13144ffSStefano Zampini eerr = PETSC_TRUE; 632a13144ffSStefano Zampini } 633a13144ffSStefano Zampini } 634a13144ffSStefano Zampini } 635a13144ffSStefano Zampini ierr = MatRestoreRowIJ( lG,0,PETSC_FALSE,PETSC_FALSE,&i, &ii, &jj,&done);CHKERRQ(ierr); 636a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 637a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 638a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 639a13144ffSStefano Zampini /* an error should not occur at this point */ 640a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 641a13144ffSStefano Zampini 6424e64d54eSstefano_zampini /* Check the number of endpoints */ 6434e64d54eSstefano_zampini /* TODO: add case for circular edge */ 6444e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 6454e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 6464e64d54eSstefano_zampini for (i=0;i<nee;i++) { 6474e64d54eSstefano_zampini PetscInt size, found = 0; 6484e64d54eSstefano_zampini 6494e64d54eSstefano_zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 6504e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 6514e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 6524e64d54eSstefano_zampini for (j=0;j<size;j++) { 6534e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 6544e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 6554e64d54eSstefano_zampini PetscInt vv = jj[k]; 6564e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 6574e64d54eSstefano_zampini found++; 6584e64d54eSstefano_zampini } 6594e64d54eSstefano_zampini } 6604e64d54eSstefano_zampini } 6614e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 6624e64d54eSstefano_zampini if (found != 2) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %d corners for edge %d\n",found,i); 6634e64d54eSstefano_zampini } 6644e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 6654e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 6664e64d54eSstefano_zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 6674e64d54eSstefano_zampini 668a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 669a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 670a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 671a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 672a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 673a13144ffSStefano Zampini for (i=0;i<nv;i++) { 674a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 675a13144ffSStefano Zampini 676a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 677a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 678a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 679a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 680a13144ffSStefano Zampini if (emax < emarks[j]) { 681a13144ffSStefano Zampini emax = emarks[j]; 682a13144ffSStefano Zampini eemax = j; 683a13144ffSStefano Zampini } 684a13144ffSStefano Zampini } 685a13144ffSStefano Zampini /* not relevant for edges */ 686a13144ffSStefano Zampini if (!eemax) continue; 687a13144ffSStefano Zampini 688a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 689a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 690a13144ffSStefano 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]); 691a13144ffSStefano Zampini } 692a13144ffSStefano Zampini } 693a13144ffSStefano Zampini } 694a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 695a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 696a13144ffSStefano Zampini #endif 697a13144ffSStefano Zampini 698a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 699a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 700a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 701a13144ffSStefano Zampini extmem *= maxsize; 702a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 703a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 704a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 705a13144ffSStefano Zampini for (i=0;i<nv;i++) { 706a13144ffSStefano Zampini PetscInt mark = 0,size,start; 707a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 708a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 709a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 710a13144ffSStefano Zampini mark = marks[jj[j]]; 711a13144ffSStefano Zampini 712a13144ffSStefano Zampini /* not relevant */ 713a13144ffSStefano Zampini if (!mark) continue; 714a13144ffSStefano Zampini 715a13144ffSStefano Zampini /* import extended row */ 716a13144ffSStefano Zampini mark--; 717a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 718a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 719a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 720a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 721a13144ffSStefano Zampini #endif 722a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 723a13144ffSStefano Zampini extrowcum[mark] += size; 724a13144ffSStefano Zampini } 725a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 726a13144ffSStefano Zampini cum = 0; 727a13144ffSStefano Zampini for (i=0;i<nee;i++) { 728a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 729a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 730a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 731a13144ffSStefano Zampini cum = PetscMax(cum,size); 732a13144ffSStefano Zampini } 733a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 734a13144ffSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 735a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 736a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 737a13144ffSStefano Zampini 738a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 739a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 740a13144ffSStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 741a13144ffSStefano Zampini for (i=0;i<maxsize;i++) vals[i] = 1.; 742a13144ffSStefano Zampini 743a13144ffSStefano Zampini /* Create vectors for quadrature rules */ 744a13144ffSStefano Zampini ierr = PetscMalloc1(nquads,&quads);CHKERRQ(ierr); 745a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 746a13144ffSStefano Zampini ierr = MatCreateVecs(pc->pmat,&quads[i],NULL);CHKERRQ(ierr); 747a13144ffSStefano Zampini ierr = VecSetLocalToGlobalMapping(quads[i],el2g);CHKERRQ(ierr); 748a13144ffSStefano Zampini } 749a13144ffSStefano Zampini ierr = PCBDDCNullSpaceCreate(comm,PETSC_FALSE,nquads,quads,&nnsp);CHKERRQ(ierr); 750a13144ffSStefano Zampini 751a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 752a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 753a13144ffSStefano Zampini ierr = MatSetSizes(T,Le,Le,Ne,Ne);CHKERRQ(ierr); 754a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 755a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 756a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 757a13144ffSStefano Zampini ierr = MatSetLocalToGlobalMapping(T,el2g,el2g);CHKERRQ(ierr); 758a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 759a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 760a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 761a13144ffSStefano Zampini 762a13144ffSStefano Zampini /* Defaults to identity */ 763a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 764a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 765a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 766a13144ffSStefano Zampini 767a13144ffSStefano Zampini for (i=0;i<nee;i++) { 768a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 769a13144ffSStefano Zampini 770a13144ffSStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],&Gins,&GKins,work,rwork);CHKERRQ(ierr); 771a13144ffSStefano Zampini if (Gins && GKins) { 772a13144ffSStefano Zampini PetscScalar *data; 773a13144ffSStefano Zampini const PetscInt *rows,*cols; 774a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 775a13144ffSStefano Zampini 776a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 777a13144ffSStefano Zampini /* H1 */ 778a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 779a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 780a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 781a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 782a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 783a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 784a13144ffSStefano Zampini /* complement */ 785a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 786a13144ffSStefano Zampini if (ncc > nquads-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet supported ncc %d nquads %d",ncc,nquads); 787a13144ffSStefano 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); 788a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 789a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 790a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 791a13144ffSStefano Zampini /* Gins kernel quadratures */ 792a13144ffSStefano Zampini for (j=0;j<ncc;j++) { 793a13144ffSStefano Zampini ierr = VecSetValueLocal(quads[j],cols[nch+j],1.,INSERT_VALUES);CHKERRQ(ierr); 794a13144ffSStefano Zampini } 795a13144ffSStefano Zampini /* H1 average */ 796a13144ffSStefano Zampini ierr = VecSetValuesLocal(quads[nquads-1],nch,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 797a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 798a13144ffSStefano Zampini } 799a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 800a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 801a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 802a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 803a13144ffSStefano Zampini } 804a13144ffSStefano Zampini 805a13144ffSStefano Zampini /* Start assembling */ 806a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 807a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 808a13144ffSStefano Zampini ierr = VecAssemblyBegin(quads[i]);CHKERRQ(ierr); 809a13144ffSStefano Zampini } 810a13144ffSStefano Zampini 811a13144ffSStefano Zampini /* Free */ 812a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 813a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 814a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 815a13144ffSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 816a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 817a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 818a13144ffSStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&eedges,&primals);CHKERRQ(ierr); 819a13144ffSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 820a13144ffSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 821a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 822a13144ffSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 823a13144ffSStefano Zampini 824a13144ffSStefano Zampini /* Complete assembling */ 825a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 826a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 827a13144ffSStefano Zampini ierr = VecAssemblyEnd(quads[i]);CHKERRQ(ierr); 828a13144ffSStefano Zampini } 829a13144ffSStefano Zampini for (i=0;i<nquads;i++) { 830a13144ffSStefano Zampini ierr = VecDestroy(&quads[i]);CHKERRQ(ierr); 831a13144ffSStefano Zampini } 832a13144ffSStefano Zampini ierr = PetscFree(quads);CHKERRQ(ierr); 833a13144ffSStefano Zampini 834a13144ffSStefano Zampini /* tell PCBDDC the topography has been analyzed */ 835a13144ffSStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 836a13144ffSStefano Zampini 837a13144ffSStefano Zampini /* set change of basis */ 838a13144ffSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,PETSC_FALSE);CHKERRQ(ierr); 839a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 840a13144ffSStefano Zampini 841a13144ffSStefano Zampini /* set quadratures */ 842a13144ffSStefano Zampini ierr = MatSetNearNullSpace(pc->pmat,nnsp);CHKERRQ(ierr); 843a13144ffSStefano Zampini ierr = MatNullSpaceDestroy(&nnsp);CHKERRQ(ierr); 844a13144ffSStefano Zampini 845a13144ffSStefano Zampini PetscFunctionReturn(0); 846a13144ffSStefano Zampini } 847a13144ffSStefano Zampini 848d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 849d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 850d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 851d8203eabSStefano Zampini #undef __FUNCT__ 852d8203eabSStefano Zampini #define __FUNCT__ "PCBDDCNullSpaceCreate" 853d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 854d8203eabSStefano Zampini { 855d8203eabSStefano Zampini PetscErrorCode ierr; 856d8203eabSStefano Zampini PetscInt i; 857d8203eabSStefano Zampini 858d8203eabSStefano Zampini PetscFunctionBegin; 859d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 860d8203eabSStefano Zampini PetscInt first,last; 861d8203eabSStefano Zampini 862d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 86386fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 864d8203eabSStefano Zampini if (i>=first && i < last) { 865d8203eabSStefano Zampini PetscScalar *data; 866d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 867d8203eabSStefano Zampini if (!has_const) { 868d8203eabSStefano Zampini data[i-first] = 1.; 869d8203eabSStefano Zampini } else { 87086fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 87186fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 872d8203eabSStefano Zampini } 873d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 874d8203eabSStefano Zampini } 875d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 876d8203eabSStefano Zampini } 877d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 878d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 879d8203eabSStefano Zampini PetscInt first,last; 880d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 881d8203eabSStefano Zampini if (i>=first && i < last) { 882d8203eabSStefano Zampini PetscScalar *data; 883d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 884d8203eabSStefano Zampini if (!has_const) { 885d8203eabSStefano Zampini data[i-first] = 0.; 886d8203eabSStefano Zampini } else { 88786fa73c5SStefano Zampini data[2*i-first] = 0.; 88886fa73c5SStefano Zampini data[2*i-first+1] = 0.; 889d8203eabSStefano Zampini } 890d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 891d8203eabSStefano Zampini } 892d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 893d8203eabSStefano Zampini } 894d8203eabSStefano Zampini PetscFunctionReturn(0); 895d8203eabSStefano Zampini } 896d8203eabSStefano Zampini 897669cc0f4SStefano Zampini #undef __FUNCT__ 898669cc0f4SStefano Zampini #define __FUNCT__ "PCBDDCComputeNoNetFlux" 8998ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 900669cc0f4SStefano Zampini { 901a198735bSStefano Zampini Mat loc_divudotp; 902fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 9038ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 904669cc0f4SStefano Zampini IS *faces,*edges; 905669cc0f4SStefano Zampini PetscScalar *vals; 906669cc0f4SStefano Zampini const PetscScalar *array; 907669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 9081ae86dd6SStefano Zampini PetscMPIInt rank; 909a198735bSStefano Zampini PetscErrorCode ierr; 910669cc0f4SStefano Zampini 911669cc0f4SStefano Zampini PetscFunctionBegin; 912669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 913669cc0f4SStefano Zampini if (graph->twodim) { 914669cc0f4SStefano Zampini lmaxneighs = 2; 915669cc0f4SStefano Zampini } else { 916669cc0f4SStefano Zampini lmaxneighs = 1; 917669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 918669cc0f4SStefano Zampini const PetscInt *idxs; 919669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 920669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 921669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 922669cc0f4SStefano Zampini } 923669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 924669cc0f4SStefano Zampini } 925669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 926669cc0f4SStefano Zampini maxsize = 0; 927669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 928669cc0f4SStefano Zampini PetscInt nn; 929669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 930669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 931669cc0f4SStefano Zampini } 932669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 933669cc0f4SStefano Zampini PetscInt nn; 934669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 935669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 936669cc0f4SStefano Zampini } 937669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 938669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 939669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 9408ae0ca82SStefano Zampini if (!transpose) { 9418ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 9428ae0ca82SStefano Zampini } else { 9438ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 9448ae0ca82SStefano Zampini } 945669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 9461ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 947d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 948669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 9498ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 950669cc0f4SStefano Zampini } 951d8203eabSStefano Zampini 952669cc0f4SStefano Zampini /* compute local quad vec */ 953a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 9548ae0ca82SStefano Zampini if (!transpose) { 955a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 9568ae0ca82SStefano Zampini } else { 9578ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 9588ae0ca82SStefano Zampini } 959669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 9608ae0ca82SStefano Zampini if (!transpose) { 961a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 9628ae0ca82SStefano Zampini } else { 9638ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 9648ae0ca82SStefano Zampini } 965fa23a32eSStefano Zampini if (vl2l) { 966fa23a32eSStefano Zampini ierr = VecGetSubVector(v,vl2l,&vins);CHKERRQ(ierr); 967fa23a32eSStefano Zampini } else { 968fa23a32eSStefano Zampini vins = v; 969fa23a32eSStefano Zampini } 970fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 971669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 9729a962809SStefano Zampini 9731ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 9741ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 975669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 976669cc0f4SStefano Zampini const PetscInt *idxs; 977669cc0f4SStefano Zampini PetscInt idx,nn,j; 978669cc0f4SStefano Zampini 979669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 980669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 981669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 9821ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 983669cc0f4SStefano Zampini idx = -(idx+1); 984669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 985669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 986669cc0f4SStefano Zampini } 987669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 988669cc0f4SStefano Zampini const PetscInt *idxs; 989669cc0f4SStefano Zampini PetscInt idx,nn,j; 990669cc0f4SStefano Zampini 991669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 992669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 993669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 9941ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 995669cc0f4SStefano Zampini idx = -(idx+1); 996669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 997669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 998669cc0f4SStefano Zampini } 999c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1000fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1001fa23a32eSStefano Zampini if (vl2l) { 1002fa23a32eSStefano Zampini ierr = VecRestoreSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1003fa23a32eSStefano Zampini } 1004669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1005669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1006669cc0f4SStefano Zampini 1007669cc0f4SStefano Zampini /* assemble near null space */ 1008669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1009669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1010669cc0f4SStefano Zampini } 1011669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1012669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 1013669cc0f4SStefano Zampini } 1014669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1015669cc0f4SStefano Zampini PetscFunctionReturn(0); 1016669cc0f4SStefano Zampini } 1017669cc0f4SStefano Zampini 1018669cc0f4SStefano Zampini 1019a3df083aSStefano Zampini #undef __FUNCT__ 10201f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 10211f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 10221f4df5f7SStefano Zampini { 10231f4df5f7SStefano Zampini PetscErrorCode ierr; 10241f4df5f7SStefano Zampini Vec local,global; 10251f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 10261f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 10271f4df5f7SStefano Zampini 10281f4df5f7SStefano Zampini PetscFunctionBegin; 10291f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 10301f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 10311f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 10321f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 10331f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 10341f4df5f7SStefano Zampini PetscInt i; 10351f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 10361f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 10371f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 10381f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 10391f4df5f7SStefano Zampini } 10401f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 10411f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 10421f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 10431f4df5f7SStefano Zampini } 10441f4df5f7SStefano Zampini } else { 1045986cdee1SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering if bs > 1 */ 10461f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1047986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 1048986cdee1SStefano Zampini if (i > 1) { 1049986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 10501f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 10511f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 10521f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 10531f4df5f7SStefano Zampini } 10541f4df5f7SStefano Zampini } 10551f4df5f7SStefano Zampini } 1056986cdee1SStefano Zampini } 10571f4df5f7SStefano Zampini 10581f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 10591f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 10601f4df5f7SStefano Zampini } 10611f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 10621f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 10631f4df5f7SStefano Zampini } 10641f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 10651f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 10661f4df5f7SStefano Zampini } 10671f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 10681f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 10691f4df5f7SStefano Zampini PetscFunctionReturn(0); 10701f4df5f7SStefano Zampini } 10711f4df5f7SStefano Zampini 10721f4df5f7SStefano Zampini #undef __FUNCT__ 10733e589ea0SStefano Zampini #define __FUNCT__ "PCBDDCBenignRemoveInterior" 10743e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 10753e589ea0SStefano Zampini { 10763e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 10773e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 10783e589ea0SStefano Zampini PetscErrorCode ierr; 10793e589ea0SStefano Zampini 10803e589ea0SStefano Zampini PetscFunctionBegin; 10813e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 10823e589ea0SStefano Zampini PetscFunctionReturn(0); 10833e589ea0SStefano Zampini } 10843e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 10853e589ea0SStefano Zampini Vec swap; 10863e589ea0SStefano Zampini 10873e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 10883e589ea0SStefano Zampini swap = pcbddc->work_change; 10893e589ea0SStefano Zampini pcbddc->work_change = r; 10903e589ea0SStefano Zampini r = swap; 10913e589ea0SStefano Zampini } 10923e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10933e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 10943e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 10953e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 10963e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10973e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10983e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 10993e589ea0SStefano Zampini Vec swap; 11003e589ea0SStefano Zampini 11013e589ea0SStefano Zampini swap = r; 11023e589ea0SStefano Zampini r = pcbddc->work_change; 11033e589ea0SStefano Zampini pcbddc->work_change = swap; 11043e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 11053e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 11063e589ea0SStefano Zampini } 11073e589ea0SStefano Zampini PetscFunctionReturn(0); 11083e589ea0SStefano Zampini } 11093e589ea0SStefano Zampini 11103e589ea0SStefano Zampini #undef __FUNCT__ 1111a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 1112a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1113a3df083aSStefano Zampini { 1114a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1115a3df083aSStefano Zampini PetscErrorCode ierr; 1116a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1117a3df083aSStefano Zampini 1118a3df083aSStefano Zampini PetscFunctionBegin; 1119a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1120a3df083aSStefano Zampini if (transpose) { 1121a3df083aSStefano Zampini apply_right = ctx->apply_left; 1122a3df083aSStefano Zampini apply_left = ctx->apply_right; 1123a3df083aSStefano Zampini } else { 1124a3df083aSStefano Zampini apply_right = ctx->apply_right; 1125a3df083aSStefano Zampini apply_left = ctx->apply_left; 1126a3df083aSStefano Zampini } 1127a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1128a3df083aSStefano Zampini if (apply_right) { 1129a3df083aSStefano Zampini const PetscScalar *ax; 1130a3df083aSStefano Zampini PetscInt nl,i; 1131a3df083aSStefano Zampini 1132a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1133a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1134a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1135a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);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 sum = 0.; 1143a3df083aSStefano Zampini if (ctx->apply_p0) { 1144a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1145a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1146a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1147a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1148a3df083aSStefano Zampini } 1149a3df083aSStefano Zampini } else { 1150a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1151a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1152a3df083aSStefano Zampini } 1153a3df083aSStefano Zampini } 1154a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1155a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1156a3df083aSStefano Zampini } 1157a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1158a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1159a3df083aSStefano Zampini } 1160a3df083aSStefano Zampini if (transpose) { 1161a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1162a3df083aSStefano Zampini } else { 1163a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1164a3df083aSStefano Zampini } 1165a3df083aSStefano Zampini if (reset_x) { 1166a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1167a3df083aSStefano Zampini } 1168a3df083aSStefano Zampini if (apply_left) { 1169a3df083aSStefano Zampini PetscScalar *ay; 1170a3df083aSStefano Zampini PetscInt i; 1171a3df083aSStefano Zampini 1172a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1173a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1174a3df083aSStefano Zampini PetscScalar sum,val; 1175a3df083aSStefano Zampini const PetscInt *idxs; 1176a3df083aSStefano Zampini PetscInt nz,j; 1177a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1178a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1179a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1180a3df083aSStefano Zampini if (ctx->apply_p0) { 1181a3df083aSStefano Zampini sum = 0.; 1182a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1183a3df083aSStefano Zampini sum += ay[idxs[j]]; 1184a3df083aSStefano Zampini ay[idxs[j]] += val; 1185a3df083aSStefano Zampini } 1186a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1187a3df083aSStefano Zampini } else { 1188a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1189a3df083aSStefano Zampini ay[idxs[j]] += val; 1190a3df083aSStefano Zampini } 1191a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1192a3df083aSStefano Zampini } 1193a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1194a3df083aSStefano Zampini } 1195a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1196a3df083aSStefano Zampini } 1197a3df083aSStefano Zampini PetscFunctionReturn(0); 1198a3df083aSStefano Zampini } 1199a3df083aSStefano Zampini 1200a3df083aSStefano Zampini #undef __FUNCT__ 1201a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 1202a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1203a3df083aSStefano Zampini { 1204a3df083aSStefano Zampini PetscErrorCode ierr; 1205a3df083aSStefano Zampini 1206a3df083aSStefano Zampini PetscFunctionBegin; 1207a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1208a3df083aSStefano Zampini PetscFunctionReturn(0); 1209a3df083aSStefano Zampini } 1210a3df083aSStefano Zampini 1211a3df083aSStefano Zampini #undef __FUNCT__ 1212a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 1213a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1214a3df083aSStefano Zampini { 1215a3df083aSStefano Zampini PetscErrorCode ierr; 1216a3df083aSStefano Zampini 1217a3df083aSStefano Zampini PetscFunctionBegin; 1218a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1219a3df083aSStefano Zampini PetscFunctionReturn(0); 1220a3df083aSStefano Zampini } 1221a3df083aSStefano Zampini 1222a3df083aSStefano Zampini #undef __FUNCT__ 1223a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 1224a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1225a3df083aSStefano Zampini { 1226a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1227a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1228a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1229a3df083aSStefano Zampini PetscErrorCode ierr; 1230a3df083aSStefano Zampini 1231a3df083aSStefano Zampini PetscFunctionBegin; 1232a3df083aSStefano Zampini if (!restore) { 12331dd7afcfSStefano Zampini Mat A_IB,A_BI; 1234a3df083aSStefano Zampini PetscScalar *work; 1235b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1236a3df083aSStefano Zampini 12379a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 12389a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1239a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1240a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1241a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1242a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1243a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1244a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1245a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 1246a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 1247a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 1248a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 1249a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 1250a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 1251059032f7SStefano Zampini if (reuse) { 1252a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 12531dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 1254059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 1255059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 1256059032f7SStefano Zampini PetscInt i; 1257059032f7SStefano Zampini 1258059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 1259059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1260059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1261059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1262059032f7SStefano Zampini } 1263059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 12641dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 1265059032f7SStefano Zampini } 1266a3df083aSStefano Zampini ctx->A = pcis->A_IB; 1267a3df083aSStefano Zampini ctx->work = work; 1268a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 1269a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1270a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1271a3df083aSStefano Zampini pcis->A_IB = A_IB; 1272a3df083aSStefano Zampini 1273a3df083aSStefano Zampini /* A_BI as A_IB^T */ 1274a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 1275a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 1276a3df083aSStefano Zampini pcis->A_BI = A_BI; 1277a3df083aSStefano Zampini } else { 12781dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 12791dd7afcfSStefano Zampini PetscFunctionReturn(0); 12801dd7afcfSStefano Zampini } 1281a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 1282a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1283a3df083aSStefano Zampini pcis->A_IB = ctx->A; 12841dd7afcfSStefano Zampini ctx->A = NULL; 12851dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 12861dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 12871dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 12881dd7afcfSStefano Zampini if (ctx->free) { 1289059032f7SStefano Zampini PetscInt i; 12901dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1291059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1292059032f7SStefano Zampini } 1293059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1294059032f7SStefano Zampini } 1295a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 1296a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 1297a3df083aSStefano Zampini } 1298a3df083aSStefano Zampini PetscFunctionReturn(0); 1299a3df083aSStefano Zampini } 1300a3df083aSStefano Zampini 1301a3df083aSStefano Zampini /* used just in bddc debug mode */ 1302a3df083aSStefano Zampini #undef __FUNCT__ 1303a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 1304a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 1305a3df083aSStefano Zampini { 1306a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1307a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1308a3df083aSStefano Zampini Mat An; 1309a3df083aSStefano Zampini PetscErrorCode ierr; 1310a3df083aSStefano Zampini 1311a3df083aSStefano Zampini PetscFunctionBegin; 1312a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 1313a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 1314a3df083aSStefano Zampini if (is1) { 1315a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 1316a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 1317a3df083aSStefano Zampini } else { 1318a3df083aSStefano Zampini *B = An; 1319a3df083aSStefano Zampini } 1320a3df083aSStefano Zampini PetscFunctionReturn(0); 1321a3df083aSStefano Zampini } 1322a3df083aSStefano Zampini 13231cf9b237SStefano Zampini /* TODO: add reuse flag */ 13241cf9b237SStefano Zampini #undef __FUNCT__ 13251cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 13261cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 13271cf9b237SStefano Zampini { 13281cf9b237SStefano Zampini Mat Bt; 13291cf9b237SStefano Zampini PetscScalar *a,*bdata; 13301cf9b237SStefano Zampini const PetscInt *ii,*ij; 13311cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 13321cf9b237SStefano Zampini PetscBool flg_row; 13331cf9b237SStefano Zampini PetscErrorCode ierr; 13341cf9b237SStefano Zampini 13351cf9b237SStefano Zampini PetscFunctionBegin; 13361cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 13371cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 13381cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 13391cf9b237SStefano Zampini nnz = n; 13401cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 13411cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 13421cf9b237SStefano Zampini } 13431cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 13441cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 13451cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 13461cf9b237SStefano Zampini nnz = 0; 13471cf9b237SStefano Zampini bii[0] = 0; 13481cf9b237SStefano Zampini for (i=0;i<n;i++) { 13491cf9b237SStefano Zampini PetscInt j; 13501cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 13511cf9b237SStefano Zampini PetscScalar entry = a[j]; 13521cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 13531cf9b237SStefano Zampini bij[nnz] = ij[j]; 13541cf9b237SStefano Zampini bdata[nnz] = entry; 13551cf9b237SStefano Zampini nnz++; 13561cf9b237SStefano Zampini } 13571cf9b237SStefano Zampini } 13581cf9b237SStefano Zampini bii[i+1] = nnz; 13591cf9b237SStefano Zampini } 13601cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 13611cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 13621cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 13631cf9b237SStefano Zampini { 13641cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 13651cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 13661cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 13671cf9b237SStefano Zampini } 13681cf9b237SStefano Zampini *B = Bt; 13691cf9b237SStefano Zampini PetscFunctionReturn(0); 13701cf9b237SStefano Zampini } 13711cf9b237SStefano Zampini 1372674ae819SStefano Zampini #undef __FUNCT__ 13734f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 13744f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 13754f1b2e48SStefano Zampini { 13764f1b2e48SStefano Zampini Mat B; 13774f1b2e48SStefano Zampini IS is_dummy,*cc_n; 13784f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 13794f1b2e48SStefano Zampini PCBDDCGraph graph; 13804f1b2e48SStefano Zampini PetscInt i,n; 13814f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 13824f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 13834f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 13844f1b2e48SStefano Zampini PetscErrorCode ierr; 13854f1b2e48SStefano Zampini 13864f1b2e48SStefano Zampini PetscFunctionBegin; 138763c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 138863c961adSStefano Zampini *ncc = 0; 138963c961adSStefano Zampini *cc = NULL; 139063c961adSStefano Zampini PetscFunctionReturn(0); 139163c961adSStefano Zampini } 13924f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 13934f1b2e48SStefano Zampini if (!isseqaij && filter) { 13941cf9b237SStefano Zampini PetscBool isseqdense; 13951cf9b237SStefano Zampini 13961cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 13971cf9b237SStefano Zampini if (!isseqdense) { 13984f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 13991cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 14001cf9b237SStefano Zampini PetscScalar *array; 14011cf9b237SStefano Zampini PetscReal chop=1.e-6; 14021cf9b237SStefano Zampini 14031cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 14041cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 14051cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 14061cf9b237SStefano Zampini for (i=0;i<n;i++) { 14071cf9b237SStefano Zampini PetscInt j; 14081cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 14091cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 14101cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 14111cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 14121cf9b237SStefano Zampini } 14131cf9b237SStefano Zampini } 14141cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 14159d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 14161cf9b237SStefano Zampini } 14174f1b2e48SStefano Zampini } else { 14184f1b2e48SStefano Zampini B = A; 14194f1b2e48SStefano Zampini } 14204f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 14214f1b2e48SStefano Zampini 14224f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 14234f1b2e48SStefano Zampini if (filter) { 14244f1b2e48SStefano Zampini PetscScalar *data; 14254f1b2e48SStefano Zampini PetscInt j,cum; 14264f1b2e48SStefano Zampini 14274f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 14284f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 14294f1b2e48SStefano Zampini cum = 0; 14304f1b2e48SStefano Zampini for (i=0;i<n;i++) { 14314f1b2e48SStefano Zampini PetscInt t; 14324f1b2e48SStefano Zampini 14334f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 14344f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 14354f1b2e48SStefano Zampini continue; 14364f1b2e48SStefano Zampini } 14374f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 14384f1b2e48SStefano Zampini } 14394f1b2e48SStefano Zampini t = xadj_filtered[i]; 14404f1b2e48SStefano Zampini xadj_filtered[i] = cum; 14414f1b2e48SStefano Zampini cum += t; 14424f1b2e48SStefano Zampini } 14434f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 14444f1b2e48SStefano Zampini } else { 14454f1b2e48SStefano Zampini xadj_filtered = NULL; 14464f1b2e48SStefano Zampini adjncy_filtered = NULL; 14474f1b2e48SStefano Zampini } 14484f1b2e48SStefano Zampini 14494f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 14504f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 14514f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 14524f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 14534f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 1454be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 14554f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 14564f1b2e48SStefano Zampini if (xadj_filtered) { 14574f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 14584f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 14594f1b2e48SStefano Zampini } else { 14604f1b2e48SStefano Zampini graph->xadj = xadj; 14614f1b2e48SStefano Zampini graph->adjncy = adjncy; 14624f1b2e48SStefano Zampini } 14634f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 14644f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 14654f1b2e48SStefano Zampini /* partial clean up */ 14664f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 14674f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 14681cf9b237SStefano Zampini if (A != B) { 14694f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 14704f1b2e48SStefano Zampini } 14714f1b2e48SStefano Zampini 14724f1b2e48SStefano Zampini /* get back data */ 14731cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 14741cf9b237SStefano Zampini if (cc) { 14754f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 14764f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 14774f1b2e48SStefano 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); 14784f1b2e48SStefano Zampini } 14794f1b2e48SStefano Zampini *cc = cc_n; 14801cf9b237SStefano Zampini } 14814f1b2e48SStefano Zampini /* clean up graph */ 14824f1b2e48SStefano Zampini graph->xadj = 0; 14834f1b2e48SStefano Zampini graph->adjncy = 0; 14844f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 14854f1b2e48SStefano Zampini PetscFunctionReturn(0); 14864f1b2e48SStefano Zampini } 14874f1b2e48SStefano Zampini 14884f1b2e48SStefano Zampini #undef __FUNCT__ 14895408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 14905408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 14915408967cSStefano Zampini { 14925408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 14935408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1494dee84bffSStefano Zampini IS dirIS = NULL; 14954f1b2e48SStefano Zampini PetscInt i; 14965408967cSStefano Zampini PetscErrorCode ierr; 14975408967cSStefano Zampini 14985408967cSStefano Zampini PetscFunctionBegin; 1499dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 15005408967cSStefano Zampini if (zerodiag) { 15015408967cSStefano Zampini Mat A; 15025408967cSStefano Zampini Vec vec3_N; 15035408967cSStefano Zampini PetscScalar *vals; 15045408967cSStefano Zampini const PetscInt *idxs; 1505d12d3064SStefano Zampini PetscInt nz,*count; 15065408967cSStefano Zampini 15075408967cSStefano Zampini /* p0 */ 15085408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 15095408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 15105408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 15115408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 15124f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 15135408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 15145408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 15155408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 15165408967cSStefano Zampini /* v_I */ 15175408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 15185408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 15195408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 15205408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 15215408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 15225408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 15235408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 15245408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 15255408967cSStefano Zampini if (dirIS) { 15265408967cSStefano Zampini PetscInt n; 15275408967cSStefano Zampini 15285408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 15295408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 15305408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 15315408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 15325408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 15335408967cSStefano Zampini } 15345408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 15355408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 15365408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 15375408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 1538669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 15395408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 15405408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 15419a962809SStefano 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])); 15425408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 15435408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 1544d12d3064SStefano Zampini 1545d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 1546d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 1547d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 1548d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 1549d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 1550d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 15519a962809SStefano 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]); 1552d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 1553d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 15545408967cSStefano Zampini } 1555dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 15565408967cSStefano Zampini 15575408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 15585408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 15594f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 15605408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 15614f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 15625408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 1563f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1564f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 1565f2a566d8SStefano 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); 1566f2a566d8SStefano Zampini } 15675408967cSStefano Zampini PetscFunctionReturn(0); 15685408967cSStefano Zampini } 15695408967cSStefano Zampini 15705408967cSStefano Zampini #undef __FUNCT__ 1571339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 1572339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 1573339f8db1SStefano Zampini { 1574339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 15754f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 1576b0f5fe93SStefano Zampini PetscInt nz,n; 15771f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 15784f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 1579339f8db1SStefano Zampini PetscErrorCode ierr; 1580339f8db1SStefano Zampini 1581339f8db1SStefano Zampini PetscFunctionBegin; 15829f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 15839f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 1584a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 1585a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 1586a3df083aSStefano Zampini } 1587a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1588a3df083aSStefano Zampini pcbddc->benign_n = 0; 15891ae86dd6SStefano Zampini /* if a local info on dofs is present, assumes that the last field represents "pressures" 15904f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 15914f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 15924f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 15931ae86dd6SStefano Zampini since the local Schur complements are already SPD 15944f1b2e48SStefano Zampini */ 15954f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 15964f1b2e48SStefano Zampini have_null = PETSC_TRUE; 159740fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 15984f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 15994f1b2e48SStefano Zampini 16004f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 16014f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 16024f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 16034f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 1604ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 160540fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 160640fa8d13SStefano Zampini if (!sorted) { 160740fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 160840fa8d13SStefano Zampini } 160940fa8d13SStefano Zampini } else { 161040fa8d13SStefano Zampini pressures = NULL; 161140fa8d13SStefano Zampini } 161297d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 161397d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 161427b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 161597d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 1616339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 1617339f8db1SStefano Zampini if (!sorted) { 1618339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 1619339f8db1SStefano Zampini } 1620339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 16214f1b2e48SStefano Zampini if (!nz) { 16224f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 16234f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 162440fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 162540fa8d13SStefano Zampini } 16264f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 16274f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 16284f1b2e48SStefano Zampini zerodiag_subs = NULL; 16294f1b2e48SStefano Zampini pcbddc->benign_n = 0; 16301f4df5f7SStefano Zampini n_interior_dofs = 0; 16311f4df5f7SStefano Zampini interior_dofs = NULL; 16321f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 16331f4df5f7SStefano Zampini PetscInt n,i,j; 16341f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 16351f4df5f7SStefano Zampini PetscInt *iwork; 16361f4df5f7SStefano Zampini 16371f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 16381f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 16391f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 16401f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 164190648384SStefano Zampini for (i=1;i<n_neigh;i++) 16421f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 16431f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 16441f4df5f7SStefano Zampini for (i=0;i<n;i++) 16451f4df5f7SStefano Zampini if (!iwork[i]) 16461f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 16471f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 16481f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 16491f4df5f7SStefano Zampini } 16504f1b2e48SStefano Zampini if (has_null_pressures) { 16514f1b2e48SStefano Zampini IS *subs; 16521f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 16531f4df5f7SStefano Zampini const PetscInt *idxs; 16541f4df5f7SStefano Zampini PetscScalar *array; 16551f4df5f7SStefano Zampini Vec *work; 16561f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 16574f1b2e48SStefano Zampini 16584f1b2e48SStefano Zampini subs = pcbddc->local_subs; 16594f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 16601f4df5f7SStefano 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) */ 16611f4df5f7SStefano Zampini if (pcbddc->current_level) { 16621f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 16631f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 16641f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 16651f4df5f7SStefano Zampini /* work[0] = 1_p */ 16661f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 16671f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 16681f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 16691f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 16701f4df5f7SStefano Zampini /* work[0] = 1_v */ 16711f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 16721f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 16731f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 16741f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 16751f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 16761f4df5f7SStefano Zampini } 16774f1b2e48SStefano Zampini if (nsubs > 1) { 16784f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 16794f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 16804f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 16814f1b2e48SStefano Zampini IS t_zerodiag_subs; 16824f1b2e48SStefano Zampini PetscInt nl; 16834f1b2e48SStefano Zampini 16844f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 16854f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 16864f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 16874f1b2e48SStefano Zampini if (nl) { 16884f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 16894f1b2e48SStefano Zampini 16901f4df5f7SStefano Zampini if (pcbddc->current_level) { 16911f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 16921f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 16931f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 16941f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 16951f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 16961f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 16971f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 16981f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 16991f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 17001f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 17011f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 17021f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 17031f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 17041f4df5f7SStefano Zampini valid = PETSC_FALSE; 17051f4df5f7SStefano Zampini break; 17061f4df5f7SStefano Zampini } 17071f4df5f7SStefano Zampini } 17081f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 17091f4df5f7SStefano Zampini } 17101f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 17111f4df5f7SStefano Zampini IS t_bc; 17121f4df5f7SStefano Zampini PetscInt nzb; 17131f4df5f7SStefano Zampini 17141f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 17151f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 17161f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 17171f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 17181f4df5f7SStefano Zampini } 17191f4df5f7SStefano Zampini if (valid && pressures) { 17204f1b2e48SStefano Zampini IS t_pressure_subs; 17214f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 17224f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 17234f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 17244f1b2e48SStefano Zampini } 17254f1b2e48SStefano Zampini if (valid) { 17264f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 17274f1b2e48SStefano Zampini pcbddc->benign_n++; 17284f1b2e48SStefano Zampini } else { 17294f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 17304f1b2e48SStefano Zampini } 17314f1b2e48SStefano Zampini } 17324f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 17334f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 17344f1b2e48SStefano Zampini } 17354f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 17364f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 17371f4df5f7SStefano Zampini 17381f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 17391f4df5f7SStefano Zampini PetscInt nzb; 17401f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 17411f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 17421f4df5f7SStefano Zampini } 17431f4df5f7SStefano Zampini if (valid && pressures) { 17444f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 17454f1b2e48SStefano Zampini } 17461f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 17471f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 17481f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 17491f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 17501f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 17511f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 17521f4df5f7SStefano Zampini valid = PETSC_FALSE; 17531f4df5f7SStefano Zampini break; 17541f4df5f7SStefano Zampini } 17551f4df5f7SStefano Zampini } 17561f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 17571f4df5f7SStefano Zampini } 17584f1b2e48SStefano Zampini if (valid) { 17594f1b2e48SStefano Zampini pcbddc->benign_n = 1; 1760ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 17614f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 17624f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 17634f1b2e48SStefano Zampini } 17644f1b2e48SStefano Zampini } 17651f4df5f7SStefano Zampini if (pcbddc->current_level) { 17661f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 17674f1b2e48SStefano Zampini } 17681f4df5f7SStefano Zampini } 17691f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 17704f1b2e48SStefano Zampini 17714f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 1772b9b0e38cSStefano Zampini PetscInt n; 1773b9b0e38cSStefano Zampini 17744f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 17754f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 1776b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 1777b9b0e38cSStefano Zampini if (n) { 17784f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 17794f1b2e48SStefano Zampini have_null = PETSC_FALSE; 17804f1b2e48SStefano Zampini } 1781b9b0e38cSStefano Zampini } 17824f1b2e48SStefano Zampini 17834f1b2e48SStefano Zampini /* final check for null pressures */ 17844f1b2e48SStefano Zampini if (zerodiag && pressures) { 17854f1b2e48SStefano Zampini PetscInt nz,np; 17864f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 17874f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 17884f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 17894f1b2e48SStefano Zampini } 17904f1b2e48SStefano Zampini 17914f1b2e48SStefano Zampini if (recompute_zerodiag) { 17924f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 17934f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 17944f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 17954f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 17964f1b2e48SStefano Zampini } else { 17974f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 17984f1b2e48SStefano Zampini 17994f1b2e48SStefano Zampini nzn = 0; 18004f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 18014f1b2e48SStefano Zampini PetscInt ns; 18024f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 18034f1b2e48SStefano Zampini nzn += ns; 18044f1b2e48SStefano Zampini } 18054f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 18064f1b2e48SStefano Zampini nzn = 0; 18074f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 18084f1b2e48SStefano Zampini PetscInt ns,*idxs; 18094f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 18104f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 18114f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 18124f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 18134f1b2e48SStefano Zampini nzn += ns; 18144f1b2e48SStefano Zampini } 18154f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 18164f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 18174f1b2e48SStefano Zampini } 18184f1b2e48SStefano Zampini have_null = PETSC_FALSE; 18194f1b2e48SStefano Zampini } 18204f1b2e48SStefano Zampini 1821669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 1822a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 1823a198735bSStefano Zampini Mat A,loc_divudotp; 1824a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 1825a198735bSStefano Zampini IS row,col,isused = NULL; 1826a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 1827a198735bSStefano Zampini 18281f4df5f7SStefano Zampini if (pressures) { 18291f4df5f7SStefano Zampini isused = pressures; 18301f4df5f7SStefano Zampini } else { 18311f4df5f7SStefano Zampini isused = zerodiag; 18321f4df5f7SStefano Zampini } 1833a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 1834669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 18351ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 18361ae86dd6SStefano 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"); 1837a198735bSStefano Zampini n_isused = 0; 1838a198735bSStefano Zampini if (isused) { 1839a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 1840a198735bSStefano Zampini } 1841a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1842a198735bSStefano Zampini st = st-n_isused; 18431ae86dd6SStefano Zampini if (n) { 1844a198735bSStefano Zampini const PetscInt *gidxs; 1845a198735bSStefano Zampini 1846a198735bSStefano Zampini ierr = MatGetSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 1847a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 1848a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 1849a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 1850a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 1851a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 18521ae86dd6SStefano Zampini } else { 1853a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 1854a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 1855a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 1856a198735bSStefano Zampini } 1857a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 1858a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 1859a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 1860a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 1861a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 1862a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 1863a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 1864a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 1865a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 1866a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 1867a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 1868a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 1869a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 1870a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 18711ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18721ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18731ae86dd6SStefano Zampini } 1874b3afcdbeSStefano Zampini 1875b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 18764f1b2e48SStefano Zampini if (has_null_pressures) { 18774f1b2e48SStefano Zampini IS zerodiagc; 18784f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 18794f1b2e48SStefano Zampini PetscInt i,s,*nnz; 18804f1b2e48SStefano Zampini 18814f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 1882339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 1883339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 1884339f8db1SStefano Zampini /* local change of basis for pressures */ 1885339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 188697d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 1887339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 1888339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1889339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 18904f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 18914f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 18924f1b2e48SStefano Zampini PetscInt nzs,j; 18934f1b2e48SStefano Zampini 18944f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 18954f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 18964f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 18974f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 18984f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 18994f1b2e48SStefano Zampini } 1900339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 1901339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 1902339f8db1SStefano Zampini /* set identity on velocities */ 1903339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 1904339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 1905339f8db1SStefano Zampini } 19064f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 19074f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 19089f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 19094f1b2e48SStefano 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); 1910339f8db1SStefano Zampini /* set change on pressures */ 19114f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 19124f1b2e48SStefano Zampini PetscScalar *array; 19134f1b2e48SStefano Zampini PetscInt nzs; 19144f1b2e48SStefano Zampini 19154f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 19164f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 19174f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 1918339f8db1SStefano Zampini PetscScalar vals[2]; 1919339f8db1SStefano Zampini PetscInt cols[2]; 1920339f8db1SStefano Zampini 1921339f8db1SStefano Zampini cols[0] = idxs[i]; 19224f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 1923339f8db1SStefano Zampini vals[0] = 1.; 1924b0f5fe93SStefano Zampini vals[1] = 1.; 19254f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 1926339f8db1SStefano Zampini } 19274f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 19284f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 19294f1b2e48SStefano Zampini array[nzs-1] = 1.; 19304f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 19314f1b2e48SStefano Zampini /* store local idxs for p0 */ 19324f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 19334f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 1934339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 19354f1b2e48SStefano Zampini } 1936339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1937339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1938a3df083aSStefano Zampini /* project if needed */ 1939a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 19401dd7afcfSStefano Zampini Mat M; 19411dd7afcfSStefano Zampini 19421dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 1943339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 19441dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 19451dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 1946a3df083aSStefano Zampini } 19474f1b2e48SStefano Zampini /* store global idxs for p0 */ 19484f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1949339f8db1SStefano Zampini } 1950ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 19514f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 1952b0f5fe93SStefano Zampini 1953b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 1954b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 195527b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 195627b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1957339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 1958339f8db1SStefano Zampini PetscFunctionReturn(0); 1959339f8db1SStefano Zampini } 1960339f8db1SStefano Zampini 1961339f8db1SStefano Zampini #undef __FUNCT__ 1962015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 1963015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 1964efc2fbd9SStefano Zampini { 1965efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1966de9d7bd0SStefano Zampini PetscScalar *array; 1967efc2fbd9SStefano Zampini PetscErrorCode ierr; 1968efc2fbd9SStefano Zampini 1969efc2fbd9SStefano Zampini PetscFunctionBegin; 1970efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 1971efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 19724f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 1973efc2fbd9SStefano Zampini } 1974de9d7bd0SStefano Zampini if (get) { 1975efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 19764f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 19774f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 1978efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 1979de9d7bd0SStefano Zampini } else { 1980de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 1981de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1982de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 1983de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 1984efc2fbd9SStefano Zampini } 1985efc2fbd9SStefano Zampini PetscFunctionReturn(0); 1986efc2fbd9SStefano Zampini } 1987efc2fbd9SStefano Zampini 1988efc2fbd9SStefano Zampini #undef __FUNCT__ 1989c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 1990c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 1991c263805aSStefano Zampini { 1992c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1993c263805aSStefano Zampini PetscErrorCode ierr; 1994c263805aSStefano Zampini 1995c263805aSStefano Zampini PetscFunctionBegin; 1996c263805aSStefano Zampini /* TODO: add error checking 1997c263805aSStefano Zampini - avoid nested pop (or push) calls. 1998c263805aSStefano Zampini - cannot push before pop. 19991c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2000c263805aSStefano Zampini */ 20014f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2002efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2003efc2fbd9SStefano Zampini } 2004c263805aSStefano Zampini if (pop) { 2005a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 20064f1b2e48SStefano Zampini IS is_p0; 20074f1b2e48SStefano Zampini MatReuse reuse; 2008c263805aSStefano Zampini 2009c263805aSStefano Zampini /* extract B_0 */ 20104f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 20114f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 20124f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 20134f1b2e48SStefano Zampini } 20144f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 20154f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2016c263805aSStefano Zampini /* remove rows and cols from local problem */ 2017c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 201897d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 20194f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 20204f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2021a3df083aSStefano Zampini } else { 2022a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2023a3df083aSStefano Zampini PetscScalar *vals; 2024a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2025a3df083aSStefano Zampini 2026a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2027a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2028a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 20290b5adadeSStefano Zampini PetscInt *nnz; 2030a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2031a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2032a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2033331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2034331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2035331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2036331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2037331e053bSStefano Zampini } 2038331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2039331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2040331e053bSStefano Zampini } 2041a3df083aSStefano Zampini 2042a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2043a3df083aSStefano Zampini PetscScalar *array; 2044a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2045a3df083aSStefano Zampini 2046a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2047a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2048a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2049a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2050a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2051a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2052a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2053a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2054a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2055a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2056a3df083aSStefano Zampini cum = 0; 2057a3df083aSStefano Zampini for (j=0;j<n;j++) { 205822db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2059a3df083aSStefano Zampini vals[cum] = array[j]; 2060a3df083aSStefano Zampini idxs_ins[cum] = j; 2061a3df083aSStefano Zampini cum++; 2062a3df083aSStefano Zampini } 2063a3df083aSStefano Zampini } 2064a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2065a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2066a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2067a3df083aSStefano Zampini } 2068a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2069a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2070a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2071a3df083aSStefano Zampini } 2072c263805aSStefano Zampini } else { /* push */ 2073a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 20744f1b2e48SStefano Zampini PetscInt i; 20754f1b2e48SStefano Zampini 20764f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 20774f1b2e48SStefano Zampini PetscScalar *B0_vals; 20784f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 20794f1b2e48SStefano Zampini 20804f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 20814f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 20827b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 20834f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 20844f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 20854f1b2e48SStefano Zampini } 2086c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2087c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2088a3df083aSStefano Zampini } else { 2089a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2090a3df083aSStefano Zampini } 2091c263805aSStefano Zampini } 2092c263805aSStefano Zampini PetscFunctionReturn(0); 2093c263805aSStefano Zampini } 2094c263805aSStefano Zampini 2095c263805aSStefano Zampini #undef __FUNCT__ 2096b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 209708122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2098b1b3d7a2SStefano Zampini { 2099b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 210008122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 210108122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 210208122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 210308122e43SStefano Zampini PetscScalar *work,lwork; 210408122e43SStefano Zampini PetscScalar *St,*S,*eigv; 210508122e43SStefano Zampini PetscScalar *Sarray,*Starray; 210608122e43SStefano Zampini PetscReal *eigs,thresh; 21071b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2108f6f667cfSStefano Zampini PetscBool allocated_S_St; 210908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 211008122e43SStefano Zampini PetscReal *rwork; 211108122e43SStefano Zampini #endif 2112b1b3d7a2SStefano Zampini PetscErrorCode ierr; 2113b1b3d7a2SStefano Zampini 2114b1b3d7a2SStefano Zampini PetscFunctionBegin; 2115b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 2116af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 2117af25d912SStefano 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); 211806a4e24aSStefano Zampini 2119fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2120fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2121fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2122fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 21231575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2124fd14bc51SStefano Zampini } 2125fd14bc51SStefano Zampini 2126e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 2127e496cd5dSStefano 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); 2128e496cd5dSStefano Zampini } 2129e496cd5dSStefano Zampini 213008122e43SStefano Zampini /* max size of subsets */ 213108122e43SStefano Zampini mss = 0; 213208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 213308122e43SStefano Zampini PetscInt subset_size; 2134862806e4SStefano Zampini 213508122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 213608122e43SStefano Zampini mss = PetscMax(mss,subset_size); 213708122e43SStefano Zampini } 213808122e43SStefano Zampini 213908122e43SStefano Zampini /* min/max and threshold */ 214008122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 2141f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 214208122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 2143f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 2144f6f667cfSStefano Zampini if (nmin) { 2145f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 2146f6f667cfSStefano Zampini } 214708122e43SStefano Zampini 214808122e43SStefano Zampini /* allocate lapack workspace */ 214908122e43SStefano Zampini cum = cum2 = 0; 215008122e43SStefano Zampini maxneigs = 0; 215108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 215208122e43SStefano Zampini PetscInt n,subset_size; 2153f6f667cfSStefano Zampini 215408122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 215508122e43SStefano Zampini n = PetscMin(subset_size,nmax); 21569162d606SStefano Zampini cum += subset_size; 21579162d606SStefano Zampini cum2 += subset_size*n; 215808122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 215908122e43SStefano Zampini } 216008122e43SStefano Zampini if (mss) { 21619ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 216208122e43SStefano Zampini PetscBLASInt B_itype = 1; 216308122e43SStefano Zampini PetscBLASInt B_N = mss; 21644c6709b3SStefano Zampini PetscReal zero = 0.0; 21654c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 216608122e43SStefano Zampini 216708122e43SStefano Zampini B_lwork = -1; 216808122e43SStefano Zampini S = NULL; 216908122e43SStefano Zampini St = NULL; 2170a58a30b4SStefano Zampini eigs = NULL; 2171a58a30b4SStefano Zampini eigv = NULL; 2172a58a30b4SStefano Zampini B_iwork = NULL; 2173a58a30b4SStefano Zampini B_ifail = NULL; 2174d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2175d1710679SStefano Zampini rwork = NULL; 2176d1710679SStefano Zampini #endif 21778bec7fa6SStefano Zampini thresh = 1.0; 217808122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 217908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 218008122e43SStefano 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)); 218108122e43SStefano Zampini #else 218208122e43SStefano 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)); 218308122e43SStefano Zampini #endif 218408122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 218508122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 218608122e43SStefano Zampini } else { 218708122e43SStefano Zampini /* TODO */ 218808122e43SStefano Zampini } 218908122e43SStefano Zampini } else { 219008122e43SStefano Zampini lwork = 0; 219108122e43SStefano Zampini } 219208122e43SStefano Zampini 219308122e43SStefano Zampini nv = 0; 2194d62866d3SStefano 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) */ 2195d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 219608122e43SStefano Zampini } 21974c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 2198f6f667cfSStefano Zampini if (allocated_S_St) { 2199f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 2200f6f667cfSStefano Zampini } 2201f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 220208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 220308122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 220408122e43SStefano Zampini #endif 22059162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 22069162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 22079162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 220808122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 22099162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 221008122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 221108122e43SStefano Zampini 221208122e43SStefano Zampini maxneigs = 0; 221372b8c272SStefano Zampini cum = cumarray = 0; 22149162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 22159162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 2216d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 221708122e43SStefano Zampini const PetscInt *idxs; 221808122e43SStefano Zampini 2219d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 222008122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 222108122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 222208122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 222308122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 22249162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 22259162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 222608122e43SStefano Zampini } 2227d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 222808122e43SStefano Zampini } 222908122e43SStefano Zampini 223008122e43SStefano Zampini if (mss) { /* multilevel */ 223108122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 223208122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 223308122e43SStefano Zampini } 223408122e43SStefano Zampini 2235ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 223608122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 223708122e43SStefano Zampini const PetscInt *idxs; 22389d54b7f4SStefano Zampini PetscReal upper,lower; 2239862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 224008122e43SStefano Zampini PetscBLASInt B_N; 2241aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 224208122e43SStefano Zampini 22439d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 22449d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 22459d54b7f4SStefano Zampini lower = thresh; 22469d54b7f4SStefano Zampini } else { 22479d54b7f4SStefano Zampini upper = 1./thresh; 22489d54b7f4SStefano Zampini lower = 0.; 22499d54b7f4SStefano Zampini } 2250862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 2251ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 2252f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 2253f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 22549ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 2255aff50787SStefano Zampini PetscInt j,k; 2256aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 2257aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 2258aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 225908122e43SStefano Zampini } 226008122e43SStefano Zampini for (j=0;j<subset_size;j++) { 2261aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 2262aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 2263aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 2264aff50787SStefano Zampini } 226508122e43SStefano Zampini } 226608122e43SStefano Zampini } else { 226708122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 226808122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 226908122e43SStefano Zampini } 22708bec7fa6SStefano Zampini } else { 2271f6f667cfSStefano Zampini S = Sarray + cumarray; 2272f6f667cfSStefano Zampini St = Starray + cumarray; 22738bec7fa6SStefano Zampini } 2274aff50787SStefano Zampini /* see if we can save some work */ 2275b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 2276aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 2277aff50787SStefano Zampini } 2278aff50787SStefano Zampini 2279b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 2280aff50787SStefano Zampini B_neigs = 0; 2281aff50787SStefano Zampini } else { 22829ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 228308122e43SStefano Zampini PetscBLASInt B_itype = 1; 2284f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 22854c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 22869552c7c7SStefano Zampini PetscInt nmin_s; 2287b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 228808122e43SStefano Zampini 2289fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 22908bec7fa6SStefano 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]]); 2291fd14bc51SStefano Zampini } 2292d16cbb6bSStefano Zampini 2293b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 2294b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 2295b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 2296b7ab4a40SStefano Zampini } 2297b7ab4a40SStefano Zampini 229808122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2299b7ab4a40SStefano Zampini if (compute_range) { 2300d16cbb6bSStefano Zampini 2301d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 230208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 23039d54b7f4SStefano 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)); 230408122e43SStefano Zampini #else 23059d54b7f4SStefano 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)); 230608122e43SStefano Zampini #endif 2307b7ab4a40SStefano Zampini } else if (!same_data) { 2308d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 2309d16cbb6bSStefano Zampini B_IL = 1; 2310d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 23119d54b7f4SStefano 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)); 2312d16cbb6bSStefano Zampini #else 23139d54b7f4SStefano 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)); 2314d16cbb6bSStefano Zampini #endif 2315b7ab4a40SStefano Zampini } else { /* same_data is true, so get the adaptive function requested by the user */ 2316b7ab4a40SStefano Zampini PetscInt k; 2317b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 2318b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 2319b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 2320b7ab4a40SStefano Zampini nmin = nmax; 2321b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 2322b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 2323b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 2324b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 2325b7ab4a40SStefano Zampini } 2326d16cbb6bSStefano Zampini } 232708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 232808122e43SStefano Zampini if (B_ierr) { 23296c4ed002SBarry 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); 23306c4ed002SBarry 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); 23316c4ed002SBarry 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); 233208122e43SStefano Zampini } 233308122e43SStefano Zampini 233408122e43SStefano Zampini if (B_neigs > nmax) { 2335fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2336fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 2337fd14bc51SStefano Zampini } 23389d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 233908122e43SStefano Zampini B_neigs = nmax; 234008122e43SStefano Zampini } 234108122e43SStefano Zampini 23429552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 23439552c7c7SStefano Zampini if (B_neigs < nmin_s) { 234408122e43SStefano Zampini PetscBLASInt B_neigs2; 234508122e43SStefano Zampini 23469d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2347f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 23489d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 23499d54b7f4SStefano Zampini } else { 23509d54b7f4SStefano Zampini B_IL = B_neigs + 1; 23519d54b7f4SStefano Zampini B_IU = nmin_s; 23529d54b7f4SStefano Zampini } 2353fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2354fd14bc51SStefano 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); 2355fd14bc51SStefano Zampini } 23569ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 23571ae86dd6SStefano Zampini PetscInt j,k; 235808122e43SStefano Zampini for (j=0;j<subset_size;j++) { 23591ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 23601ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 23611ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 236208122e43SStefano Zampini } 236308122e43SStefano Zampini } 236408122e43SStefano Zampini } else { 236508122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 236608122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 236708122e43SStefano Zampini } 236808122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 236908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 23709d54b7f4SStefano 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)); 237108122e43SStefano Zampini #else 23729d54b7f4SStefano 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)); 237308122e43SStefano Zampini #endif 237408122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 237508122e43SStefano Zampini B_neigs += B_neigs2; 237608122e43SStefano Zampini } 237708122e43SStefano Zampini if (B_ierr) { 23786c4ed002SBarry 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); 23796c4ed002SBarry 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); 23806c4ed002SBarry 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); 238108122e43SStefano Zampini } 2382fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2383ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 238408122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 238508122e43SStefano Zampini if (eigs[j] == 0.0) { 2386ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 238708122e43SStefano Zampini } else { 23889d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2389ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 23909d54b7f4SStefano Zampini } else { 23919d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 23929d54b7f4SStefano Zampini } 2393fd14bc51SStefano Zampini } 239408122e43SStefano Zampini } 239508122e43SStefano Zampini } 239608122e43SStefano Zampini } else { 239708122e43SStefano Zampini /* TODO */ 239808122e43SStefano Zampini } 2399aff50787SStefano Zampini } 24006c3e6151SStefano Zampini /* change the basis back to the original one */ 24016c3e6151SStefano Zampini if (sub_schurs->change) { 240272b8c272SStefano Zampini Mat change,phi,phit; 24036c3e6151SStefano Zampini 24046c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 24056c3e6151SStefano Zampini PetscInt ii; 24066c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 24076c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 24086c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 2409684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2410684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 2411684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 2412684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2413684229deSStefano Zampini #else 24146c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 2415684229deSStefano Zampini #endif 24166c3e6151SStefano Zampini } 24176c3e6151SStefano Zampini } 24186c3e6151SStefano Zampini } 241972b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 24206c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 242172b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 24226c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 24236c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 24246c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 24256c3e6151SStefano Zampini } 24268bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 24278bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 24289162d606SStefano Zampini if (B_neigs) { 24299162d606SStefano 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); 2430fd14bc51SStefano Zampini 2431fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 24329552c7c7SStefano Zampini PetscInt ii; 24339552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 2434ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 24359552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 2436ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2437ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2438ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2439ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2440ac47001eSStefano Zampini #else 2441ac47001eSStefano 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); 2442ac47001eSStefano Zampini #endif 24439552c7c7SStefano Zampini } 24449552c7c7SStefano Zampini } 2445fd14bc51SStefano Zampini } 24469162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 24479162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 24489162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 24499162d606SStefano Zampini cum++; 245008122e43SStefano Zampini } 245108122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 245208122e43SStefano Zampini /* shift for next computation */ 245308122e43SStefano Zampini cumarray += subset_size*subset_size; 245408122e43SStefano Zampini } 2455fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2456fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2457fd14bc51SStefano Zampini } 245808122e43SStefano Zampini 245908122e43SStefano Zampini if (mss) { 246008122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 246108122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 2462f6f667cfSStefano Zampini /* destroy matrices (junk) */ 2463f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 2464f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 246508122e43SStefano Zampini } 2466f6f667cfSStefano Zampini if (allocated_S_St) { 2467f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 2468f6f667cfSStefano Zampini } 2469f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 247008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 247108122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 247208122e43SStefano Zampini #endif 247308122e43SStefano Zampini if (pcbddc->dbg_flag) { 24741b968477SStefano Zampini PetscInt maxneigs_r; 2475b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 24769b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 247708122e43SStefano Zampini } 247808122e43SStefano Zampini PetscFunctionReturn(0); 247908122e43SStefano Zampini } 2480b1b3d7a2SStefano Zampini 2481674ae819SStefano Zampini #undef __FUNCT__ 2482c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 2483c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 2484c8587f34SStefano Zampini { 24858629588bSStefano Zampini PetscScalar *coarse_submat_vals; 2486c8587f34SStefano Zampini PetscErrorCode ierr; 2487c8587f34SStefano Zampini 2488c8587f34SStefano Zampini PetscFunctionBegin; 2489f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 24905e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 2491c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 2492c8587f34SStefano Zampini 2493684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 24940fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 2495684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 2496c8587f34SStefano Zampini 24978629588bSStefano Zampini /* 24988629588bSStefano Zampini Setup local correction and local part of coarse basis. 24998629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 25008629588bSStefano Zampini */ 250147f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 25028629588bSStefano Zampini 25038629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 25048629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 25058629588bSStefano Zampini 25068629588bSStefano Zampini /* free */ 25078629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 2508c8587f34SStefano Zampini PetscFunctionReturn(0); 2509c8587f34SStefano Zampini } 2510c8587f34SStefano Zampini 2511c8587f34SStefano Zampini #undef __FUNCT__ 2512674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 2513674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 2514674ae819SStefano Zampini { 2515674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2516674ae819SStefano Zampini PetscErrorCode ierr; 2517674ae819SStefano Zampini 2518674ae819SStefano Zampini PetscFunctionBegin; 2519674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 252030368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 2521674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 2522785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 2523674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 2524f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2525f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2526785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 252763602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 252863602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 2529674ae819SStefano Zampini PetscFunctionReturn(0); 2530674ae819SStefano Zampini } 2531674ae819SStefano Zampini 2532674ae819SStefano Zampini #undef __FUNCT__ 2533674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 2534674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 2535674ae819SStefano Zampini { 2536674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 25374f1b2e48SStefano Zampini PetscInt i; 2538674ae819SStefano Zampini PetscErrorCode ierr; 2539674ae819SStefano Zampini 2540674ae819SStefano Zampini PetscFunctionBegin; 2541a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 2542b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2543674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 254416909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 25451dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 2546674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2547669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 2548fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 2549a13144ffSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 2550674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 255171582508SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 25524f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 25534f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 25544f1b2e48SStefano Zampini } 25554f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 2556b334f244SStefano Zampini if (pcbddc->sub_schurs) { 2557b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 2558b334f244SStefano Zampini } 2559674ae819SStefano Zampini PetscFunctionReturn(0); 2560674ae819SStefano Zampini } 2561674ae819SStefano Zampini 2562674ae819SStefano Zampini #undef __FUNCT__ 2563674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 2564674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 2565674ae819SStefano Zampini { 2566674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2567674ae819SStefano Zampini PetscErrorCode ierr; 2568674ae819SStefano Zampini 2569674ae819SStefano Zampini PetscFunctionBegin; 2570674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 257158da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 2572ca92afb2SStefano Zampini PetscScalar *array; 257306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 257406656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 257558da7f69SStefano Zampini } 2576674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 2577674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 257815aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 257915aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 2580674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 2581674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 2582674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 258306656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 2584674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 2585674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 25868ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2587674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2588674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2589674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 2590f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 2591f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 2592f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 2593f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 2594727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 25950e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2596f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 259770cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 259881d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 25990369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 26001dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 26014f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 26028b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 2603ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 2604ca92afb2SStefano Zampini PetscInt i; 2605ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2606ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2607ca92afb2SStefano Zampini } 2608ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2609ca92afb2SStefano Zampini } 26104f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 2611674ae819SStefano Zampini PetscFunctionReturn(0); 2612674ae819SStefano Zampini } 2613674ae819SStefano Zampini 2614674ae819SStefano Zampini #undef __FUNCT__ 2615f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 2616f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 26176bfb1811SStefano Zampini { 26186bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 26196bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 26206bfb1811SStefano Zampini VecType impVecType; 26214f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 26226bfb1811SStefano Zampini PetscErrorCode ierr; 26236bfb1811SStefano Zampini 26246bfb1811SStefano Zampini PetscFunctionBegin; 26256c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 2626e7b262bdSStefano Zampini /* get sizes */ 26274f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 2628b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 26296bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 2630e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 2631e7b262bdSStefano Zampini /* R nodes */ 2632e7b262bdSStefano Zampini old_size = -1; 2633e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 2634e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 2635e7b262bdSStefano Zampini } 2636e7b262bdSStefano Zampini if (n_R != old_size) { 2637e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 2638e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 26396bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 26406bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 26416bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 26426bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 2643e7b262bdSStefano Zampini } 2644e7b262bdSStefano Zampini /* local primal dofs */ 2645e7b262bdSStefano Zampini old_size = -1; 2646e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 2647e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 2648e7b262bdSStefano Zampini } 2649e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 2650e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 265183b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 2652e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 26536bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 2654e7b262bdSStefano Zampini } 2655e7b262bdSStefano Zampini /* local explicit constraints */ 2656e7b262bdSStefano Zampini old_size = -1; 2657e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 2658e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 2659e7b262bdSStefano Zampini } 2660e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 2661e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 266283b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 266383b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 266483b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 266583b7ccabSStefano Zampini } 26666bfb1811SStefano Zampini PetscFunctionReturn(0); 26676bfb1811SStefano Zampini } 26686bfb1811SStefano Zampini 26696bfb1811SStefano Zampini #undef __FUNCT__ 267047f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 267147f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 267288ebb749SStefano Zampini { 267325084f0cSStefano Zampini PetscErrorCode ierr; 267425084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 267588ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 267688ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2677d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 267825084f0cSStefano Zampini /* submatrices of local problem */ 267980677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 268006656605SStefano Zampini /* submatrices of local coarse problem */ 268106656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 268225084f0cSStefano Zampini /* working matrices */ 268306656605SStefano Zampini Mat C_CR; 268425084f0cSStefano Zampini /* additional working stuff */ 268506656605SStefano Zampini PC pc_R; 26864f1b2e48SStefano Zampini Mat F; 26875cbda25cSStefano Zampini Vec dummy_vec; 2688a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 268925084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 269006656605SStefano Zampini PetscScalar *work; 269106656605SStefano Zampini PetscInt *idx_V_B; 2692ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 269306656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 2694ffd830a3SStefano Zampini 269525084f0cSStefano Zampini /* some shortcuts to scalars */ 269606656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 269788ebb749SStefano Zampini 269888ebb749SStefano Zampini PetscFunctionBegin; 26999a962809SStefano 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"); 2700ffd830a3SStefano Zampini 2701ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 2702b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 27034f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 2704b371cd4fSStefano Zampini n_B = pcis->n_B; 2705b371cd4fSStefano Zampini n_D = pcis->n - n_B; 270688ebb749SStefano Zampini n_R = pcis->n - n_vertices; 270788ebb749SStefano Zampini 270888ebb749SStefano Zampini /* vertices in boundary numbering */ 2709785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 27100e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 27116c4ed002SBarry 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); 271288ebb749SStefano Zampini 271306656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 2714019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 271506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 271606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 271706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 271806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 271906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 272006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 272106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 272206656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 272306656605SStefano Zampini 272406656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 272506656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 272606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 272706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 272806656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 2729ffd830a3SStefano Zampini lda_rhs = n_R; 2730a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 273106656605SStefano Zampini if (isLU || isILU || isCHOL) { 273206656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 2733b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 2734df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2735d62866d3SStefano Zampini MatFactorType type; 2736d62866d3SStefano Zampini 2737df4d28bfSStefano Zampini F = reuse_solver->F; 27386816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 2739d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 2740ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 274122db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 274206656605SStefano Zampini } else { 274306656605SStefano Zampini F = NULL; 274406656605SStefano Zampini } 274506656605SStefano Zampini 2746ffd830a3SStefano Zampini /* allocate workspace */ 2747ffd830a3SStefano Zampini n = 0; 2748ffd830a3SStefano Zampini if (n_constraints) { 2749ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 2750ffd830a3SStefano Zampini } 2751ffd830a3SStefano Zampini if (n_vertices) { 2752ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 2753ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 2754ffd830a3SStefano Zampini } 2755ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 2756ffd830a3SStefano Zampini 27575cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 27585cbda25cSStefano Zampini dummy_vec = NULL; 27595cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 27605cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 27615cbda25cSStefano Zampini } 27625cbda25cSStefano Zampini 276388ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 276488ebb749SStefano Zampini if (n_constraints) { 276572b8c272SStefano Zampini Mat M1,M2,M3,C_B; 276606656605SStefano Zampini IS is_aux; 276780677318SStefano Zampini PetscScalar *array,*array2; 276806656605SStefano Zampini 2769f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 277080677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 277188ebb749SStefano Zampini 277225084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 277325084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 27748ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 277572b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 277688ebb749SStefano Zampini 277780677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 277880677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 2779ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 278088ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 278106656605SStefano Zampini const PetscScalar *row_cmat_values; 278206656605SStefano Zampini const PetscInt *row_cmat_indices; 278306656605SStefano Zampini PetscInt size_of_constraint,j; 278488ebb749SStefano Zampini 278506656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 278606656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 2787ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 278806656605SStefano Zampini } 278906656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 279006656605SStefano Zampini } 2791ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 279206656605SStefano Zampini if (F) { 279306656605SStefano Zampini Mat B; 279406656605SStefano Zampini 2795ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 2796a3df083aSStefano Zampini if (need_benign_correction) { 2797df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2798a3df083aSStefano Zampini 279972b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 280072b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 2801a3df083aSStefano Zampini } 280280677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 2803a3df083aSStefano Zampini if (need_benign_correction) { 2804a3df083aSStefano Zampini PetscScalar *marr; 2805df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2806a3df083aSStefano Zampini 2807a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 28085cbda25cSStefano Zampini if (lda_rhs != n_R) { 28095cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 28105cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 28115cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 28125cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 28135cbda25cSStefano Zampini } 28145cbda25cSStefano Zampini } else { 2815a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 2816a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 28175cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 2818a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2819a3df083aSStefano Zampini } 28205cbda25cSStefano Zampini } 2821a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 2822a3df083aSStefano Zampini } 282306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 282406656605SStefano Zampini } else { 282580677318SStefano Zampini PetscScalar *marr; 282680677318SStefano Zampini 282780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 282806656605SStefano Zampini for (i=0;i<n_constraints;i++) { 2829ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 2830ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 283106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 283206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 283306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 283406656605SStefano Zampini } 283580677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 283606656605SStefano Zampini } 283780677318SStefano Zampini if (!pcbddc->switch_static) { 283880677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 283980677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 284080677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 284180677318SStefano Zampini for (i=0;i<n_constraints;i++) { 2842ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 284380677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 284480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 284580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 284680677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 284780677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 284880677318SStefano Zampini } 284980677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 285080677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 285172b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 285280677318SStefano Zampini } else { 2853ffd830a3SStefano Zampini if (lda_rhs != n_R) { 2854ffd830a3SStefano Zampini IS dummy; 2855ffd830a3SStefano Zampini 2856ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 285772b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 2858ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 2859ffd830a3SStefano Zampini } else { 286080677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 286180677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 2862ffd830a3SStefano Zampini } 286325084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 286480677318SStefano Zampini } 286580677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 286680677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 286780677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 286806656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 286906656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 287080677318SStefano Zampini if (isCHOL) { 287180677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 287280677318SStefano Zampini } else { 287325084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 287480677318SStefano Zampini } 287580677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 287606656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 287725084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 287825084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 287925084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 288080677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 288172b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 288272b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 288306656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 288406656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 2885f4ddd8eeSStefano Zampini } 2886fc227af8SStefano Zampini 2887fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 288888ebb749SStefano Zampini if (n_vertices) { 288906656605SStefano Zampini IS is_aux; 28903a50541eSStefano Zampini 2891b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 28926816873aSStefano Zampini IS tis; 28936816873aSStefano Zampini 28946816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 28956816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 28966816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 28976816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 28986816873aSStefano Zampini } else { 28993a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 29006816873aSStefano Zampini } 29019577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 29029577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 290304708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 290425084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 290588ebb749SStefano Zampini } 290688ebb749SStefano Zampini 290788ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 2908f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 290906656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 291006656605SStefano Zampini if (pcbddc->coarse_phi_D) { 291106656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 291206656605SStefano Zampini } 2913f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 291406656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 291506656605SStefano Zampini PetscScalar *marray; 291606656605SStefano Zampini 291706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 291806656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 2919f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 2920f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 2921f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 2922f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 2923f4ddd8eeSStefano Zampini } 2924f4ddd8eeSStefano Zampini } 292506656605SStefano Zampini 2926f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 292706656605SStefano Zampini PetscScalar *marray; 292888ebb749SStefano Zampini 292906656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 29308eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 293106656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 293288ebb749SStefano Zampini } 29333301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 293406656605SStefano Zampini n *= 2; 293588ebb749SStefano Zampini } 293606656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 293706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 293806656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 29398eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 294006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 294106656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 294288ebb749SStefano Zampini } 29433301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 294406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 29458eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 294606656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 294706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 294888ebb749SStefano Zampini } 294988ebb749SStefano Zampini } else { 2950c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 2951c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 29521b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2953c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 2954c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 2955c0553b1fSStefano Zampini } 295688ebb749SStefano Zampini } 295706656605SStefano Zampini } 2958019a44ceSStefano Zampini 295906656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 29604f1b2e48SStefano Zampini p0_lidx_I = NULL; 29614f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 2962d12edf2fSStefano Zampini const PetscInt *idxs; 2963d12edf2fSStefano Zampini 2964d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 29654f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 29664f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 29674f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 29684f1b2e48SStefano Zampini } 2969d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 2970d12edf2fSStefano Zampini } 2971d16cbb6bSStefano Zampini 297206656605SStefano Zampini /* vertices */ 297306656605SStefano Zampini if (n_vertices) { 297416f15bc4SStefano Zampini 2975af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 297604708bb6SStefano Zampini 297716f15bc4SStefano Zampini if (n_R) { 297814393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 297906656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 298016f15bc4SStefano Zampini PetscScalar *x,*y; 298104708bb6SStefano Zampini PetscBool isseqaij; 298206656605SStefano Zampini 298321eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 298414393ed6SStefano Zampini if (need_benign_correction) { 298514393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 298614393ed6SStefano Zampini IS is_p0; 298714393ed6SStefano Zampini PetscInt *idxs_p0,n; 298814393ed6SStefano Zampini 298914393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 299014393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 299114393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 2992af25d912SStefano 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); 299314393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 299414393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 299514393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 299614393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 299714393ed6SStefano Zampini } 299814393ed6SStefano Zampini 2999ffd830a3SStefano Zampini if (lda_rhs == n_R) { 3000af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3001ffd830a3SStefano Zampini } else { 3002ca92afb2SStefano Zampini PetscScalar *av,*array; 3003ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 3004ca92afb2SStefano Zampini PetscInt n; 3005ca92afb2SStefano Zampini PetscBool flg_row; 3006ffd830a3SStefano Zampini 3007ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 3008ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 30099d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3010ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3011ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 3012ca92afb2SStefano Zampini for (i=0;i<n;i++) { 3013ca92afb2SStefano Zampini PetscInt j; 3014ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 3015ffd830a3SStefano Zampini } 3016ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3017ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3018ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 3019ffd830a3SStefano Zampini } 3020ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3021a3df083aSStefano Zampini if (need_benign_correction) { 3022df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3023a3df083aSStefano Zampini PetscScalar *marr; 3024a3df083aSStefano Zampini 3025a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 302614393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 302714393ed6SStefano Zampini 302814393ed6SStefano Zampini | 0 0 0 | (V) 302914393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 303014393ed6SStefano Zampini | 0 0 -1 | (p0) 303114393ed6SStefano Zampini 303214393ed6SStefano Zampini */ 3033df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 303414393ed6SStefano Zampini const PetscScalar *vals; 303514393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 303614393ed6SStefano Zampini PetscInt n,j,nz; 303714393ed6SStefano Zampini 3038df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3039df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 304014393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 304114393ed6SStefano Zampini for (j=0;j<n;j++) { 304214393ed6SStefano Zampini PetscScalar val = vals[j]; 304314393ed6SStefano Zampini PetscInt k,col = idxs[j]; 304414393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 304514393ed6SStefano Zampini } 304614393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3047df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 304814393ed6SStefano Zampini } 304972b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 305072b8c272SStefano Zampini } 305172b8c272SStefano Zampini if (F) { 305214393ed6SStefano Zampini /* need to correct the rhs */ 305372b8c272SStefano Zampini if (need_benign_correction) { 305472b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 305572b8c272SStefano Zampini PetscScalar *marr; 305672b8c272SStefano Zampini 305772b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 30585cbda25cSStefano Zampini if (lda_rhs != n_R) { 30595cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 30605cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 30615cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 30625cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 30635cbda25cSStefano Zampini } 30645cbda25cSStefano Zampini } else { 3065a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3066a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 30675cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3068a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3069a3df083aSStefano Zampini } 30705cbda25cSStefano Zampini } 3071a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 3072a3df083aSStefano Zampini } 307306656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 307414393ed6SStefano Zampini /* need to correct the solution */ 3075a3df083aSStefano Zampini if (need_benign_correction) { 3076df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3077a3df083aSStefano Zampini PetscScalar *marr; 3078a3df083aSStefano Zampini 3079a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 30805cbda25cSStefano Zampini if (lda_rhs != n_R) { 30815cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 30825cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 30835cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 30845cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 30855cbda25cSStefano Zampini } 30865cbda25cSStefano Zampini } else { 3087a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3088a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 30895cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3090a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3091a3df083aSStefano Zampini } 30925cbda25cSStefano Zampini } 3093a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 3094a3df083aSStefano Zampini } 309506656605SStefano Zampini } else { 309606656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 309706656605SStefano Zampini for (i=0;i<n_vertices;i++) { 3098ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 3099ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 310006656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 310106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 310206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 310306656605SStefano Zampini } 310406656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 310506656605SStefano Zampini } 310680677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3107ffd830a3SStefano Zampini /* S_VV and S_CV */ 310806656605SStefano Zampini if (n_constraints) { 310906656605SStefano Zampini Mat B; 311080677318SStefano Zampini 3111ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 311280677318SStefano Zampini for (i=0;i<n_vertices;i++) { 3113ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3114ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 311580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 311680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 311780677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 311880677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 311980677318SStefano Zampini } 3120ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 312180677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 312280677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 3123ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 312480677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 312506656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 3126ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 3127ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 312806656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 312906656605SStefano Zampini } 313004708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 313104708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 3132511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 313304708bb6SStefano Zampini } 3134ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3135ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 3136ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3137ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 3138ffd830a3SStefano Zampini } 313906656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 314014393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 314114393ed6SStefano Zampini if (need_benign_correction) { 3142df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 314314393ed6SStefano Zampini PetscScalar *marr,*sums; 314414393ed6SStefano Zampini 314514393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 314614393ed6SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr); 3147df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 314814393ed6SStefano Zampini const PetscScalar *vals; 314914393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 315014393ed6SStefano Zampini PetscInt n,j,nz; 315114393ed6SStefano Zampini 3152df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3153df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 315414393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 315514393ed6SStefano Zampini PetscInt k; 315614393ed6SStefano Zampini sums[j] = 0.; 315714393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 315814393ed6SStefano Zampini } 315914393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 316014393ed6SStefano Zampini for (j=0;j<n;j++) { 316114393ed6SStefano Zampini PetscScalar val = vals[j]; 316214393ed6SStefano Zampini PetscInt k; 316314393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 316414393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 316514393ed6SStefano Zampini } 316614393ed6SStefano Zampini } 316714393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3168df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 316914393ed6SStefano Zampini } 317014393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 317114393ed6SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr); 317214393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 317314393ed6SStefano Zampini } 317480677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 317506656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 317606656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 317706656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 317806656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 317906656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 318006656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 318106656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3182d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 3183019a44ceSStefano Zampini } else { 3184d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3185d16cbb6bSStefano Zampini } 318621eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 3187d16cbb6bSStefano Zampini 318806656605SStefano Zampini /* coarse basis functions */ 318906656605SStefano Zampini for (i=0;i<n_vertices;i++) { 319016f15bc4SStefano Zampini PetscScalar *y; 319116f15bc4SStefano Zampini 3192ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 319306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 319406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 319506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 319606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 319706656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 319806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 319906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 320006656605SStefano Zampini 320106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 32024f1b2e48SStefano Zampini PetscInt j; 32034f1b2e48SStefano Zampini 320406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 320506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 320606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 320706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 320806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 32094f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 321006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 321106656605SStefano Zampini } 321206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 321306656605SStefano Zampini } 321404708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 321504708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 321606656605SStefano Zampini } 32175cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 321806656605SStefano Zampini 321906656605SStefano Zampini if (n_constraints) { 322006656605SStefano Zampini Mat B; 322106656605SStefano Zampini 3222ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 322306656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 322480677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 322506656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 322606656605SStefano Zampini if (n_vertices) { 322780677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 322880677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 322980677318SStefano Zampini } else { 323080677318SStefano Zampini Mat S_VCt; 323180677318SStefano Zampini 3232ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3233ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 323472b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 3235ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 3236ffd830a3SStefano Zampini } 323780677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 323880677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 323980677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 324080677318SStefano Zampini } 324106656605SStefano Zampini } 324206656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 324306656605SStefano Zampini /* coarse basis functions */ 324406656605SStefano Zampini for (i=0;i<n_constraints;i++) { 324506656605SStefano Zampini PetscScalar *y; 324606656605SStefano Zampini 3247ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 324806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 324906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 325006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 325106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 325206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 325306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 325406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 32554f1b2e48SStefano Zampini PetscInt j; 32564f1b2e48SStefano Zampini 325706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 325806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 325906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 326006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 326106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 32624f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 326306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 326406656605SStefano Zampini } 326506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 326606656605SStefano Zampini } 326706656605SStefano Zampini } 326880677318SStefano Zampini if (n_constraints) { 326980677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 327080677318SStefano Zampini } 32714f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 327272b8c272SStefano Zampini 327372b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 327472b8c272SStefano Zampini if (pcbddc->benign_n) { 327572b8c272SStefano Zampini Mat B0_B,B0_BPHI; 327672b8c272SStefano Zampini IS is_dummy; 327772b8c272SStefano Zampini PetscScalar *data; 327872b8c272SStefano Zampini PetscInt j; 327972b8c272SStefano Zampini 328072b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 328172b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 328272b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 328372b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 328486c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 328572b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 328672b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 328772b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 328872b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 328972b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 329072b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 329172b8c272SStefano Zampini } 329272b8c272SStefano Zampini } 329372b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 329472b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 329572b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 329672b8c272SStefano Zampini } 3297019a44ceSStefano Zampini 329806656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 32993301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3300ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 3301ffd830a3SStefano Zampini PetscScalar *marray; 330206656605SStefano Zampini 330306656605SStefano Zampini if (n_constraints) { 3304ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 330506656605SStefano Zampini 3306af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 330706656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 3308ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 330916f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 331006656605SStefano Zampini if (n_vertices) { 3311ffd830a3SStefano Zampini Mat S_VCT; 331206656605SStefano Zampini 331306656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 3314ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 331516f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 331606656605SStefano Zampini } 3317ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 33185b782168SStefano Zampini } else { 33195b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 332006656605SStefano Zampini } 332116f15bc4SStefano Zampini if (n_vertices && n_R) { 3322ffd830a3SStefano Zampini PetscScalar *av,*marray; 3323ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 3324ffd830a3SStefano Zampini PetscInt n; 3325ffd830a3SStefano Zampini PetscBool flg_row; 332606656605SStefano Zampini 3327ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 3328af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3329ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3330ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 3331ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3332ffd830a3SStefano Zampini for (i=0;i<n;i++) { 3333ffd830a3SStefano Zampini PetscInt j; 3334ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 3335ffd830a3SStefano Zampini } 3336ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 3337ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3338ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 333906656605SStefano Zampini } 334006656605SStefano Zampini 3341ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 3342ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3343ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 3344ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 3345ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 334606656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 334706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 334806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 334906656605SStefano Zampini } 3350ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 33515b782168SStefano Zampini if (B_C) { 3352ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 3353ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 3354ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 3355ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 3356ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 3357ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3358ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 335906656605SStefano Zampini } 3360ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 33615b782168SStefano Zampini } 336206656605SStefano Zampini /* coarse basis functions */ 336306656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 336406656605SStefano Zampini PetscScalar *y; 336506656605SStefano Zampini 3366ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 336706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 336806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 336906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 337006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 337106656605SStefano Zampini if (i<n_vertices) { 337206656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 337306656605SStefano Zampini } 337406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 337506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 337606656605SStefano Zampini 337706656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 337806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 337906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 338006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 338106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 338206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 338306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 338406656605SStefano Zampini } 338506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 338606656605SStefano Zampini } 3387ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 3388ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 338906656605SStefano Zampini } 3390d62866d3SStefano Zampini /* free memory */ 339188ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 339206656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 339306656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 339406656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 339506656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 3396d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3397d62866d3SStefano Zampini if (n_vertices) { 3398d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 3399d62866d3SStefano Zampini } 3400d62866d3SStefano Zampini if (n_constraints) { 3401d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 3402d62866d3SStefano Zampini } 340388ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 340488ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 340588ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 3406d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 340788ebb749SStefano Zampini Mat coarse_sub_mat; 340825084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 340988ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 341088ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 341188ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 34128bec7fa6SStefano Zampini Mat C_B,CPHI; 34138bec7fa6SStefano Zampini IS is_dummy; 34148bec7fa6SStefano Zampini Vec mones; 341588ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 341688ebb749SStefano Zampini PetscReal real_value; 341788ebb749SStefano Zampini 3418a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 3419a3df083aSStefano Zampini Mat A; 3420a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 3421a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 3422a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 3423a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 3424a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3425a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 3426a3df083aSStefano Zampini } else { 342788ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 342888ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 342988ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 343088ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3431a3df083aSStefano Zampini } 343288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 343388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 3434ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 343588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 343688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 343788ebb749SStefano Zampini } 343888ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 343988ebb749SStefano Zampini 344025084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 34413301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 344225084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3443ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 344488ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 344588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 344688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 344788ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 344888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 344988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 345088ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 345188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 345288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 345388ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 345488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 345588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 345688ebb749SStefano Zampini } else { 345788ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 345888ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 345988ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 346088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 346188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 346288ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 346388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 346488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 346588ebb749SStefano Zampini } 346688ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 346788ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 346888ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 3469511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 34704f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3471fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 3472d12edf2fSStefano Zampini PetscScalar *data,*data2; 34734f1b2e48SStefano Zampini PetscInt j; 3474d12edf2fSStefano Zampini 34754f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 3476fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 3477d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 347886c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 3479d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 3480d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 34814f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 34824f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 3483d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 34844f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 34854f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 34864f1b2e48SStefano Zampini } 3487d12edf2fSStefano Zampini } 3488d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 3489d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 3490d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 3491d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 3492d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 3493d12edf2fSStefano Zampini } 3494d12edf2fSStefano Zampini #if 0 3495d12edf2fSStefano Zampini { 3496d12edf2fSStefano Zampini PetscViewer viewer; 3497d12edf2fSStefano Zampini char filename[256]; 3498ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 3499d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 3500d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3501ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 3502ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 3503ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 3504d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 350572b8c272SStefano Zampini if (save_change) { 350672b8c272SStefano Zampini Mat phi_B; 350772b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 350872b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 350972b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 351072b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 351172b8c272SStefano Zampini } else { 3512ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 3513ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 351472b8c272SStefano Zampini } 3515ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 3516ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 3517ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 3518ffd830a3SStefano Zampini } 3519ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 3520ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 3521ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 3522ffd830a3SStefano Zampini } 352372b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 3524ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 3525ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 3526ffd830a3SStefano Zampini } 3527d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3528d12edf2fSStefano Zampini } 3529d12edf2fSStefano Zampini #endif 353081d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 35318bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 35321575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 353306656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 35348bec7fa6SStefano Zampini 35358bec7fa6SStefano Zampini /* check constraints */ 3536a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 3537a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 35384f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 35398bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3540a00504b5SStefano Zampini } else { 3541a00504b5SStefano Zampini PetscScalar *data; 3542a00504b5SStefano Zampini Mat tmat; 3543a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 3544a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 3545a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 3546a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3547a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3548a00504b5SStefano Zampini } 35498bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 35508bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 35518bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 35528bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 3553bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 3554ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 3555bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 3556bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 3557bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 3558bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 3559bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 356088ebb749SStefano Zampini } 35618bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 35628bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 35638bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 35648bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 356525084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 356688ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 356788ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 356888ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 356988ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 357088ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 357188ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 357288ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 357388ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 357488ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 357588ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 3576ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 357788ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 357888ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 357988ebb749SStefano Zampini } 358088ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 358188ebb749SStefano Zampini } 35828629588bSStefano Zampini /* get back data */ 35838629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 358488ebb749SStefano Zampini PetscFunctionReturn(0); 358588ebb749SStefano Zampini } 358688ebb749SStefano Zampini 358788ebb749SStefano Zampini #undef __FUNCT__ 3588d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 3589d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 3590aa0d41d4SStefano Zampini { 3591d65f70fdSStefano Zampini Mat *work_mat; 3592d65f70fdSStefano Zampini IS isrow_s,iscol_s; 3593d65f70fdSStefano Zampini PetscBool rsorted,csorted; 3594c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 3595aa0d41d4SStefano Zampini PetscErrorCode ierr; 3596aa0d41d4SStefano Zampini 3597aa0d41d4SStefano Zampini PetscFunctionBegin; 3598d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 3599d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 3600d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 3601d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 3602aa0d41d4SStefano Zampini 3603d65f70fdSStefano Zampini if (!rsorted) { 3604906d46d4SStefano Zampini const PetscInt *idxs; 3605906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 3606aa0d41d4SStefano Zampini 3607d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 3608d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 3609d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3610d65f70fdSStefano Zampini idxs_perm_r[i] = i; 3611aa0d41d4SStefano Zampini } 3612d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 3613d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 3614d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3615d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 3616aa0d41d4SStefano Zampini } 3617d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 3618d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 3619d65f70fdSStefano Zampini } else { 3620d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 3621d65f70fdSStefano Zampini isrow_s = isrow; 3622aa0d41d4SStefano Zampini } 3623906d46d4SStefano Zampini 3624d65f70fdSStefano Zampini if (!csorted) { 3625d65f70fdSStefano Zampini if (isrow == iscol) { 3626d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 3627d65f70fdSStefano Zampini iscol_s = isrow_s; 3628d65f70fdSStefano Zampini } else { 3629d65f70fdSStefano Zampini const PetscInt *idxs; 3630d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 3631906d46d4SStefano Zampini 3632d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 3633d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 3634d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3635d65f70fdSStefano Zampini idxs_perm_c[i] = i; 3636d65f70fdSStefano Zampini } 3637d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 3638d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 3639d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3640d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 3641d65f70fdSStefano Zampini } 3642d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 3643d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 3644d65f70fdSStefano Zampini } 3645d65f70fdSStefano Zampini } else { 3646d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 3647d65f70fdSStefano Zampini iscol_s = iscol; 3648d65f70fdSStefano Zampini } 3649d65f70fdSStefano Zampini 3650d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 3651d65f70fdSStefano Zampini 3652d65f70fdSStefano Zampini if (!rsorted || !csorted) { 3653906d46d4SStefano Zampini Mat new_mat; 3654d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 3655906d46d4SStefano Zampini 3656d65f70fdSStefano Zampini if (!rsorted) { 3657d65f70fdSStefano Zampini PetscInt *idxs_r,i; 3658d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 3659d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 3660d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 3661906d46d4SStefano Zampini } 3662d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 3663d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 3664d65f70fdSStefano Zampini } else { 3665d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 3666906d46d4SStefano Zampini } 3667d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 3668d65f70fdSStefano Zampini 3669d65f70fdSStefano Zampini if (!csorted) { 3670d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 3671d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 3672d65f70fdSStefano Zampini is_perm_c = is_perm_r; 3673d65f70fdSStefano Zampini } else { 3674d65f70fdSStefano Zampini PetscInt *idxs_c,i; 3675d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 3676d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 3677d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 3678d65f70fdSStefano Zampini } 3679d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 3680d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 3681d65f70fdSStefano Zampini } 3682d65f70fdSStefano Zampini } else { 3683d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 3684d65f70fdSStefano Zampini } 3685d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 3686d65f70fdSStefano Zampini 3687d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 3688d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 3689d65f70fdSStefano Zampini work_mat[0] = new_mat; 3690d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 3691d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 3692d65f70fdSStefano Zampini } 3693d65f70fdSStefano Zampini 3694d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 3695d65f70fdSStefano Zampini *B = work_mat[0]; 3696d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 3697d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 3698d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 3699d65f70fdSStefano Zampini PetscFunctionReturn(0); 3700d65f70fdSStefano Zampini } 3701d65f70fdSStefano Zampini 3702d65f70fdSStefano Zampini #undef __FUNCT__ 37035e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 37045e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 3705aa0d41d4SStefano Zampini { 3706aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 37075e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3708d65f70fdSStefano Zampini Mat new_mat; 37095e8657edSStefano Zampini IS is_local,is_global; 3710d65f70fdSStefano Zampini PetscInt local_size; 3711d65f70fdSStefano Zampini PetscBool isseqaij; 3712aa0d41d4SStefano Zampini PetscErrorCode ierr; 3713aa0d41d4SStefano Zampini 3714aa0d41d4SStefano Zampini PetscFunctionBegin; 3715aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 37165e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 37175e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 3718b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 3719aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 3720d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 3721aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 3722906d46d4SStefano Zampini 3723906d46d4SStefano Zampini /* check */ 3724906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3725906d46d4SStefano Zampini Vec x,x_change; 3726906d46d4SStefano Zampini PetscReal error; 3727906d46d4SStefano Zampini 37285e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 3729906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 37305e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 3731e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3732e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3733d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 3734e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3735e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3736906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 3737906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 3738906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3739906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 3740906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 3741906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 3742906d46d4SStefano Zampini } 3743906d46d4SStefano Zampini 374422d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 37459b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 374622d5777bSStefano Zampini if (isseqaij) { 3747a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3748a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 3749aa0d41d4SStefano Zampini } else { 3750a00504b5SStefano Zampini Mat work_mat; 37511cf9b237SStefano Zampini 3752a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3753aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 3754a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 37551d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 3756aa0d41d4SStefano Zampini } 37573301b35fSStefano Zampini if (matis->A->symmetric_set) { 37583301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 3759e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 37603301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 3761e496cd5dSStefano Zampini #endif 37623301b35fSStefano Zampini } 3763d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 3764aa0d41d4SStefano Zampini PetscFunctionReturn(0); 3765aa0d41d4SStefano Zampini } 3766aa0d41d4SStefano Zampini 3767aa0d41d4SStefano Zampini #undef __FUNCT__ 3768a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 37698ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 3770a64d13efSStefano Zampini { 3771a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3772a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3773d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 377453892102SStefano Zampini PetscInt *idx_R_local=NULL; 37753a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 37763a50541eSStefano Zampini PetscInt vbs,bs; 37776816873aSStefano Zampini PetscBT bitmask=NULL; 3778a64d13efSStefano Zampini PetscErrorCode ierr; 3779a64d13efSStefano Zampini 3780a64d13efSStefano Zampini PetscFunctionBegin; 3781b23d619eSStefano Zampini /* 3782b23d619eSStefano Zampini No need to setup local scatters if 3783b23d619eSStefano Zampini - primal space is unchanged 3784b23d619eSStefano Zampini AND 3785b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 3786b23d619eSStefano Zampini AND 3787b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 3788b23d619eSStefano Zampini */ 3789b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 3790f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 3791f4ddd8eeSStefano Zampini } 3792f4ddd8eeSStefano Zampini /* destroy old objects */ 3793f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3794f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3795f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3796a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 3797b371cd4fSStefano Zampini n_B = pcis->n_B; 3798b371cd4fSStefano Zampini n_D = pcis->n - n_B; 3799b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 38003a50541eSStefano Zampini 3801a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 38026816873aSStefano Zampini 380353892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 3804b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 3805854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 3806a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 3807a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 38080e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 3809a64d13efSStefano Zampini } 3810a64d13efSStefano Zampini 3811a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 38124641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 38136816873aSStefano Zampini idx_R_local[n_R++] = i; 3814a64d13efSStefano Zampini } 3815a64d13efSStefano Zampini } 3816df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 3817df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 38186816873aSStefano Zampini 3819df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3820df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 38216816873aSStefano Zampini } 38223a50541eSStefano Zampini 38233a50541eSStefano Zampini /* Block code */ 38243a50541eSStefano Zampini vbs = 1; 38253a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 38263a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 38273a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 38283a50541eSStefano Zampini PetscInt *vary; 3829b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 3830785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 38313a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 3832d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 3833d3df7717SStefano 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 */ 38340e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 3835d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 38363a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 38373a50541eSStefano Zampini is_blocked = PETSC_FALSE; 38383a50541eSStefano Zampini break; 38393a50541eSStefano Zampini } 38403a50541eSStefano Zampini } 3841d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 3842d3df7717SStefano Zampini } else { 3843d3df7717SStefano Zampini /* Verify directly the R set */ 3844d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 3845d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 3846d3df7717SStefano Zampini for (j=1; j<bs; j++) { 3847d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 3848d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 3849d3df7717SStefano Zampini break; 3850d3df7717SStefano Zampini } 3851d3df7717SStefano Zampini } 3852d3df7717SStefano Zampini } 3853d3df7717SStefano Zampini } 38543a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 38553a50541eSStefano Zampini vbs = bs; 38563a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 38573a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 38583a50541eSStefano Zampini } 38593a50541eSStefano Zampini } 38603a50541eSStefano Zampini } 38613a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 3862b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 3863df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 386453892102SStefano Zampini 3865df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3866df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 386753892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 3868df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 386953892102SStefano Zampini } else { 38703a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 387153892102SStefano Zampini } 3872a64d13efSStefano Zampini 3873a64d13efSStefano Zampini /* print some info if requested */ 3874a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 3875a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3876a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 38771575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3878a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 3879a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 38804f1b2e48SStefano 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); 3881a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3882a64d13efSStefano Zampini } 3883a64d13efSStefano Zampini 3884a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 3885b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 38866816873aSStefano Zampini IS is_aux1,is_aux2; 38876816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 38886816873aSStefano Zampini 38893a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3890854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 3891854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 3892a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 38934641a718SStefano Zampini for (i=0; i<n_D; i++) { 38944641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 38954641a718SStefano Zampini } 3896a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3897a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 38984641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 38994641a718SStefano Zampini aux_array1[j++] = i; 3900a64d13efSStefano Zampini } 3901a64d13efSStefano Zampini } 3902a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 3903a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3904a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 39054641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 39064641a718SStefano Zampini aux_array2[j++] = i; 3907a64d13efSStefano Zampini } 3908a64d13efSStefano Zampini } 3909a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3910a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 3911a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 3912a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 3913a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 3914a64d13efSStefano Zampini 39158eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3916785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 3917a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 39184641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 39194641a718SStefano Zampini aux_array1[j++] = i; 3920a64d13efSStefano Zampini } 3921a64d13efSStefano Zampini } 3922a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 3923a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 3924a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 3925a64d13efSStefano Zampini } 39264641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 39273a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 3928d62866d3SStefano Zampini } else { 3929df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 39306816873aSStefano Zampini IS tis; 39316816873aSStefano Zampini PetscInt schur_size; 39326816873aSStefano Zampini 3933df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 39346816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 3935df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 39366816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 39376816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 39386816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 39396816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 39406816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 3941d62866d3SStefano Zampini } 3942d62866d3SStefano Zampini } 3943a64d13efSStefano Zampini PetscFunctionReturn(0); 3944a64d13efSStefano Zampini } 3945a64d13efSStefano Zampini 3946304d26faSStefano Zampini 3947304d26faSStefano Zampini #undef __FUNCT__ 3948304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 3949684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 3950304d26faSStefano Zampini { 3951304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3952304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3953304d26faSStefano Zampini PC pc_temp; 3954304d26faSStefano Zampini Mat A_RR; 3955f4ddd8eeSStefano Zampini MatReuse reuse; 3956304d26faSStefano Zampini PetscScalar m_one = -1.0; 3957304d26faSStefano Zampini PetscReal value; 395804708bb6SStefano Zampini PetscInt n_D,n_R; 3959c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 3960304d26faSStefano Zampini PetscErrorCode ierr; 3961e604994aSStefano Zampini /* prefixes stuff */ 3962312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 3963e604994aSStefano Zampini size_t len; 3964304d26faSStefano Zampini 3965304d26faSStefano Zampini PetscFunctionBegin; 3966304d26faSStefano Zampini 3967e604994aSStefano Zampini /* compute prefixes */ 3968e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 3969e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 3970e604994aSStefano Zampini if (!pcbddc->current_level) { 3971e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3972e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 3973e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 3974e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 3975e604994aSStefano Zampini } else { 3976e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 3977312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 3978e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 3979e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 3980312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 3981312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 398234d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 398334d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 3984e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 3985e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 3986e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 3987e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 3988e604994aSStefano Zampini } 3989e604994aSStefano Zampini 3990304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 3991684f6988SStefano Zampini if (dirichlet) { 3992d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3993450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 39949a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 3995450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 3996a3df083aSStefano Zampini Mat A_IIn; 3997a3df083aSStefano Zampini 3998a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 3999a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 4000a3df083aSStefano Zampini pcis->A_II = A_IIn; 4001a3df083aSStefano Zampini } 4002450f8f5eSStefano Zampini } 40033301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 40043301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 4005964fefecSStefano Zampini } 4006ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 4007964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 4008304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 4009304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 4010304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 4011304d26faSStefano Zampini /* default */ 4012304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 4013e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 40149577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 4015304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 40169577ea80SStefano Zampini if (issbaij) { 40179577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 40189577ea80SStefano Zampini } else { 4019304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 40209577ea80SStefano Zampini } 4021304d26faSStefano Zampini /* Allow user's customization */ 4022304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 4023304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4024304d26faSStefano Zampini } 4025d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 4026b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4027df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4028d62866d3SStefano Zampini 4029df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 4030d5574798SStefano Zampini } 4031304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4032304d26faSStefano Zampini if (!n_D) { 4033304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 4034304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4035304d26faSStefano Zampini } 4036304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 4037304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 4038304d26faSStefano Zampini /* set ksp_D into pcis data */ 4039304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 4040304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 4041304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 4042684f6988SStefano Zampini } 4043304d26faSStefano Zampini 4044304d26faSStefano Zampini /* NEUMANN PROBLEM */ 4045684f6988SStefano Zampini A_RR = 0; 4046684f6988SStefano Zampini if (neumann) { 4047d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 404804708bb6SStefano Zampini PetscInt ibs,mbs; 404904708bb6SStefano Zampini PetscBool issbaij; 405004708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4051f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 40528ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 4053f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 4054f4ddd8eeSStefano Zampini PetscInt nn_R; 405581d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 4056f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4057f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 4058f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 4059f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 4060f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4061f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4062f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 4063727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 4064f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4065f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4066f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 4067f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 4068f4ddd8eeSStefano Zampini } 4069f4ddd8eeSStefano Zampini } 4070f4ddd8eeSStefano Zampini /* last check */ 4071d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 4072f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4073f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4074f4ddd8eeSStefano Zampini } 4075f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 4076f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4077f4ddd8eeSStefano Zampini } 4078a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 4079af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 4080af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 408104708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 408204708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 408304708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 408404708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 408504708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 4086af732b37SStefano Zampini } else { 4087511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 40886816873aSStefano Zampini } 408904708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 409004708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 409104708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 409204708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 409304708bb6SStefano Zampini } else { 4094511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 409504708bb6SStefano Zampini } 409604708bb6SStefano Zampini } 4097a00504b5SStefano Zampini /* extract A_RR */ 4098b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4099a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4100a00504b5SStefano Zampini 4101a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 410216e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4103a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 410416e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 410516e386b8SStefano Zampini } else { 4106a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 4107a00504b5SStefano Zampini } 4108a00504b5SStefano Zampini } else { 4109a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4110a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 4111a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4112a00504b5SStefano Zampini } 4113a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 4114f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 411516e386b8SStefano Zampini } 41163301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 41173301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 41186816873aSStefano Zampini } 4119f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 4120304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 4121304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 4122304d26faSStefano Zampini /* default */ 4123304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 4124e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 4125304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 41269577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 41279577ea80SStefano Zampini if (issbaij) { 41289577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 41299577ea80SStefano Zampini } else { 4130304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 41319577ea80SStefano Zampini } 4132304d26faSStefano Zampini /* Allow user's customization */ 4133304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 4134304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4135304d26faSStefano Zampini } 4136304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4137304d26faSStefano Zampini if (!n_R) { 4138304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 4139304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4140304d26faSStefano Zampini } 41415cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 4142df4d28bfSStefano Zampini /* Reuse solver if it is present */ 4143b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4144df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4145d62866d3SStefano Zampini 4146df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 4147d62866d3SStefano Zampini } 4148304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 4149304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 4150684f6988SStefano Zampini } 4151304d26faSStefano Zampini 4152684f6988SStefano Zampini if (pcbddc->dbg_flag) { 4153684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 41541575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4155684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4156684f6988SStefano Zampini } 4157c7017625SStefano Zampini 4158c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 4159c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 4160c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 4161c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 4162c7017625SStefano Zampini } 4163c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 4164c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 4165c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 4166c7017625SStefano Zampini } 4167c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 4168c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 4169c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 4170c7017625SStefano Zampini } 4171c7017625SStefano Zampini 4172c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 4173c7017625SStefano Zampini if (pcbddc->dbg_flag) { 4174684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 41750fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 41760fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 41770fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 41780fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 41790fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 4180e604994aSStefano 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); 4181c7017625SStefano Zampini if (check_corr[0]) { 4182c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 4183c7017625SStefano Zampini } 4184304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4185304d26faSStefano Zampini } 4186684f6988SStefano Zampini if (neumann) { /* Neumann */ 41870fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 41880fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 41890fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 41900fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 41910fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 4192e604994aSStefano 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); 4193c7017625SStefano Zampini if (check_corr[1]) { 4194c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 4195c7017625SStefano Zampini } 4196304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4197304d26faSStefano Zampini } 4198684f6988SStefano Zampini } 41995cbda25cSStefano Zampini /* free Neumann problem's matrix */ 42005cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4201304d26faSStefano Zampini PetscFunctionReturn(0); 4202304d26faSStefano Zampini } 4203304d26faSStefano Zampini 4204304d26faSStefano Zampini #undef __FUNCT__ 4205ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 420680677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 4207674ae819SStefano Zampini { 4208674ae819SStefano Zampini PetscErrorCode ierr; 4209674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4210be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4211b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 4212674ae819SStefano Zampini 4213674ae819SStefano Zampini PetscFunctionBegin; 4214b334f244SStefano Zampini if (!reuse_solver) { 421580677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 421620c7b377SStefano Zampini } 421780677318SStefano Zampini if (!pcbddc->switch_static) { 421880677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 421980677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 422080677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 422120c7b377SStefano Zampini } 4222b334f244SStefano Zampini if (!reuse_solver) { 422380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 422480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 422520c7b377SStefano Zampini } else { 4226df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4227be83ff47SStefano Zampini 4228df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4229df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 423020c7b377SStefano Zampini } 4231be83ff47SStefano Zampini } else { 423280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 423380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 423480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 423580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 423680677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 423780677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 423880677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 423980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 424080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4241674ae819SStefano Zampini } 4242674ae819SStefano Zampini } 4243b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 424480677318SStefano Zampini if (applytranspose) { 424580677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 424680677318SStefano Zampini } else { 424780677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 424880677318SStefano Zampini } 4249be83ff47SStefano Zampini } else { 4250df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4251be83ff47SStefano Zampini 4252be83ff47SStefano Zampini if (applytranspose) { 4253df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4254be83ff47SStefano Zampini } else { 4255df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4256be83ff47SStefano Zampini } 4257be83ff47SStefano Zampini } 425880677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 425980677318SStefano Zampini if (!pcbddc->switch_static) { 4260b334f244SStefano Zampini if (!reuse_solver) { 426180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 426280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4263be83ff47SStefano Zampini } else { 4264df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4265be83ff47SStefano Zampini 4266df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4267df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4268be83ff47SStefano Zampini } 426980677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 427080677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 427180677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 427280677318SStefano Zampini } 427380677318SStefano Zampini } else { 427480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 427580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 427680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 427780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 427880677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 427980677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 428080677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 428180677318SStefano Zampini } 428280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 428380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 428480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 428580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4286674ae819SStefano Zampini } 4287674ae819SStefano Zampini PetscFunctionReturn(0); 4288674ae819SStefano Zampini } 4289674ae819SStefano Zampini 4290dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 4291674ae819SStefano Zampini #undef __FUNCT__ 4292674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 4293dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 4294674ae819SStefano Zampini { 4295674ae819SStefano Zampini PetscErrorCode ierr; 4296674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4297674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 4298674ae819SStefano Zampini const PetscScalar zero = 0.0; 4299674ae819SStefano Zampini 4300674ae819SStefano Zampini PetscFunctionBegin; 4301dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 43024fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4303dc359a40SStefano Zampini if (applytranspose) { 4304674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 43058eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 4306dc359a40SStefano Zampini } else { 4307674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 4308674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 430915aaf578SStefano Zampini } 43104fee134fSStefano Zampini } else { 43114fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 43124fee134fSStefano Zampini } 4313efc2fbd9SStefano Zampini 4314efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 43154f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4316efc2fbd9SStefano Zampini PetscScalar *array; 43174f1b2e48SStefano Zampini PetscInt j; 4318efc2fbd9SStefano Zampini 4319efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 43204f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 4321efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4322efc2fbd9SStefano Zampini } 4323efc2fbd9SStefano Zampini 432412edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 432512edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 432612edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 432712edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 432812edc857SStefano Zampini 43299f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 433012edc857SStefano Zampini if (pcbddc->coarse_ksp) { 433151694757SStefano Zampini Mat coarse_mat; 4332964fefecSStefano Zampini Vec rhs,sol; 433351694757SStefano Zampini MatNullSpace nullsp; 433427b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 4335964fefecSStefano Zampini 433627b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 433727b6a85dSStefano Zampini PC coarse_pc; 433827b6a85dSStefano Zampini 433927b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 434027b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 434127b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 434227b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 434327b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 434427b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 43453bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 434627b6a85dSStefano Zampini } 434727b6a85dSStefano Zampini } 4348964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 4349964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 435051694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 435151694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 435251694757SStefano Zampini if (nullsp) { 435351694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 435451694757SStefano Zampini } 435512edc857SStefano Zampini if (applytranspose) { 43569a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 4357964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 43582701bc32SStefano Zampini } else { 43591f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 43602701bc32SStefano Zampini PC coarse_pc; 43612701bc32SStefano Zampini 43622701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 43632701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 43643e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 43652701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 436612edc857SStefano Zampini } else { 4367964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 436812edc857SStefano Zampini } 43692701bc32SStefano Zampini } 43701d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 437127b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 437227b6a85dSStefano Zampini PC coarse_pc; 437327b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 437427b6a85dSStefano Zampini 437527b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 437627b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 437727b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 43783bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 437927b6a85dSStefano Zampini } 438051694757SStefano Zampini if (nullsp) { 438151694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 438251694757SStefano Zampini } 438312edc857SStefano Zampini } 4384674ae819SStefano Zampini 4385674ae819SStefano Zampini /* Local solution on R nodes */ 43864fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 438780677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 43889f00e9b4SStefano Zampini } 43899f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 43909f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 439112edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4392674ae819SStefano Zampini 43934fee134fSStefano Zampini /* Sum contributions from the two levels */ 43944fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4395dc359a40SStefano Zampini if (applytranspose) { 4396dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 4397dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4398dc359a40SStefano Zampini } else { 4399674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 44008eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4401dc359a40SStefano Zampini } 4402efc2fbd9SStefano Zampini /* store p0 */ 44034f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4404efc2fbd9SStefano Zampini PetscScalar *array; 44054f1b2e48SStefano Zampini PetscInt j; 4406efc2fbd9SStefano Zampini 4407efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 44084f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 4409efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4410efc2fbd9SStefano Zampini } 44114fee134fSStefano Zampini } else { /* expand the coarse solution */ 44124fee134fSStefano Zampini if (applytranspose) { 44134fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 44144fee134fSStefano Zampini } else { 44154fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 44164fee134fSStefano Zampini } 44174fee134fSStefano Zampini } 4418674ae819SStefano Zampini PetscFunctionReturn(0); 4419674ae819SStefano Zampini } 4420674ae819SStefano Zampini 4421674ae819SStefano Zampini #undef __FUNCT__ 4422674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 442312edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 4424674ae819SStefano Zampini { 4425674ae819SStefano Zampini PetscErrorCode ierr; 4426674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 442758da7f69SStefano Zampini PetscScalar *array; 442812edc857SStefano Zampini Vec from,to; 4429674ae819SStefano Zampini 4430674ae819SStefano Zampini PetscFunctionBegin; 443112edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 443212edc857SStefano Zampini from = pcbddc->coarse_vec; 443312edc857SStefano Zampini to = pcbddc->vec1_P; 443412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 443512edc857SStefano Zampini Vec tvec; 443658da7f69SStefano Zampini 443758da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 443858da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 443912edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 444058da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 444158da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 444258da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 444312edc857SStefano Zampini } 444412edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 444512edc857SStefano Zampini from = pcbddc->vec1_P; 444612edc857SStefano Zampini to = pcbddc->coarse_vec; 444712edc857SStefano Zampini } 444812edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 4449674ae819SStefano Zampini PetscFunctionReturn(0); 4450674ae819SStefano Zampini } 4451674ae819SStefano Zampini 4452674ae819SStefano Zampini #undef __FUNCT__ 4453674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 445412edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 4455674ae819SStefano Zampini { 4456674ae819SStefano Zampini PetscErrorCode ierr; 4457674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 445858da7f69SStefano Zampini PetscScalar *array; 445912edc857SStefano Zampini Vec from,to; 4460674ae819SStefano Zampini 4461674ae819SStefano Zampini PetscFunctionBegin; 446212edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 446312edc857SStefano Zampini from = pcbddc->coarse_vec; 446412edc857SStefano Zampini to = pcbddc->vec1_P; 446512edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 446612edc857SStefano Zampini from = pcbddc->vec1_P; 446712edc857SStefano Zampini to = pcbddc->coarse_vec; 446812edc857SStefano Zampini } 446912edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 447012edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 447112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 447212edc857SStefano Zampini Vec tvec; 447358da7f69SStefano Zampini 447412edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 447558da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 447658da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 447758da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 447858da7f69SStefano Zampini } 447958da7f69SStefano Zampini } else { 448058da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 448158da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 448212edc857SStefano Zampini } 448312edc857SStefano Zampini } 4484674ae819SStefano Zampini PetscFunctionReturn(0); 4485674ae819SStefano Zampini } 4486674ae819SStefano Zampini 4487984c4197SStefano Zampini /* uncomment for testing purposes */ 4488984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 4489674ae819SStefano Zampini #undef __FUNCT__ 4490674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 4491674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 4492674ae819SStefano Zampini { 4493674ae819SStefano Zampini PetscErrorCode ierr; 4494674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4495674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4496674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4497984c4197SStefano Zampini /* one and zero */ 4498984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 4499984c4197SStefano Zampini /* space to store constraints and their local indices */ 45009162d606SStefano Zampini PetscScalar *constraints_data; 45019162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 45029162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 45039162d606SStefano Zampini PetscInt *constraints_n; 4504984c4197SStefano Zampini /* iterators */ 4505b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 4506984c4197SStefano Zampini /* BLAS integers */ 4507e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 4508e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 4509c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 4510727cdba6SStefano Zampini /* reuse */ 45110e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 45120e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 4513984c4197SStefano Zampini /* change of basis */ 4514b3d85658SStefano Zampini PetscBool qr_needed; 45159162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 4516984c4197SStefano Zampini /* auxiliary stuff */ 451764efe560SStefano Zampini PetscInt *nnz,*is_indices; 45188a0068c3SStefano Zampini PetscInt ncc; 4519984c4197SStefano Zampini /* some quantities */ 452045a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 4521a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 4522984c4197SStefano Zampini 4523674ae819SStefano Zampini PetscFunctionBegin; 45248e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 45258e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 45268e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 452716909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 4528088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 4529088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 45300e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 45310e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 45320e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 45330e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 45340e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 4535088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 4536cf5a6209SStefano Zampini 4537cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 45389162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 4539cf5a6209SStefano Zampini MatNullSpace nearnullsp; 4540cf5a6209SStefano Zampini const Vec *nearnullvecs; 4541cf5a6209SStefano Zampini Vec *localnearnullsp; 4542cf5a6209SStefano Zampini PetscScalar *array; 4543cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 4544cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 4545674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 4546b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 4547674ae819SStefano Zampini PetscScalar *work; 4548674ae819SStefano Zampini PetscReal *singular_vals; 4549674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4550674ae819SStefano Zampini PetscReal *rwork; 4551674ae819SStefano Zampini #endif 4552674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4553674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 4554674ae819SStefano Zampini #else 4555964fefecSStefano Zampini PetscBLASInt dummy_int=1; 4556964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 4557674ae819SStefano Zampini #endif 4558674ae819SStefano Zampini 4559674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 4560d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 4561e4d548c7SStefano Zampini /* print some info */ 45621f4df5f7SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs) { 4563e4d548c7SStefano Zampini PetscInt nv; 4564e4d548c7SStefano Zampini 4565c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 4566e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 4567e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4568e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 4569e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 4570e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 4571e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 4572e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4573e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4574e4d548c7SStefano Zampini } 4575e4d548c7SStefano Zampini 4576d06fc5fdSStefano Zampini /* free unneeded index sets */ 4577d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 4578d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 4579674ae819SStefano Zampini } 4580d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 4581d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 4582d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 4583d06fc5fdSStefano Zampini } 4584d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 4585d06fc5fdSStefano Zampini n_ISForEdges = 0; 4586d06fc5fdSStefano Zampini } 4587d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 4588d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 4589d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 4590d06fc5fdSStefano Zampini } 4591d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 4592d06fc5fdSStefano Zampini n_ISForFaces = 0; 4593d06fc5fdSStefano Zampini } 459470022509SStefano Zampini 4595674ae819SStefano Zampini /* check if near null space is attached to global mat */ 4596674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 4597674ae819SStefano Zampini if (nearnullsp) { 4598674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 4599f4ddd8eeSStefano Zampini /* remove any stored info */ 4600f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 4601f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 4602f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 4603f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 4604f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 4605473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 4606f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 4607f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 4608f4ddd8eeSStefano Zampini } 4609984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 4610984c4197SStefano Zampini nnsp_size = 0; 4611674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 4612674ae819SStefano Zampini } 4613984c4197SStefano Zampini /* get max number of constraints on a single cc */ 4614984c4197SStefano Zampini max_constraints = nnsp_size; 4615984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 4616984c4197SStefano Zampini 4617674ae819SStefano Zampini /* 4618674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 46199162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 46209162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 46219162d606SStefano Zampini There can be multiple constraints per connected component 4622674ae819SStefano Zampini */ 4623674ae819SStefano Zampini n_vertices = 0; 4624674ae819SStefano Zampini if (ISForVertices) { 4625674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 4626674ae819SStefano Zampini } 46279162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 46289162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 46299162d606SStefano Zampini 46309162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 46319162d606SStefano Zampini total_counts *= max_constraints; 4632674ae819SStefano Zampini total_counts += n_vertices; 46334641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 46349162d606SStefano Zampini 4635674ae819SStefano Zampini total_counts = 0; 4636674ae819SStefano Zampini max_size_of_constraint = 0; 4637674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 46389162d606SStefano Zampini IS used_is; 4639674ae819SStefano Zampini if (i<n_ISForEdges) { 46409162d606SStefano Zampini used_is = ISForEdges[i]; 4641674ae819SStefano Zampini } else { 46429162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 4643674ae819SStefano Zampini } 46449162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 4645674ae819SStefano Zampini total_counts += j; 4646674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 4647674ae819SStefano Zampini } 46489162d606SStefano 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); 46499162d606SStefano Zampini 4650984c4197SStefano Zampini /* get local part of global near null space vectors */ 4651785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 4652984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 4653984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 4654e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4655e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4656984c4197SStefano Zampini } 4657674ae819SStefano Zampini 4658242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 4659242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 4660a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 4661242a89d7SStefano Zampini 4662984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 4663a773dcb8SStefano Zampini if (!skip_lapack) { 4664674ae819SStefano Zampini PetscScalar temp_work; 4665911cabfeSStefano Zampini 4666674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4667984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 4668785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 4669785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 4670785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 4671674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4672785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 4673674ae819SStefano Zampini #endif 4674674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 4675c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 4676c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 4677674ae819SStefano Zampini lwork = -1; 4678674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4679674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 4680c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 4681674ae819SStefano Zampini #else 4682c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 4683674ae819SStefano Zampini #endif 4684674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4685984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 4686674ae819SStefano Zampini #else /* on missing GESVD */ 4687674ae819SStefano Zampini /* SVD */ 4688674ae819SStefano Zampini PetscInt max_n,min_n; 4689674ae819SStefano Zampini max_n = max_size_of_constraint; 4690984c4197SStefano Zampini min_n = max_constraints; 4691984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 4692674ae819SStefano Zampini min_n = max_size_of_constraint; 4693984c4197SStefano Zampini max_n = max_constraints; 4694674ae819SStefano Zampini } 4695785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 4696674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4697785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 4698674ae819SStefano Zampini #endif 4699674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 4700674ae819SStefano Zampini lwork = -1; 4701e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 4702e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 4703b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 4704674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4705674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 47069162d606SStefano 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)); 4707674ae819SStefano Zampini #else 47089162d606SStefano 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)); 4709674ae819SStefano Zampini #endif 4710674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4711984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 4712984c4197SStefano Zampini #endif /* on missing GESVD */ 4713674ae819SStefano Zampini /* Allocate optimal workspace */ 4714674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 4715854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 4716674ae819SStefano Zampini } 4717674ae819SStefano Zampini /* Now we can loop on constraining sets */ 4718674ae819SStefano Zampini total_counts = 0; 47199162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 47209162d606SStefano Zampini constraints_data_ptr[0] = 0; 4721674ae819SStefano Zampini /* vertices */ 47229162d606SStefano Zampini if (n_vertices) { 4723674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 47249162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 4725674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 47269162d606SStefano Zampini constraints_n[total_counts] = 1; 47279162d606SStefano Zampini constraints_data[total_counts] = 1.0; 47289162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 47299162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 4730674ae819SStefano Zampini total_counts++; 4731674ae819SStefano Zampini } 4732674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4733674ae819SStefano Zampini n_vertices = total_counts; 4734674ae819SStefano Zampini } 4735984c4197SStefano Zampini 4736674ae819SStefano Zampini /* edges and faces */ 47379162d606SStefano Zampini total_counts_cc = total_counts; 4738911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 47399162d606SStefano Zampini IS used_is; 47409162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 47419162d606SStefano Zampini 4742911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 47439162d606SStefano Zampini used_is = ISForEdges[ncc]; 4744984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 4745674ae819SStefano Zampini } else { 47469162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 4747984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 4748674ae819SStefano Zampini } 4749674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 47509162d606SStefano Zampini 47519162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 47529162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4753984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 4754984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 4755674ae819SStefano Zampini if (nnsp_has_cnst) { 47565b08dc53SStefano Zampini PetscScalar quad_value; 47579162d606SStefano Zampini 47589162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 47599162d606SStefano Zampini idxs_copied = PETSC_TRUE; 47609162d606SStefano Zampini 4761a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 4762674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 4763a773dcb8SStefano Zampini } else { 4764a773dcb8SStefano Zampini quad_value = 1.0; 4765a773dcb8SStefano Zampini } 4766674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 47679162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 4768674ae819SStefano Zampini } 47699162d606SStefano Zampini temp_constraints++; 4770674ae819SStefano Zampini total_counts++; 4771674ae819SStefano Zampini } 4772674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 4773984c4197SStefano Zampini PetscReal real_value; 47749162d606SStefano Zampini PetscScalar *ptr_to_data; 47759162d606SStefano Zampini 4776984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 47779162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 4778674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 47799162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 4780674ae819SStefano Zampini } 4781984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 4782984c4197SStefano Zampini /* check if array is null on the connected component */ 4783e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 47849162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 47855b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 4786674ae819SStefano Zampini temp_constraints++; 4787674ae819SStefano Zampini total_counts++; 47889162d606SStefano Zampini if (!idxs_copied) { 47899162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 47909162d606SStefano Zampini idxs_copied = PETSC_TRUE; 4791674ae819SStefano Zampini } 4792674ae819SStefano Zampini } 47939162d606SStefano Zampini } 47949162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 479545a1bb75SStefano Zampini valid_constraints = temp_constraints; 4796eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 4797a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 47989162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 47999162d606SStefano Zampini 48009162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 4801a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 48029162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 4803a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 48049162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 4805a773dcb8SStefano Zampini } else { /* perform SVD */ 4806984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 48079162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 4808674ae819SStefano Zampini 4809674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4810984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 4811984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 4812984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 4813984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 4814984c4197SStefano Zampini from that computed using LAPACKgesvd 4815984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 4816984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 4817984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 4818674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 4819e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 4820984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4821674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 4822674ae819SStefano Zampini for (k=0;k<j+1;k++) { 48239162d606SStefano 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)); 4824674ae819SStefano Zampini } 4825674ae819SStefano Zampini } 4826e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 4827e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 4828e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 4829674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 4830c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 4831674ae819SStefano Zampini #else 4832c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 4833674ae819SStefano Zampini #endif 4834674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4835984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 4836984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 4837674ae819SStefano Zampini j = 0; 4838984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 4839674ae819SStefano Zampini total_counts = total_counts-j; 484045a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 4841e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 4842c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 4843c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 4844c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 4845c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4846c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 4847c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 4848674ae819SStefano Zampini if (j<temp_constraints) { 4849984c4197SStefano Zampini PetscInt ii; 4850984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 4851674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 48529162d606SStefano 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)); 4853674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4854984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 4855674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 48569162d606SStefano 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]; 4857674ae819SStefano Zampini } 4858674ae819SStefano Zampini } 4859674ae819SStefano Zampini } 4860674ae819SStefano Zampini #else /* on missing GESVD */ 4861e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 4862e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 4863b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 4864674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 4865674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 48669162d606SStefano 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)); 4867674ae819SStefano Zampini #else 48689162d606SStefano 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)); 4869674ae819SStefano Zampini #endif 4870984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 4871674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 4872984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 4873e310c8b4SStefano Zampini k = temp_constraints; 4874e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 4875674ae819SStefano Zampini j = 0; 4876e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 487745a1bb75SStefano Zampini valid_constraints = k-j; 4878911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 4879984c4197SStefano Zampini #endif /* on missing GESVD */ 4880674ae819SStefano Zampini } 4881a773dcb8SStefano Zampini } 48829162d606SStefano Zampini /* update pointers information */ 48839162d606SStefano Zampini if (valid_constraints) { 48849162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 48859162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 48869162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 48879162d606SStefano Zampini /* set change_of_basis flag */ 488845a1bb75SStefano Zampini if (boolforchange) { 4889b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 48909162d606SStefano Zampini } 4891b3d85658SStefano Zampini total_counts_cc++; 489245a1bb75SStefano Zampini } 489345a1bb75SStefano Zampini } 4894984c4197SStefano Zampini /* free workspace */ 48958f1c130eSStefano Zampini if (!skip_lapack) { 4896984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4897984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 4898984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 4899984c4197SStefano Zampini #endif 4900984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 4901984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 4902984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 4903984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 4904984c4197SStefano Zampini #endif 4905984c4197SStefano Zampini } 4906984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 4907984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 4908984c4197SStefano Zampini } 4909984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 4910cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 4911cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 4912cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 4913cf5a6209SStefano Zampini } 4914cf5a6209SStefano Zampini if (n_ISForFaces) { 4915cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 4916cf5a6209SStefano Zampini } 4917cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 4918cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 4919cf5a6209SStefano Zampini } 4920cf5a6209SStefano Zampini if (n_ISForEdges) { 4921cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 4922cf5a6209SStefano Zampini } 4923cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 492408122e43SStefano Zampini } else { 492508122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4926984c4197SStefano Zampini 492708122e43SStefano Zampini total_counts = 0; 492808122e43SStefano Zampini n_vertices = 0; 4929d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 4930d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 493108122e43SStefano Zampini } 493208122e43SStefano Zampini max_constraints = 0; 49339162d606SStefano Zampini total_counts_cc = 0; 493408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 493508122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 49369162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 493708122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 493808122e43SStefano Zampini } 49399162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 49409162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 49419162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 49429162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 494374d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 49449162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 49459162d606SStefano Zampini total_counts_cc = 0; 49469162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 49479162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 49489162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 494908122e43SStefano Zampini } 495008122e43SStefano Zampini } 49519162d606SStefano Zampini #if 0 49529162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 49539162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 49549162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 49559162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 49569162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 49579162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 49589162d606SStefano Zampini } 49599162d606SStefano Zampini printf("\n"); 49609162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 49619162d606SStefano Zampini } 49621b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 49638bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 49641b968477SStefano Zampini } 49651b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 49668bec7fa6SStefano 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]); 49671b968477SStefano Zampini } 496808122e43SStefano Zampini #endif 496908122e43SStefano Zampini 49708bec7fa6SStefano Zampini max_size_of_constraint = 0; 49719162d606SStefano 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]); 49729162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 497308122e43SStefano Zampini /* Change of basis */ 4974b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 497508122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 497608122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 497708122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 4978b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 497908122e43SStefano Zampini } 498008122e43SStefano Zampini } 498108122e43SStefano Zampini } 498208122e43SStefano Zampini } 4983984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 49844f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 498508122e43SStefano Zampini 49869162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 49879162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 49886c4ed002SBarry 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); 4989674ae819SStefano Zampini 4990674ae819SStefano Zampini /* Create constraint matrix */ 4991674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 499216f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 4993984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 4994984c4197SStefano Zampini 4995984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 4996a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 4997a717540cSStefano Zampini qr_needed = PETSC_FALSE; 499874d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 4999984c4197SStefano Zampini total_primal_vertices=0; 5000b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 50019162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 50029162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 500372b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 50049162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 5005b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 500664efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 50079162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 50089162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 5009a717540cSStefano Zampini } 5010b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 501191af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 5012a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 5013a717540cSStefano Zampini qr_needed = PETSC_TRUE; 5014a717540cSStefano Zampini } 5015fa434743SStefano Zampini } else { 5016b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 5017fa434743SStefano Zampini } 5018a717540cSStefano Zampini } 5019b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 5020b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 5021674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 502270022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5023b3d85658SStefano Zampini 50244f1b2e48SStefano 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); 50250e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 50260e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 5027984c4197SStefano Zampini 5028984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 502974d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 5030785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 5031984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 503274d5cdf7SStefano Zampini 5033984c4197SStefano Zampini j = total_primal_vertices; 503474d5cdf7SStefano Zampini total_counts = total_primal_vertices; 5035b3d85658SStefano Zampini cum = total_primal_vertices; 50369162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 50374641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 5038b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 5039b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 5040b3d85658SStefano Zampini cum++; 50419162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 504274d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 504374d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 504474d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 504574d5cdf7SStefano Zampini } 50469162d606SStefano Zampini j += constraints_n[i]; 5047674ae819SStefano Zampini } 5048674ae819SStefano Zampini } 5049674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 5050674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 5051088faed8SStefano Zampini 5052674ae819SStefano Zampini /* set values in constraint matrix */ 5053984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 50540e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5055674ae819SStefano Zampini } 5056984c4197SStefano Zampini total_counts = total_primal_vertices; 50579162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 50584641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 50599162d606SStefano Zampini PetscInt *cols; 50609162d606SStefano Zampini 50619162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 50629162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 50639162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 50649162d606SStefano Zampini PetscInt row = total_counts+k; 50659162d606SStefano Zampini PetscScalar *vals; 50669162d606SStefano Zampini 50679162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 50689162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 50699162d606SStefano Zampini } 50709162d606SStefano Zampini total_counts += constraints_n[i]; 5071674ae819SStefano Zampini } 5072674ae819SStefano Zampini } 5073674ae819SStefano Zampini /* assembling */ 5074674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5075674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5076088faed8SStefano Zampini 5077984c4197SStefano Zampini /* 50786a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5079984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 5080f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 5081984c4197SStefano Zampini */ 5082674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 5083674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 5084026de310SStefano Zampini /* dual and primal dofs on a single cc */ 5085984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 5086984c4197SStefano Zampini /* working stuff for GEQRF */ 508781d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 5088984c4197SStefano Zampini PetscBLASInt lqr_work; 5089984c4197SStefano Zampini /* working stuff for UNGQR */ 5090984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 5091984c4197SStefano Zampini PetscBLASInt lgqr_work; 5092984c4197SStefano Zampini /* working stuff for TRTRS */ 5093984c4197SStefano Zampini PetscScalar *trs_rhs; 50943f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 5095984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 5096984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 5097984c4197SStefano Zampini PetscScalar *start_vals; 5098984c4197SStefano Zampini /* working stuff for values insertion */ 50994641a718SStefano Zampini PetscBT is_primal; 510064efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 5101906d46d4SStefano Zampini /* matrix sizes */ 5102906d46d4SStefano Zampini PetscInt global_size,local_size; 5103906d46d4SStefano Zampini /* temporary change of basis */ 5104906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 5105cf5a6209SStefano Zampini /* extra space for debugging */ 5106cf5a6209SStefano Zampini PetscScalar *dbg_work; 5107984c4197SStefano Zampini 5108906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 5109906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 511016f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 5111bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 5112906d46d4SStefano Zampini /* nonzeros for local mat */ 5113bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 51141dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5115bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 51161dd7afcfSStefano Zampini } else { 51171dd7afcfSStefano Zampini const PetscInt *ii; 51181dd7afcfSStefano Zampini PetscInt n; 51191dd7afcfSStefano Zampini PetscBool flg_row; 51201dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 51211dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 51221dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 51231dd7afcfSStefano Zampini } 51249162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 5125a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 51269162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 5127a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 51289162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 5129a717540cSStefano Zampini } else { 51309162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 51319162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 5132a717540cSStefano Zampini } 5133a717540cSStefano Zampini } 5134a717540cSStefano Zampini } 5135906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 5136bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 51371dd7afcfSStefano Zampini /* Set interior change in the matrix */ 51381dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5139bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 5140906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 5141a717540cSStefano Zampini } 51421dd7afcfSStefano Zampini } else { 51431dd7afcfSStefano Zampini const PetscInt *ii,*jj; 51441dd7afcfSStefano Zampini PetscScalar *aa; 51451dd7afcfSStefano Zampini PetscInt n; 51461dd7afcfSStefano Zampini PetscBool flg_row; 51471dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 51481dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 51491dd7afcfSStefano Zampini for (i=0;i<n;i++) { 51501dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 51511dd7afcfSStefano Zampini } 51521dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 51531dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 51541dd7afcfSStefano Zampini } 5155a717540cSStefano Zampini 5156a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5157a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5158a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5159a717540cSStefano Zampini } 5160a717540cSStefano Zampini 5161a717540cSStefano Zampini 5162a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 5163a717540cSStefano Zampini /* 5164a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 5165a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 5166a717540cSStefano Zampini 5167a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 5168a717540cSStefano Zampini 5169a6b551f4SStefano 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) 5170a6b551f4SStefano Zampini 5171a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 5172a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 5173a717540cSStefano Zampini | ... | 5174a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 5175a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 5176a717540cSStefano Zampini 5177a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 5178a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 5179a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 5180a6b551f4SStefano Zampini 5181a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 5182a717540cSStefano Zampini */ 5183a717540cSStefano Zampini if (qr_needed) { 5184984c4197SStefano Zampini /* space to store Q */ 5185854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 51864e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 51874e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 5188984c4197SStefano Zampini /* first we issue queries for optimal work */ 51893f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 51903f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 51913f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5192984c4197SStefano Zampini lqr_work = -1; 51933f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 5194984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 5195984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 5196785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 5197984c4197SStefano Zampini lgqr_work = -1; 51983f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 51993f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 52003f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 52013f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 52023f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 52033f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 5204984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 5205984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 5206785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 5207984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 5208785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 5209a717540cSStefano Zampini /* allocating workspace for check */ 5210a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5211cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 5212a717540cSStefano Zampini } 5213a717540cSStefano Zampini } 5214984c4197SStefano Zampini /* array to store whether a node is primal or not */ 52154641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 5216473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 52170e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 52186c4ed002SBarry 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); 521939e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 522039e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 522139e2fb2aSStefano Zampini } 522239e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 5223984c4197SStefano Zampini 5224a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 52259162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 52269162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 52274641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 5228984c4197SStefano Zampini /* get constraint info */ 52299162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 5230984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 5231984c4197SStefano Zampini 5232984c4197SStefano Zampini if (pcbddc->dbg_flag) { 52339162d606SStefano 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); 5234674ae819SStefano Zampini } 5235984c4197SStefano Zampini 5236fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 5237a717540cSStefano Zampini 5238a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 5239a717540cSStefano Zampini if (pcbddc->dbg_flag) { 52409162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5241a717540cSStefano Zampini } 5242984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 52439162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5244984c4197SStefano Zampini 5245984c4197SStefano Zampini /* compute QR decomposition of constraints */ 52463f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 52473f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 52483f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5249674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 52503f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 5251984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 5252674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5253984c4197SStefano Zampini 5254984c4197SStefano Zampini /* explictly compute R^-T */ 5255984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 5256984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 52573f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 52583f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 52593f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 52603f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 5261984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 52623f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 5263984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 5264984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5265984c4197SStefano Zampini 5266a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 52673f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 52683f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 52693f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 52703f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5271984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 52723f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 5273984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 5274984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5275984c4197SStefano Zampini 5276984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 5277984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 5278984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 52793f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 52803f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 52813f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 52823f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 52833f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 52843f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5285984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 52869162d606SStefano 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)); 5287984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 52889162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5289984c4197SStefano Zampini 5290984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 52919162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 5292984c4197SStefano Zampini /* insert cols for primal dofs */ 5293984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 5294984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 52959162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5296906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5297984c4197SStefano Zampini } 5298984c4197SStefano Zampini /* insert cols for dual dofs */ 5299984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 53009162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 5301984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 53029162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5303906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5304984c4197SStefano Zampini j++; 5305674ae819SStefano Zampini } 5306674ae819SStefano Zampini } 5307984c4197SStefano Zampini 5308984c4197SStefano Zampini /* check change of basis */ 5309984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5310984c4197SStefano Zampini PetscInt ii,jj; 5311984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 5312c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 5313c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5314c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 5315c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5316c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 5317c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 5318984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5319cf5a6209SStefano 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)); 5320984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5321984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5322984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5323cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 5324cf5a6209SStefano 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; 5325674ae819SStefano Zampini } 5326674ae819SStefano Zampini } 5327984c4197SStefano Zampini if (!valid_qr) { 532822d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 5329984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5330984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5331cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 5332cf5a6209SStefano 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])); 5333674ae819SStefano Zampini } 5334cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 5335cf5a6209SStefano 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])); 5336984c4197SStefano Zampini } 5337984c4197SStefano Zampini } 5338984c4197SStefano Zampini } 5339674ae819SStefano Zampini } else { 534022d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 5341674ae819SStefano Zampini } 5342674ae819SStefano Zampini } 5343a717540cSStefano Zampini } else { /* simple transformation block */ 5344a717540cSStefano Zampini PetscInt row,col; 5345a6b551f4SStefano Zampini PetscScalar val,norm; 5346a6b551f4SStefano Zampini 5347a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 53489162d606SStefano 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)); 5349a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 53509162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 53519162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5352bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 53539162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 5354906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 53559162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 5356a717540cSStefano Zampini } else { 5357a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 53589162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5359a717540cSStefano Zampini if (row != col) { 53609162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 5361a717540cSStefano Zampini } else { 53629162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 5363a717540cSStefano Zampini } 5364906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 5365a717540cSStefano Zampini } 5366a717540cSStefano Zampini } 5367a717540cSStefano Zampini } 536898a51de6SStefano Zampini if (pcbddc->dbg_flag) { 536922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 5370a717540cSStefano Zampini } 5371674ae819SStefano Zampini } 5372984c4197SStefano Zampini } else { 5373984c4197SStefano Zampini if (pcbddc->dbg_flag) { 53749162d606SStefano 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); 5375674ae819SStefano Zampini } 5376674ae819SStefano Zampini } 5377674ae819SStefano Zampini } 5378a717540cSStefano Zampini 5379a717540cSStefano Zampini /* free workspace */ 5380a717540cSStefano Zampini if (qr_needed) { 5381984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5382cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 5383984c4197SStefano Zampini } 5384984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 5385984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 5386984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 5387984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 5388984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 5389674ae819SStefano Zampini } 5390a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 5391906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5392906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5393906d46d4SStefano Zampini 5394906d46d4SStefano Zampini /* assembling of global change of variable */ 539588c03ad3SStefano Zampini if (!pcbddc->fake_change) { 5396bbb9e6c6SStefano Zampini Mat tmat; 539716f15bc4SStefano Zampini PetscInt bs; 539816f15bc4SStefano Zampini 5399906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 5400906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 5401bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 5402bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 5403bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5404bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 540516f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 540616f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 5407906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 5408bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 5409bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5410bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 5411bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5412bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5413e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5414e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5415bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 5416bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 541788c03ad3SStefano Zampini 5418906d46d4SStefano Zampini /* check */ 5419906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 5420906d46d4SStefano Zampini PetscReal error; 5421906d46d4SStefano Zampini Vec x,x_change; 5422906d46d4SStefano Zampini 5423906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 5424906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 5425906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 5426906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 5427e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5428e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5429bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 5430e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5431e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5432906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 5433906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 5434906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 5435906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5436bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 5437906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 5438906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 5439906d46d4SStefano Zampini } 5440b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 5441b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 5442b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 5443bf3a8328SStefano Zampini 54449a962809SStefano 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); 5445b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 5446ac632422SStefano Zampini Mat S_new,tmat; 5447bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 5448bbb9e6c6SStefano Zampini 5449bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 54506816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 5451bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5452bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 5453bf3a8328SStefano Zampini IS is_V; 5454b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 5455b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 5456b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 5457b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 5458b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 5459bf3a8328SStefano Zampini } 5460bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 5461ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 5462b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 5463ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 5464bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5465bf3a8328SStefano Zampini const PetscScalar *array; 5466bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 5467bf3a8328SStefano Zampini PetscInt i,n_V; 5468bf3a8328SStefano Zampini 5469b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 5470b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 5471b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 5472b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 5473b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 5474b087196eSStefano Zampini for (i=0;i<n_V;i++) { 5475b087196eSStefano Zampini PetscScalar val; 5476b087196eSStefano Zampini PetscInt idx; 5477b087196eSStefano Zampini 5478b087196eSStefano Zampini idx = idxs_V[i]; 5479b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 5480b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 5481b087196eSStefano Zampini } 5482b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5483b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5484bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 5485bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 5486bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 5487bf3a8328SStefano Zampini } 5488ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 5489ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 5490ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 5491ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 5492b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 5493ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 5494bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 5495b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 5496bf3a8328SStefano Zampini } 5497ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 5498ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 5499ac632422SStefano Zampini } 5500b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 550188c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 5502b96c3477SStefano Zampini } 5503c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 5504b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 5505c9db6a07SStefano Zampini PetscInt i; 5506c9db6a07SStefano Zampini 5507c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5508c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 5509c9db6a07SStefano Zampini } 5510c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 5511c9db6a07SStefano Zampini } 5512b96c3477SStefano Zampini } 551316909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 551416909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 551516909a7fSStefano Zampini } else { 5516906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 551716909a7fSStefano Zampini } 55181dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 551927b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 552072b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 552172b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 552272b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 552372b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 552472b8c272SStefano Zampini } 55251dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 552627b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 5527b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 5528b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 5529906d46d4SStefano Zampini } else { 55301dd7afcfSStefano Zampini Mat benign_global = NULL; 553127b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 55321dd7afcfSStefano Zampini Mat tmat; 55331dd7afcfSStefano Zampini 55341dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 55351dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 55361dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 55371dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 55381dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 55391dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 55401dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 55411dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 55421dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 55431dd7afcfSStefano Zampini if (pcbddc->benign_change) { 55441dd7afcfSStefano Zampini Mat M; 55451dd7afcfSStefano Zampini 55461dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 55471dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 55481dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 55491dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 5550906d46d4SStefano Zampini } else { 55511dd7afcfSStefano Zampini Mat eye; 55521dd7afcfSStefano Zampini PetscScalar *array; 55531dd7afcfSStefano Zampini 55541dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 55551dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 55561dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 55571dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 5558906d46d4SStefano Zampini } 55591dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 55601dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55611dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 55621dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 55631dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 55641dd7afcfSStefano Zampini } 55651dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 55661dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 55671dd7afcfSStefano Zampini } 55681dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 55691dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 55701dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 557127b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 55721dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 55731dd7afcfSStefano Zampini } 55741dd7afcfSStefano Zampini } 557516909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 557616909a7fSStefano Zampini IS is_global; 557716909a7fSStefano Zampini const PetscInt *gidxs; 557816909a7fSStefano Zampini 557916909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 558016909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 558116909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 558216909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 558316909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 558416909a7fSStefano Zampini } 55851dd7afcfSStefano Zampini } 55861dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 55871dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 5588b9b85e73SStefano Zampini } 5589a717540cSStefano Zampini 559072b8c272SStefano Zampini if (!pcbddc->fake_change) { 55914f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 55924f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 55934f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 55944f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 5595019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 5596019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 5597019a44ceSStefano Zampini pcbddc->local_primal_size++; 5598019a44ceSStefano Zampini } 5599019a44ceSStefano Zampini 5600019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 5601727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 5602727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 56039f47a83aSStefano 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); 5604c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 56050e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 56069f47a83aSStefano 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); 5607727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 5608727cdba6SStefano Zampini } 56090e6343abSStefano Zampini } 5610727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 5611b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 561272b8c272SStefano Zampini } 561372b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 5614727cdba6SStefano Zampini 5615a717540cSStefano Zampini /* flush dbg viewer */ 5616b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 5617b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5618b8ffe317SStefano Zampini } 5619a717540cSStefano Zampini 5620e310c8b4SStefano Zampini /* free workspace */ 5621a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 56224641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 562308122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 56249162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 56259162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 562608122e43SStefano Zampini } else { 56279162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 56289162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 56299162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 563008122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 563108122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 56329162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 56339162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 563408122e43SStefano Zampini } 5635674ae819SStefano Zampini PetscFunctionReturn(0); 5636674ae819SStefano Zampini } 5637674ae819SStefano Zampini 5638674ae819SStefano Zampini #undef __FUNCT__ 5639674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 5640674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 5641674ae819SStefano Zampini { 564271582508SStefano Zampini ISLocalToGlobalMapping map; 5643674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5644674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 564514f95afaSStefano Zampini PetscInt ierr,i,N; 5646674ae819SStefano Zampini 5647674ae819SStefano Zampini PetscFunctionBegin; 5648c8272957SStefano Zampini if (pcbddc->graphanalyzed && !pcbddc->recompute_topography) PetscFunctionReturn(0); 56498e61c736SStefano Zampini /* Reset previously computed graph */ 56508e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 5651674ae819SStefano Zampini /* Init local Graph struct */ 56527fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 565371582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 5654be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 5655674ae819SStefano Zampini 5656575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 56579a962809SStefano 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); 56589577ea80SStefano Zampini 5659674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 5660d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 56614d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 56624d379d7bSStefano Zampini PetscInt nvtxs; 5663e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 5664674ae819SStefano Zampini 56652fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 56662fffb893SStefano Zampini if (flg_row) { 56674d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 5668b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 56692fffb893SStefano Zampini } 56702fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 5671674ae819SStefano Zampini } 56729b28b941SStefano Zampini if (pcbddc->dbg_flag) { 56739b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5674674ae819SStefano Zampini } 5675674ae819SStefano Zampini 5676674ae819SStefano Zampini /* Setup of Graph */ 56774b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 567814f95afaSStefano 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); 5679674ae819SStefano Zampini 56804f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 56814f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 56824f1b2e48SStefano Zampini PetscInt *local_subs; 56834f1b2e48SStefano Zampini 56844f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 56854f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 56864f1b2e48SStefano Zampini const PetscInt *idxs; 56874f1b2e48SStefano Zampini PetscInt nl,j; 56884f1b2e48SStefano Zampini 56894f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 56904f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 569171582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 56924f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 56934f1b2e48SStefano Zampini } 56944f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 56954f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 56964f1b2e48SStefano Zampini } 56974f1b2e48SStefano Zampini 5698674ae819SStefano Zampini /* Graph's connected components analysis */ 5699674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 570071582508SStefano Zampini 570171582508SStefano Zampini /* set flag indicating analysis has been done */ 570271582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 5703674ae819SStefano Zampini PetscFunctionReturn(0); 5704674ae819SStefano Zampini } 5705674ae819SStefano Zampini 57069a7d3425SStefano Zampini #undef __FUNCT__ 57079a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 57089a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 57099a7d3425SStefano Zampini { 57109a7d3425SStefano Zampini PetscInt i,j; 57119a7d3425SStefano Zampini PetscScalar *alphas; 57129a7d3425SStefano Zampini PetscErrorCode ierr; 57139a7d3425SStefano Zampini 57149a7d3425SStefano Zampini PetscFunctionBegin; 5715785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 57169a7d3425SStefano Zampini for (i=0;i<n;i++) { 57179a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 5718669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 5719669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 5720669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 57219a7d3425SStefano Zampini } 57229a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 57239a7d3425SStefano Zampini PetscFunctionReturn(0); 57249a7d3425SStefano Zampini } 57259a7d3425SStefano Zampini 5726e7931f94SStefano Zampini #undef __FUNCT__ 572770cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 572857de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 5729e7931f94SStefano Zampini { 573057de7509SStefano Zampini Mat A; 5731e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 5732e7931f94SStefano Zampini PetscMPIInt size,rank,color; 573352e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 573452e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 573527b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 573657de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 573727b6a85dSStefano Zampini PetscInt xadj_count, *count; 573827b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 573927b6a85dSStefano Zampini PetscSubcomm psubcomm; 574027b6a85dSStefano Zampini MPI_Comm subcomm; 574152e5ac9dSStefano Zampini PetscErrorCode ierr; 5742a57a6d2fSStefano Zampini 5743e7931f94SStefano Zampini PetscFunctionBegin; 574457de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 574557de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 574657de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 574757de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 574857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 574957de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 575057de7509SStefano Zampini 575157de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 575257de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 575357de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 575457de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 575557de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 575657de7509SStefano Zampini im_active = !!(n); 575757de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 575857de7509SStefano Zampini void_procs = size - active_procs; 575957de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 576057de7509SStefano Zampini if (void_procs) { 576157de7509SStefano Zampini PetscInt ncand; 576257de7509SStefano Zampini 576357de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 576457de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 576557de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 576657de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 576757de7509SStefano Zampini if (!procs_candidates[i]) { 576857de7509SStefano Zampini procs_candidates[ncand++] = i; 576957de7509SStefano Zampini } 577057de7509SStefano Zampini } 577157de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 577257de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 577357de7509SStefano Zampini } 577457de7509SStefano Zampini 577514f0bfb9SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix 577614f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 577714f0bfb9SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1) { 577814f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 577914f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 578014f0bfb9SStefano Zampini else dest = rank; 578157de7509SStefano Zampini if (im_active) { 578257de7509SStefano Zampini issize = 1; 578357de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 578414f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 578557de7509SStefano Zampini } else { 578614f0bfb9SStefano Zampini isidx = dest; 578757de7509SStefano Zampini } 578857de7509SStefano Zampini } else { 578957de7509SStefano Zampini issize = 0; 579057de7509SStefano Zampini isidx = -1; 579157de7509SStefano Zampini } 579257de7509SStefano Zampini *n_subdomains = active_procs; 579357de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 5794daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 579557de7509SStefano Zampini PetscFunctionReturn(0); 579657de7509SStefano Zampini } 5797c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 5798c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 579927b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 5800e7931f94SStefano Zampini 5801e7931f94SStefano Zampini /* Get info on mapping */ 58023bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 58033bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 5804e7931f94SStefano Zampini 5805e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 5806785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 5807e7931f94SStefano Zampini xadj[0] = 0; 5808e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 5809785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 5810785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 581127b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 581227b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 581327b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 581427b6a85dSStefano Zampini count[shared[i][j]] += 1; 5815e7931f94SStefano Zampini 581627b6a85dSStefano Zampini xadj_count = 0; 58172b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 581827b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 581927b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 5820d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 5821d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 5822d023bfaeSStefano Zampini xadj_count++; 582327b6a85dSStefano Zampini break; 582427b6a85dSStefano Zampini } 5825e7931f94SStefano Zampini } 5826e7931f94SStefano Zampini } 5827d023bfaeSStefano Zampini xadj[1] = xadj_count; 582827b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 58293bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 5830e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 5831e7931f94SStefano Zampini 58323837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 5833e7931f94SStefano Zampini 583427b6a85dSStefano Zampini /* Restrict work on active processes only */ 583527b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 583627b6a85dSStefano Zampini if (void_procs) { 583727b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 583827b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 583927b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 584027b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 584127b6a85dSStefano Zampini } else { 584227b6a85dSStefano Zampini psubcomm = NULL; 584327b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 584427b6a85dSStefano Zampini } 584527b6a85dSStefano Zampini 584627b6a85dSStefano Zampini v_wgt = NULL; 584727b6a85dSStefano Zampini if (!color) { 5848e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 5849e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 5850e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5851c8587f34SStefano Zampini } else { 585252e5ac9dSStefano Zampini Mat subdomain_adj; 585352e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 585452e5ac9dSStefano Zampini MatPartitioning partitioner; 585527b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 585652e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 585757de7509SStefano Zampini PetscMPIInt size; 5858b0c7d250SStefano Zampini PetscBool aggregate; 5859b0c7d250SStefano Zampini 586027b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 586127b6a85dSStefano Zampini if (void_procs) { 586227b6a85dSStefano Zampini PetscInt prank = rank; 5863785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 586427b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 5865e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 5866e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 5867c8587f34SStefano Zampini } 5868e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 586927b6a85dSStefano Zampini } else { 587027b6a85dSStefano Zampini oldranks = NULL; 587127b6a85dSStefano Zampini } 5872b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 587327b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 5874b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 5875b0c7d250SStefano Zampini PetscMPIInt nrank; 5876b0c7d250SStefano Zampini PetscScalar *vals; 5877b0c7d250SStefano Zampini 587827b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 5879b0c7d250SStefano Zampini lrows = 0; 5880b0c7d250SStefano Zampini if (nrank<redprocs) { 5881b0c7d250SStefano Zampini lrows = size/redprocs; 5882b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 5883b0c7d250SStefano Zampini } 588427b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 5885b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 5886b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5887b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 5888b0c7d250SStefano Zampini row = nrank; 5889b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 5890b0c7d250SStefano Zampini cols = adjncy; 5891b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 5892b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 5893b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 5894b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5895b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 589652e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 589752e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 589852e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 5899b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 590027b6a85dSStefano Zampini if (use_vwgt) { 590127b6a85dSStefano Zampini Vec v; 590227b6a85dSStefano Zampini const PetscScalar *array; 590327b6a85dSStefano Zampini PetscInt nl; 590427b6a85dSStefano Zampini 590527b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 590627b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 590727b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 590827b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 590927b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 591027b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 591127b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 591222db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 591327b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 591427b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 591527b6a85dSStefano Zampini } 5916b0c7d250SStefano Zampini } else { 591727b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 591827b6a85dSStefano Zampini if (use_vwgt) { 591927b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 592027b6a85dSStefano Zampini v_wgt[0] = local_size; 592127b6a85dSStefano Zampini } 5922b0c7d250SStefano Zampini } 592322b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 5924e7931f94SStefano Zampini 5925e7931f94SStefano Zampini /* Partition */ 592627b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 5927e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 592827b6a85dSStefano Zampini if (v_wgt) { 5929e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 5930c8587f34SStefano Zampini } 593157de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 593257de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 5933e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 5934e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 593522b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 5936e7931f94SStefano Zampini 593752e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 59386583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 593952e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 594052e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 594157de7509SStefano Zampini if (!aggregate) { 594257de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 594327b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 594427b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 594527b6a85dSStefano Zampini #endif 594657de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 594727b6a85dSStefano Zampini } else if (oldranks) { 5948b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 594927b6a85dSStefano Zampini } else { 595027b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 595157de7509SStefano Zampini } 595228143c3dSStefano Zampini } else { 5953b0c7d250SStefano Zampini PetscInt idxs[1]; 5954b0c7d250SStefano Zampini PetscMPIInt tag; 5955b0c7d250SStefano Zampini MPI_Request *reqs; 5956b0c7d250SStefano Zampini 5957b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 5958b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 5959b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 596027b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 596128143c3dSStefano Zampini } 596227b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 5963b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5964b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 596557de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 596627b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 596727b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 596827b6a85dSStefano Zampini #endif 596957de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 597027b6a85dSStefano Zampini } else if (oldranks) { 5971b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 597227b6a85dSStefano Zampini } else { 597327b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 5974e7931f94SStefano Zampini } 597557de7509SStefano Zampini } 597652e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5977e7931f94SStefano Zampini /* clean up */ 5978e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 597952e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 5980e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 5981e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 5982e7931f94SStefano Zampini } 598327b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 598457de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 5985e7931f94SStefano Zampini 5986e7931f94SStefano Zampini /* assemble parallel IS for sends */ 5987e7931f94SStefano Zampini i = 1; 598827b6a85dSStefano Zampini if (!color) i=0; 598957de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 5990e7931f94SStefano Zampini PetscFunctionReturn(0); 5991e7931f94SStefano Zampini } 5992e7931f94SStefano Zampini 5993e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 5994e7931f94SStefano Zampini 5995e7931f94SStefano Zampini #undef __FUNCT__ 5996e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 59971ae86dd6SStefano 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[]) 5998e7931f94SStefano Zampini { 599970cf5478SStefano Zampini Mat local_mat; 6000e7931f94SStefano Zampini IS is_sends_internal; 60019d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 60021ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 60039d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 6004e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 6005e7931f94SStefano Zampini PetscInt* l2gmap_indices; 6006e7931f94SStefano Zampini const PetscInt* is_indices; 6007e7931f94SStefano Zampini MatType new_local_type; 6008e7931f94SStefano Zampini /* buffers */ 6009e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 601028143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 60119d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 6012e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 60131ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 6014e7931f94SStefano Zampini /* MPI */ 601528143c3dSStefano Zampini MPI_Comm comm,comm_n; 601628143c3dSStefano Zampini PetscSubcomm subcomm; 6017e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 601828143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 601928143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 60201ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 60211ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 60221ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 6023e7931f94SStefano Zampini PetscErrorCode ierr; 6024e7931f94SStefano Zampini 6025e7931f94SStefano Zampini PetscFunctionBegin; 602657de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6027e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 602828143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 602957de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 603057de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 603157de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 603257de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 603357de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 60341ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 60351ae86dd6SStefano Zampini if (nvecs) { 60361ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 60371ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 60381ae86dd6SStefano Zampini } 603957de7509SStefano Zampini /* further checks */ 6040e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6041e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 6042e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 6043e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 6044e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 604557de7509SStefano Zampini if (reuse && *mat_n) { 604670cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 604757de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 604870cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 604928143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 605070cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 605170cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 605270cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 605370cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 605470cf5478SStefano Zampini } 6055e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 6056e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 605757de7509SStefano Zampini 6058e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 6059e7931f94SStefano Zampini if (!is_sends) { 606028143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 606157de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 6062c8587f34SStefano Zampini } else { 6063e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 6064e7931f94SStefano Zampini is_sends_internal = is_sends; 6065c8587f34SStefano Zampini } 6066e7931f94SStefano Zampini 6067e7931f94SStefano Zampini /* get comm */ 6068a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 6069e7931f94SStefano Zampini 6070e7931f94SStefano Zampini /* compute number of sends */ 6071e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 6072e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 6073e7931f94SStefano Zampini 6074e7931f94SStefano Zampini /* compute number of receives */ 6075e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 6076785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 6077e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 6078e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6079e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 6080e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 6081e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 6082e7931f94SStefano Zampini 608328143c3dSStefano Zampini /* restrict comm if requested */ 608428143c3dSStefano Zampini subcomm = 0; 608528143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 608628143c3dSStefano Zampini if (restrict_comm) { 6087779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 6088779c1cceSStefano Zampini 608928143c3dSStefano Zampini color = 0; 609053a05cb3SStefano Zampini if (restrict_full) { 609153a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 609253a05cb3SStefano Zampini } else { 609353a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 609453a05cb3SStefano Zampini } 6095b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 609628143c3dSStefano Zampini subcommsize = commsize - subcommsize; 609728143c3dSStefano Zampini /* check if reuse has been requested */ 609857de7509SStefano Zampini if (reuse) { 609928143c3dSStefano Zampini if (*mat_n) { 610028143c3dSStefano Zampini PetscMPIInt subcommsize2; 610128143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 610228143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 610328143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 610428143c3dSStefano Zampini } else { 610528143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 610628143c3dSStefano Zampini } 610728143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 6108779c1cceSStefano Zampini PetscMPIInt rank; 6109779c1cceSStefano Zampini 6110779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 611128143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 611228143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 611328143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 6114306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 611528143c3dSStefano Zampini } 611628143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 611728143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 611828143c3dSStefano Zampini } else { 611928143c3dSStefano Zampini comm_n = comm; 612028143c3dSStefano Zampini } 612128143c3dSStefano Zampini 6122e7931f94SStefano Zampini /* prepare send/receive buffers */ 6123785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 6124e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 6125785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 6126e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 612728143c3dSStefano Zampini if (nis) { 6128854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 612928143c3dSStefano Zampini } 6130e7931f94SStefano Zampini 613128143c3dSStefano Zampini /* Get data from local matrices */ 61326c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 6133e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 6134e7931f94SStefano Zampini /* 6135e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 6136e7931f94SStefano Zampini send_buffer_idxs should contain: 6137e7931f94SStefano Zampini - MatType_PRIVATE type 6138e7931f94SStefano Zampini - PetscInt size_of_l2gmap 6139e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 6140e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 6141e7931f94SStefano Zampini */ 61426c4ed002SBarry Smith else { 6143e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 61443bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 6145854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 6146e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 6147e7931f94SStefano Zampini send_buffer_idxs[1] = i; 61483bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6149e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 61503bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6151e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 6152e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6153e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 6154e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 6155c8587f34SStefano Zampini } 6156c8587f34SStefano Zampini } 6157e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 615828143c3dSStefano Zampini /* additional is (if any) */ 615928143c3dSStefano Zampini if (nis) { 616028143c3dSStefano Zampini PetscMPIInt psum; 616128143c3dSStefano Zampini PetscInt j; 616228143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 616328143c3dSStefano Zampini PetscInt plen; 616428143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 616528143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 616628143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 616728143c3dSStefano Zampini } 6168854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 616928143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 617028143c3dSStefano Zampini PetscInt plen; 617128143c3dSStefano Zampini const PetscInt *is_array_idxs; 617228143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 617328143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 617428143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 617528143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 617628143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 617728143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 617828143c3dSStefano Zampini } 617928143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 618028143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 618128143c3dSStefano Zampini } 618228143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 618328143c3dSStefano Zampini } 618428143c3dSStefano Zampini 6185e7931f94SStefano Zampini buf_size_idxs = 0; 6186e7931f94SStefano Zampini buf_size_vals = 0; 618728143c3dSStefano Zampini buf_size_idxs_is = 0; 61881ae86dd6SStefano Zampini buf_size_vecs = 0; 6189e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6190e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 6191e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 619228143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 61931ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 6194e7931f94SStefano Zampini } 6195785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 6196785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 619795ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 61981ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 6199e7931f94SStefano Zampini 6200e7931f94SStefano Zampini /* get new tags for clean communications */ 6201e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 6202e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 620328143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 62041ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 6205e7931f94SStefano Zampini 6206e7931f94SStefano Zampini /* allocate for requests */ 6207785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 6208785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 620995ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 62101ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 6211785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 6212785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 621395ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 62141ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 6215e7931f94SStefano Zampini 6216e7931f94SStefano Zampini /* communications */ 6217e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6218e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 621928143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 62201ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 6221e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6222e7931f94SStefano Zampini source_dest = onodes[i]; 6223e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 6224e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 6225e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6226e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 622728143c3dSStefano Zampini if (nis) { 622857de7509SStefano Zampini source_dest = onodes_is[i]; 622928143c3dSStefano 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); 623028143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 623128143c3dSStefano Zampini } 62321ae86dd6SStefano Zampini if (nvecs) { 62331ae86dd6SStefano Zampini source_dest = onodes[i]; 62341ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 62351ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 62361ae86dd6SStefano Zampini } 6237e7931f94SStefano Zampini } 6238e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6239e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 6240e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 6241e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 624228143c3dSStefano Zampini if (nis) { 624328143c3dSStefano 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); 624428143c3dSStefano Zampini } 62451ae86dd6SStefano Zampini if (nvecs) { 62461ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 62471ae86dd6SStefano 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); 62481ae86dd6SStefano Zampini } 6249e7931f94SStefano Zampini } 6250e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6251e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 6252e7931f94SStefano Zampini 6253e7931f94SStefano Zampini /* assemble new l2g map */ 6254e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6255e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 62569d30be91SStefano Zampini new_local_rows = 0; 6257e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 62589d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6259e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6260e7931f94SStefano Zampini } 62619d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 6262e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 62639d30be91SStefano Zampini new_local_rows = 0; 6264e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 62659d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 62669d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6267e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6268e7931f94SStefano Zampini } 62699d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 62709d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 6271e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 6272e7931f94SStefano Zampini 6273e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 6274e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 6275e7931f94SStefano 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) */ 6276e7931f94SStefano Zampini if (n_recvs) { 627728143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 6278e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6279e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6280e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 6281e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 6282e7931f94SStefano Zampini break; 6283e7931f94SStefano Zampini } 6284e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6285e7931f94SStefano Zampini } 6286e7931f94SStefano Zampini switch (new_local_type_private) { 628728143c3dSStefano Zampini case MATDENSE_PRIVATE: 628828143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 6289e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6290e7931f94SStefano Zampini bs = 1; 629128143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 629228143c3dSStefano Zampini new_local_type = MATSEQDENSE; 629328143c3dSStefano Zampini bs = 1; 629428143c3dSStefano Zampini } 6295e7931f94SStefano Zampini break; 6296e7931f94SStefano Zampini case MATAIJ_PRIVATE: 6297e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6298e7931f94SStefano Zampini bs = 1; 6299e7931f94SStefano Zampini break; 6300e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 6301e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 6302e7931f94SStefano Zampini break; 6303e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 6304e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 6305e7931f94SStefano Zampini break; 6306e7931f94SStefano Zampini default: 63079d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 6308e7931f94SStefano Zampini break; 6309e7931f94SStefano Zampini } 631028143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 631128143c3dSStefano Zampini new_local_type = MATSEQDENSE; 631228143c3dSStefano Zampini bs = 1; 6313e7931f94SStefano Zampini } 6314e7931f94SStefano Zampini 631570cf5478SStefano Zampini /* create MATIS object if needed */ 631657de7509SStefano Zampini if (!reuse) { 6317e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 6318e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 631970cf5478SStefano Zampini } else { 632070cf5478SStefano Zampini /* it also destroys the local matrices */ 632157de7509SStefano Zampini if (*mat_n) { 632270cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 632357de7509SStefano Zampini } else { /* this is a fake object */ 632457de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 632557de7509SStefano Zampini } 632670cf5478SStefano Zampini } 632770cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 6328e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 63299d30be91SStefano Zampini 63309d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 63319d30be91SStefano Zampini 63329d30be91SStefano Zampini /* Global to local map of received indices */ 63339d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 63349d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 63359d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 63369d30be91SStefano Zampini 63379d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 63389d30be91SStefano Zampini buf_size_idxs = 0; 63399d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 63409d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 63419d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 63429d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 63439d30be91SStefano Zampini } 63449d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 63459d30be91SStefano Zampini 63469d30be91SStefano Zampini /* set preallocation */ 63479d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 63489d30be91SStefano Zampini if (!newisdense) { 63499d30be91SStefano Zampini PetscInt *new_local_nnz=0; 63509d30be91SStefano Zampini 63519d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 63529d30be91SStefano Zampini if (n_recvs) { 63539d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 63549d30be91SStefano Zampini } 63559d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 63569d30be91SStefano Zampini PetscInt j; 63579d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 63589d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 63599d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 63609d30be91SStefano Zampini } 63619d30be91SStefano Zampini } else { 63629d30be91SStefano Zampini /* TODO */ 63639d30be91SStefano Zampini } 63649d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 63659d30be91SStefano Zampini } 63669d30be91SStefano Zampini if (new_local_nnz) { 63679d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 63689d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 63699d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 63709d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 63719d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 63729d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 63739d30be91SStefano Zampini } else { 63749d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 63759d30be91SStefano Zampini } 63769d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 63779d30be91SStefano Zampini } else { 63789d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 63799d30be91SStefano Zampini } 6380e7931f94SStefano Zampini 6381e7931f94SStefano Zampini /* set values */ 6382e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 63839d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 6384e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6385e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 6386e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 63879d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 6388e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6389e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6390e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 639128143c3dSStefano Zampini } else { 639228143c3dSStefano Zampini /* TODO */ 6393e7931f94SStefano Zampini } 6394e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6395e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 6396e7931f94SStefano Zampini } 6397e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6398e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 639970cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 640070cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 64019d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 6402e7931f94SStefano Zampini 6403dfd14d43SStefano Zampini #if 0 640428143c3dSStefano Zampini if (!restrict_comm) { /* check */ 6405e7931f94SStefano Zampini Vec lvec,rvec; 6406e7931f94SStefano Zampini PetscReal infty_error; 6407e7931f94SStefano Zampini 64082a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 6409e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 6410e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 6411e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 641270cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 6413e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 6414e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 6415e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 6416e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 6417e7931f94SStefano Zampini } 641828143c3dSStefano Zampini #endif 6419e7931f94SStefano Zampini 642028143c3dSStefano Zampini /* assemble new additional is (if any) */ 642128143c3dSStefano Zampini if (nis) { 642228143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 642328143c3dSStefano Zampini 642428143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6425854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 642628143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 642728143c3dSStefano Zampini psum = 0; 642828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 642928143c3dSStefano Zampini for (j=0;j<nis;j++) { 643028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 643128143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 643228143c3dSStefano Zampini psum += plen; 643328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 643428143c3dSStefano Zampini } 643528143c3dSStefano Zampini } 6436854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 6437854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 643828143c3dSStefano Zampini for (i=1;i<nis;i++) { 643928143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 644028143c3dSStefano Zampini } 644128143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 644228143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 644328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 644428143c3dSStefano Zampini for (j=0;j<nis;j++) { 644528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 644628143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 644728143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 644828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 644928143c3dSStefano Zampini } 645028143c3dSStefano Zampini } 645128143c3dSStefano Zampini for (i=0;i<nis;i++) { 645228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 645328143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 645428143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 645528143c3dSStefano Zampini } 645628143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 645728143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 645828143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 645928143c3dSStefano Zampini } 6460e7931f94SStefano Zampini /* free workspace */ 646128143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 6462e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6463e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 6464e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6465e7931f94SStefano Zampini if (isdense) { 6466e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6467e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 6468e7931f94SStefano Zampini } else { 6469e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 6470e7931f94SStefano Zampini } 647128143c3dSStefano Zampini if (nis) { 647228143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 647328143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 647428143c3dSStefano Zampini } 64751ae86dd6SStefano Zampini 64761ae86dd6SStefano Zampini if (nvecs) { 64771ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 64781ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 64791ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 64801ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 64811ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 64821ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 64831ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 64841ae86dd6SStefano Zampini /* set values */ 64851ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 64861ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 64871ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 64881ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 64891ae86dd6SStefano Zampini PetscInt j; 64901ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 64911ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 64921ae86dd6SStefano Zampini } 64931ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 64941ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 64951ae86dd6SStefano Zampini } 64961ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 64971ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 64981ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 64991ae86dd6SStefano Zampini } 65001ae86dd6SStefano Zampini 65011ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 65021ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 6503e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 6504e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 65051ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 650628143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 6507e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 6508e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 65091ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 651028143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 6511e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 6512e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 6513e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 6514e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 6515e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 651628143c3dSStefano Zampini if (nis) { 651728143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 651828143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 651928143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 652028143c3dSStefano Zampini } 652128143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 652228143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 652328143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 652428143c3dSStefano Zampini for (i=0;i<nis;i++) { 652528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 652628143c3dSStefano Zampini } 65271ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 65281ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 65291ae86dd6SStefano Zampini } 653053a05cb3SStefano Zampini *mat_n = NULL; 653128143c3dSStefano Zampini } 6532e7931f94SStefano Zampini PetscFunctionReturn(0); 6533e7931f94SStefano Zampini } 6534a57a6d2fSStefano Zampini 653512edc857SStefano Zampini /* temporary hack into ksp private data structure */ 6536af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 653712edc857SStefano Zampini 6538c8587f34SStefano Zampini #undef __FUNCT__ 6539c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 6540c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 6541c8587f34SStefano Zampini { 6542c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6543c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 654420a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 65451ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 65469881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 654720a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 65486e683305SStefano Zampini IS coarse_is,*isarray; 65496e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 655030368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 6551f9eb5b7dSStefano Zampini PC pc_temp; 6552c8587f34SStefano Zampini PCType coarse_pc_type; 6553c8587f34SStefano Zampini KSPType coarse_ksp_type; 6554f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 65554f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 65566e683305SStefano Zampini Mat t_coarse_mat_is; 655757de7509SStefano Zampini PetscInt ncoarse; 655868457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 655922bc73bbSStefano Zampini PetscScalar *array; 656057de7509SStefano Zampini MatReuse coarse_mat_reuse; 656157de7509SStefano Zampini PetscBool restr, full_restr, have_void; 65629881197aSStefano Zampini PetscErrorCode ierr; 6563fdc09c96SStefano Zampini 6564c8587f34SStefano Zampini PetscFunctionBegin; 6565c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 656668457ee5SStefano 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 */ 6567fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 65685a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 6569fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 6570f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 6571f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 6572f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 6573fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 657451bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 657551bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 6576dc4bcba2SStefano Zampini PC pc; 6577dc4bcba2SStefano Zampini PetscBool isbddc; 6578dc4bcba2SStefano Zampini 6579dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 6580dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 6581dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 6582dc4bcba2SStefano Zampini if (isbddc) { 658363c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 658463c961adSStefano Zampini } else { 6585727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 658663c961adSStefano Zampini } 6587fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 6588fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 6589fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 6590f4ddd8eeSStefano Zampini } 6591fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 6592fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 6593f4ddd8eeSStefano Zampini } 659470cf5478SStefano Zampini /* reset any subassembling information */ 659557de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 659670cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 659757de7509SStefano Zampini } 65986e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 6599fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 6600f4ddd8eeSStefano Zampini } 660157de7509SStefano Zampini /* assemble coarse matrix */ 660257de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 660357de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 660457de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 660557de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 660618a45a71SStefano Zampini } else { 660757de7509SStefano Zampini coarse_mat = NULL; 660857de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 66096e683305SStefano Zampini } 6610e7931f94SStefano Zampini 6611abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 6612abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 6613abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 6614abbbba34SStefano Zampini 6615abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 661622bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 661722bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 661822bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 661922bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 6620e176bc59SStefano 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); 66216e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 66226e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 66236e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6624abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 6625abbbba34SStefano Zampini 662657de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 662757de7509SStefano Zampini im_active = !!(pcis->n); 662857de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 662957de7509SStefano Zampini 663014f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 663157de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 663257de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 663357de7509SStefano Zampini coarse_mat_is = NULL; 663457de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 663557de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 663657de7509SStefano Zampini full_restr = PETSC_TRUE; 66371ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 663857de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 663957de7509SStefano Zampini if (multilevel_requested) { 664057de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 664157de7509SStefano Zampini restr = PETSC_FALSE; 664257de7509SStefano Zampini full_restr = PETSC_FALSE; 664357de7509SStefano Zampini } else { 664457de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 664557de7509SStefano Zampini restr = PETSC_TRUE; 664657de7509SStefano Zampini full_restr = PETSC_TRUE; 664757de7509SStefano Zampini } 66484b2aedd3SStefano Zampini if (!pcbddc->coarse_size) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 664957de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 665057de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 6651a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 665257de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 6653a198735bSStefano Zampini } else { 6654a198735bSStefano Zampini PetscMPIInt size,rank; 6655a198735bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 6656a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 6657a198735bSStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 6658a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 6659a198735bSStefano Zampini } 666057de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 666157de7509SStefano Zampini PetscInt psum; 666257de7509SStefano Zampini PetscMPIInt size; 666357de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 666457de7509SStefano Zampini else psum = 0; 666557de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 666657de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 666757de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 666857de7509SStefano Zampini } 666957de7509SStefano Zampini /* determine if we can go multilevel */ 667057de7509SStefano Zampini if (multilevel_requested) { 667157de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 667257de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 667357de7509SStefano Zampini } 667457de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 667557de7509SStefano Zampini 6676e4d548c7SStefano Zampini /* dump subassembling pattern */ 6677e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 6678e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 6679e4d548c7SStefano Zampini } 6680e4d548c7SStefano Zampini 66816e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 668227b6a85dSStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal)) { /* protects from unneded computations */ 66836e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 66846e683305SStefano Zampini const PetscInt *idxs; 66856e683305SStefano Zampini ISLocalToGlobalMapping tmap; 66866e683305SStefano Zampini 66876e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 66880be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 66896e683305SStefano Zampini /* allocate space for temporary storage */ 6690854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 6691854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 66926e683305SStefano Zampini /* allocate for IS array */ 66936e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 66946e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 669527b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 669630368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 6697854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 66986e683305SStefano Zampini /* dofs splitting */ 66996e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 67006e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 67016e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 67026e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 67036e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 67046e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 67056e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 670630368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 67076e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 67086e683305SStefano Zampini } 67096e683305SStefano Zampini /* neumann boundaries */ 67106e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 67116e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 67126e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 67136e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 67146e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 67156e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 67166e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 671730368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 67186e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 67196e683305SStefano Zampini } 67206e683305SStefano Zampini /* free memory */ 67216e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 67226e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 67236e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 67246e683305SStefano Zampini } else { 67256e683305SStefano Zampini nis = 0; 67266e683305SStefano Zampini nisdofs = 0; 67276e683305SStefano Zampini nisneu = 0; 672830368db7SStefano Zampini nisvert = 0; 67296e683305SStefano Zampini isarray = NULL; 67306e683305SStefano Zampini } 67316e683305SStefano Zampini /* destroy no longer needed map */ 67326e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 67336e683305SStefano Zampini 673457de7509SStefano Zampini /* subassemble */ 673557de7509SStefano Zampini if (multilevel_allowed) { 67361ae86dd6SStefano Zampini Vec vp[1]; 67371ae86dd6SStefano Zampini PetscInt nvecs = 0; 673857de7509SStefano Zampini PetscBool reuse,reuser; 67391ae86dd6SStefano Zampini 674057de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 674157de7509SStefano Zampini else reuse = PETSC_FALSE; 674257de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 67431ae86dd6SStefano Zampini vp[0] = NULL; 67441ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 67451ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 67461ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 67471ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 67481ae86dd6SStefano Zampini nvecs = 1; 67491ae86dd6SStefano Zampini 67501ae86dd6SStefano Zampini if (pcbddc->divudotp) { 6751a198735bSStefano Zampini Mat B,loc_divudotp; 67521ae86dd6SStefano Zampini Vec v,p; 67531ae86dd6SStefano Zampini IS dummy; 67541ae86dd6SStefano Zampini PetscInt np; 67551ae86dd6SStefano Zampini 6756a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 6757a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 67581ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 6759a198735bSStefano Zampini ierr = MatGetSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 67601ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 67611ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 67621ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 67631ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 67641ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 67651ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 67661ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 67671ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 67681ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 67691ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 67701ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 67711ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 677274e2c79eSStefano Zampini } 67731ae86dd6SStefano Zampini } 67741ae86dd6SStefano Zampini if (reuser) { 67751ae86dd6SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 677674e2c79eSStefano Zampini } else { 67771ae86dd6SStefano 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); 67781ae86dd6SStefano Zampini } 67791ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 67801ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 67811ae86dd6SStefano Zampini PetscInt nl; 67821ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 67831ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 67841ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 67851ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 67861ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 67871ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 67881ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 67891ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 6790a198735bSStefano Zampini } else { 6791a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 67921ae86dd6SStefano Zampini } 67931ae86dd6SStefano Zampini } else { 67941ae86dd6SStefano 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); 67956e683305SStefano Zampini } 679657de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 679757de7509SStefano Zampini PetscMPIInt size; 679857de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size); 679957de7509SStefano Zampini if (!multilevel_allowed) { 680057de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 68016e683305SStefano Zampini } else { 680257de7509SStefano Zampini Mat A; 6803779c1cceSStefano Zampini 680457de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 680557de7509SStefano Zampini if (coarse_mat_is) { 680657de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 680757de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 680857de7509SStefano Zampini coarse_mat = coarse_mat_is; 680957de7509SStefano Zampini } 681057de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 681157de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 681257de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 6813779c1cceSStefano Zampini } 6814779c1cceSStefano Zampini } 681557de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 681657de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 68176e683305SStefano Zampini 68186e683305SStefano Zampini /* create local to global scatters for coarse problem */ 681968457ee5SStefano Zampini if (compute_vecs) { 68206e683305SStefano Zampini PetscInt lrows; 68216e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 682257de7509SStefano Zampini if (coarse_mat) { 682357de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 68246e683305SStefano Zampini } else { 68256e683305SStefano Zampini lrows = 0; 68266e683305SStefano Zampini } 68276e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 68286e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 68296e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 68306e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 68316e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 68326e683305SStefano Zampini } 68336e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 6834c8587f34SStefano Zampini 6835f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 6836f9eb5b7dSStefano Zampini if (multilevel_allowed) { 6837f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 6838f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 6839f9eb5b7dSStefano Zampini } else { 6840f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 6841f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 6842c8587f34SStefano Zampini } 6843c8587f34SStefano Zampini 68446e683305SStefano Zampini /* print some info if requested */ 68456e683305SStefano Zampini if (pcbddc->dbg_flag) { 68466e683305SStefano Zampini if (!multilevel_allowed) { 68476e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 68486e683305SStefano Zampini if (multilevel_requested) { 68496e683305SStefano 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); 68506e683305SStefano Zampini } else if (pcbddc->max_levels) { 68516e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 68526e683305SStefano Zampini } 68536e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 68546e683305SStefano Zampini } 68556e683305SStefano Zampini } 68566e683305SStefano Zampini 6857f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 685857de7509SStefano Zampini if (coarse_mat) { 68596a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 68606e683305SStefano Zampini if (pcbddc->dbg_flag) { 686157de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 68626e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 68636e683305SStefano Zampini } 6864f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 6865312be037SStefano Zampini char prefix[256],str_level[16]; 6866e604994aSStefano Zampini size_t len; 686757de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 6868422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 6869c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 6870f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 687157de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 6872c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 68736e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 6874c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 6875c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 6876e604994aSStefano Zampini /* prefix */ 6877e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 6878e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 6879e604994aSStefano Zampini if (!pcbddc->current_level) { 6880e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 6881e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 6882c8587f34SStefano Zampini } else { 6883e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 6884312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 6885312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 688634d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 6887312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 6888e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 6889e604994aSStefano Zampini } 6890e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 68913e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 68923e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 68933e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 68943e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 6895f9eb5b7dSStefano Zampini /* allow user customization */ 6896f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 68973e3c6dadSStefano Zampini } 68983e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 689951bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 69003e3c6dadSStefano Zampini if (nisdofs) { 69013e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 69023e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 69033e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 69043e3c6dadSStefano Zampini } 69053e3c6dadSStefano Zampini } 69063e3c6dadSStefano Zampini if (nisneu) { 69073e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 69083e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 6909312be037SStefano Zampini } 691030368db7SStefano Zampini if (nisvert) { 691130368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 691230368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 691330368db7SStefano Zampini } 6914f9eb5b7dSStefano Zampini 6915f9eb5b7dSStefano Zampini /* get some info after set from options */ 6916f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 6917f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 69184f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 69196e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 6920f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 6921f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 6922f9eb5b7dSStefano Zampini } 692339f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 69244f3a063dSStefano Zampini if (isredundant) { 69254f3a063dSStefano Zampini KSP inner_ksp; 69264f3a063dSStefano Zampini PC inner_pc; 69274f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 69284f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 69294f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 69304f3a063dSStefano Zampini } 6931f9eb5b7dSStefano Zampini 693257de7509SStefano Zampini /* parameters which miss an API */ 693357de7509SStefano Zampini if (isbddc) { 6934720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 6935720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 693657de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 693727b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 693827b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 6939a198735bSStefano Zampini Mat coarsedivudotp_is; 6940a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 6941a198735bSStefano Zampini IS row,col; 6942a198735bSStefano Zampini const PetscInt *gidxs; 6943a198735bSStefano Zampini PetscInt n,st,M,N; 6944a198735bSStefano Zampini 6945a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 6946a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 6947a198735bSStefano Zampini st = st-n; 6948a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 6949a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 6950a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 6951a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 6952a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 6953a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 6954a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 6955a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 6956a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 6957a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 6958a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 6959a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 6960a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 6961a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 6962a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 6963a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 6964a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 6965a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 6966a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 6967a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 69688ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 6969a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 6970720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 697159e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 6972720d30f9SStefano Zampini } 6973d4d8cf7bSStefano Zampini } 69749881197aSStefano Zampini 69753301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 69765a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 69773301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 69783301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 69793301b35fSStefano Zampini } 69803301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 69813301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 69823301b35fSStefano Zampini } 69833301b35fSStefano Zampini if (pc->pmat->spd_set) { 69843301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 69853301b35fSStefano Zampini } 698627b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 698727b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 698827b6a85dSStefano Zampini } 69896e683305SStefano Zampini /* set operators */ 69905f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 69916e683305SStefano Zampini if (pcbddc->dbg_flag) { 69926e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 69936e683305SStefano Zampini } 69946e683305SStefano Zampini } 69956e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 6996b1ecc7b1SStefano Zampini #if 0 6997b9b85e73SStefano Zampini { 6998b9b85e73SStefano Zampini PetscViewer viewer; 6999b9b85e73SStefano Zampini char filename[256]; 7000b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 7001b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 70026a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 7003b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 7004f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 7005b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 7006b9b85e73SStefano Zampini } 7007b9b85e73SStefano Zampini #endif 7008f9eb5b7dSStefano Zampini 700998a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 701098a51de6SStefano Zampini Vec crhs,csol; 701104708bb6SStefano Zampini 7012f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 7013f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 7014f347579bSStefano Zampini if (!csol) { 70152a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 7016f9eb5b7dSStefano Zampini } 7017f347579bSStefano Zampini if (!crhs) { 70182a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 7019f347579bSStefano Zampini } 7020b0f5fe93SStefano Zampini } 70211ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 7022b0f5fe93SStefano Zampini 7023b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 7024b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 7025b0f5fe93SStefano Zampini 7026b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 70274f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 70284f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 70294f1b2e48SStefano Zampini } 7030b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 7031b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 7032b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7033b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7034b0f5fe93SStefano Zampini if (coarse_mat) { 7035b0f5fe93SStefano Zampini Vec nullv; 7036b0f5fe93SStefano Zampini PetscScalar *array,*array2; 7037b0f5fe93SStefano Zampini PetscInt nl; 7038b0f5fe93SStefano Zampini 7039b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 7040b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 7041b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7042b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 7043b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 7044b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 7045b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7046b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 7047b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 7048b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 7049b0f5fe93SStefano Zampini } 7050b0f5fe93SStefano Zampini } 7051b0f5fe93SStefano Zampini 7052b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 7053b0f5fe93SStefano Zampini PetscBool ispreonly; 7054b0f5fe93SStefano Zampini 7055b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7056b0f5fe93SStefano Zampini PetscBool isnull; 7057b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 7058bef83e63SStefano Zampini if (isnull) { 7059b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 7060b0f5fe93SStefano Zampini } 7061bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 7062b0f5fe93SStefano Zampini } 7063b0f5fe93SStefano Zampini /* setup coarse ksp */ 7064b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 7065cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 7066cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 70676e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 7068c8587f34SStefano Zampini KSP check_ksp; 70692b510759SStefano Zampini KSPType check_ksp_type; 7070c8587f34SStefano Zampini PC check_pc; 70716e683305SStefano Zampini Vec check_vec,coarse_vec; 70726a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 70732b510759SStefano Zampini PetscInt its; 70746e683305SStefano Zampini PetscBool compute_eigs; 70756e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 70766e683305SStefano Zampini PetscInt neigs; 70778e185a42SStefano Zampini const char *prefix; 7078c8587f34SStefano Zampini 70792b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 70806e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 7081422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 708223ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7083f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 7084e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 7085e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 7086e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 70872b510759SStefano Zampini if (ispreonly) { 70882b510759SStefano Zampini check_ksp_type = KSPPREONLY; 70896e683305SStefano Zampini compute_eigs = PETSC_FALSE; 70902b510759SStefano Zampini } else { 7091cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 70926e683305SStefano Zampini compute_eigs = PETSC_TRUE; 7093c8587f34SStefano Zampini } 7094c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 70956e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 70966e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 70976e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 7098a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 7099a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 7100a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 7101a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 7102c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 7103c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 7104c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 7105c8587f34SStefano Zampini /* create random vec */ 71062701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 7107c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 71086e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 7109c8587f34SStefano Zampini /* solve coarse problem */ 71106e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 7111cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 71126e683305SStefano Zampini if (compute_eigs) { 7113854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 7114854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 71156e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 71161ae86dd6SStefano Zampini if (neigs) { 71176e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 71186e683305SStefano Zampini lambda_min = eigs_r[0]; 71196e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 71202701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 71212701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 7122cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 7123cbcc2c2aSStefano Zampini } 7124c8587f34SStefano Zampini } 7125c8587f34SStefano Zampini } 71261ae86dd6SStefano Zampini } 7127cbcc2c2aSStefano Zampini 7128c8587f34SStefano Zampini /* check coarse problem residual error */ 71296e683305SStefano Zampini if (pcbddc->dbg_flag) { 71306e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 71316e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 71326e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 7133c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 71346e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 71356e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 7136779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 71376e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 71386e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 71396e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 71406e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 7141b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7142b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 7143b0f5fe93SStefano Zampini } 71446e683305SStefano Zampini if (compute_eigs) { 71456e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 7146deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 7147c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 71486e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 71496e683305SStefano 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); 71506e683305SStefano Zampini for (i=0;i<neigs;i++) { 71516e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 7152c8587f34SStefano Zampini } 71536e683305SStefano Zampini } 71546e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 71556e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 71566e683305SStefano Zampini } 7157e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 71582701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 7159c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 71606e683305SStefano Zampini if (compute_eigs) { 71616e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 71626e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 7163c8587f34SStefano Zampini } 71646e683305SStefano Zampini } 71656e683305SStefano Zampini } 7166bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 7167cbcc2c2aSStefano Zampini /* print additional info */ 7168cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 71696e683305SStefano Zampini /* waits until all processes reaches this point */ 71706e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 7171cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 7172cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7173cbcc2c2aSStefano Zampini } 7174cbcc2c2aSStefano Zampini 71752b510759SStefano Zampini /* free memory */ 7176fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 7177c8587f34SStefano Zampini PetscFunctionReturn(0); 7178c8587f34SStefano Zampini } 7179674ae819SStefano Zampini 7180f34684f1SStefano Zampini #undef __FUNCT__ 7181f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 7182f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 7183f34684f1SStefano Zampini { 7184f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7185f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 7186f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 7187dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 7188dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 718973be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 7190dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 7191f34684f1SStefano Zampini PetscErrorCode ierr; 7192f34684f1SStefano Zampini 7193f34684f1SStefano Zampini PetscFunctionBegin; 7194f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 71956c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 7196dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 71973bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 7198dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7199dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 72006583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 7201dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 7202dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 7203dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 72046c4ed002SBarry 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); 7205dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 7206dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7207dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 7208dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7209dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7210f34684f1SStefano Zampini 7211f34684f1SStefano Zampini /* check numbering */ 7212f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 7213019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 7214dc456d91SStefano Zampini PetscInt i; 7215b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 7216f34684f1SStefano Zampini 7217f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7218f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 7219f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 72201575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7221019a44ceSStefano Zampini /* counter */ 7222019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7223019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 7224019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7225019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7226019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7227019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7228f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 7229f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 7230727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 7231f34684f1SStefano Zampini } 7232f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7233f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7234f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7235e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7236e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7237e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7238e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7239f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7240019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7241f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7242019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 72432c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 724475c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 7245b9b85e73SStefano Zampini set_error = PETSC_TRUE; 72462c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 72472c66d082SStefano 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); 7248f34684f1SStefano Zampini } 7249f34684f1SStefano Zampini } 7250019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7251b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 7252f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7253f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7254f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 7255f34684f1SStefano Zampini } 7256f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7257f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7258e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7259e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7260f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 7261f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 7262b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 7263ca8b9ea9SStefano Zampini PetscInt *gidxs; 7264ca8b9ea9SStefano Zampini 7265ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 72663bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 7267f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 7268f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7269f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 7270f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 72714bc2dc4bSStefano 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); 7272f34684f1SStefano Zampini } 7273f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7274ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 7275f34684f1SStefano Zampini } 7276f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 72771575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7278302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 7279f34684f1SStefano Zampini } 72808bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 7281f34684f1SStefano Zampini /* get back data */ 7282f34684f1SStefano Zampini *coarse_size_n = coarse_size; 7283f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 7284674ae819SStefano Zampini PetscFunctionReturn(0); 7285674ae819SStefano Zampini } 7286674ae819SStefano Zampini 7287e456f2a8SStefano Zampini #undef __FUNCT__ 7288e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 7289a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 7290e456f2a8SStefano Zampini { 7291e456f2a8SStefano Zampini IS localis_t; 7292a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 7293e456f2a8SStefano Zampini PetscScalar *vals; 7294e456f2a8SStefano Zampini PetscErrorCode ierr; 7295e456f2a8SStefano Zampini 7296e456f2a8SStefano Zampini PetscFunctionBegin; 7297a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 7298e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 7299854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 7300e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 7301e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7302a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 7303a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 73041035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 7305a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 73061035eff8SStefano Zampini } 7307a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 7308e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7309e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 7310a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 7311a7dc3881SStefano Zampini /* now compute set in local ordering */ 7312a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7313a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7314a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7315a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 7316a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7317ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7318e456f2a8SStefano Zampini lsize++; 7319e456f2a8SStefano Zampini } 7320e456f2a8SStefano Zampini } 7321854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 7322a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7323ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7324e456f2a8SStefano Zampini idxs[lsize++] = i; 7325e456f2a8SStefano Zampini } 7326e456f2a8SStefano Zampini } 7327a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7328a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 7329e456f2a8SStefano Zampini *localis = localis_t; 7330e456f2a8SStefano Zampini PetscFunctionReturn(0); 7331e456f2a8SStefano Zampini } 7332906d46d4SStefano Zampini 7333b96c3477SStefano Zampini #undef __FUNCT__ 7334b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 733508122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 7336b96c3477SStefano Zampini { 7337a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7338b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7339b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 7340a64f4aa4SStefano Zampini Mat S_j; 7341b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 7342b96c3477SStefano Zampini PetscBool free_used_adj; 7343b96c3477SStefano Zampini PetscErrorCode ierr; 7344b96c3477SStefano Zampini 7345b96c3477SStefano Zampini PetscFunctionBegin; 7346b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 7347b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 734808122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 7349b96c3477SStefano Zampini used_xadj = NULL; 7350b96c3477SStefano Zampini used_adjncy = NULL; 7351b96c3477SStefano Zampini } else { 735208122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 735308122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 735408122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 735508122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 7356b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 7357b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 7358b96c3477SStefano Zampini } else { 73592fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 7360b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 7361b96c3477SStefano Zampini PetscInt nvtxs; 7362b96c3477SStefano Zampini 73632fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 73642fffb893SStefano Zampini if (flg_row) { 7365b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 7366b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 7367b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 7368b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 73692fffb893SStefano Zampini } else { 73702fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 73712fffb893SStefano Zampini used_xadj = NULL; 73722fffb893SStefano Zampini used_adjncy = NULL; 73732fffb893SStefano Zampini } 73742fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 7375b96c3477SStefano Zampini } 7376b96c3477SStefano Zampini } 7377d5574798SStefano Zampini 7378d5574798SStefano Zampini /* setup sub_schurs data */ 7379a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 7380df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 7381df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 7382a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 738391af6908SStefano 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); 7384a64f4aa4SStefano Zampini } else { 73856816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 73864d7f8f00SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE; 7387a3df083aSStefano Zampini PetscInt benign_n; 738872b8c272SStefano Zampini Mat change = NULL; 73899d54b7f4SStefano Zampini Vec scaling = NULL; 739072b8c272SStefano Zampini IS change_primal = NULL; 7391a3df083aSStefano Zampini 73925feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 73935feab87aSStefano Zampini PetscInt n_vertices; 73945feab87aSStefano Zampini 73955feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 73962034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 73975feab87aSStefano Zampini } 739804708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 739904708bb6SStefano Zampini if (!isseqaij) { 740004708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 740104708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 740204708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 740304708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 740404708bb6SStefano Zampini } else { 7405511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 740604708bb6SStefano Zampini } 740704708bb6SStefano Zampini } 7408a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 7409a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 7410ca92afb2SStefano Zampini } else { 7411a3df083aSStefano Zampini benign_n = 0; 7412ca92afb2SStefano Zampini } 7413b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 7414b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 7415b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 741672b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 741722db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 7418b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 741922db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 7420b7ab4a40SStefano Zampini } 7421b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 7422b7ab4a40SStefano 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 */ 7423b7ab4a40SStefano Zampini if (need_change) { 742488c03ad3SStefano Zampini PC_IS *pcisf; 742588c03ad3SStefano Zampini PC_BDDC *pcbddcf; 742688c03ad3SStefano Zampini PC pcf; 742788c03ad3SStefano Zampini 7428e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 742988c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 743088c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 743188c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 743288c03ad3SStefano Zampini /* hacks */ 743388c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 743472b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 743572b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 743672b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 743772b8c272SStefano Zampini pcisf->n = pcis->n; 743872b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 743988c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 744088c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 744188c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 744288c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 744388c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 744488c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 744572b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 744688c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 744788c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 744872b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 744972b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 745072b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 745172b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 745272b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 745388c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 745472b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 745588c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 745688c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 745788c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 745888c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 745988c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 746088c03ad3SStefano Zampini pcf->ops->destroy = NULL; 746188c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 746288c03ad3SStefano Zampini } 74639d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 746491af6908SStefano 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); 746572b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 746672b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 7467ca92afb2SStefano Zampini } 7468d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 7469b96c3477SStefano Zampini 7470b96c3477SStefano Zampini /* free adjacency */ 7471b96c3477SStefano Zampini if (free_used_adj) { 7472b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 7473b96c3477SStefano Zampini } 7474b96c3477SStefano Zampini PetscFunctionReturn(0); 7475b96c3477SStefano Zampini } 7476b96c3477SStefano Zampini 7477b96c3477SStefano Zampini #undef __FUNCT__ 7478b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 747908122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 7480b96c3477SStefano Zampini { 7481b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7482b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7483b96c3477SStefano Zampini PCBDDCGraph graph; 7484b96c3477SStefano Zampini PetscErrorCode ierr; 7485b96c3477SStefano Zampini 7486b96c3477SStefano Zampini PetscFunctionBegin; 7487b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 748808122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 74893301b35fSStefano Zampini IS verticesIS,verticescomm; 74903301b35fSStefano Zampini PetscInt vsize,*idxs; 7491b96c3477SStefano Zampini 7492b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 74933301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 74943301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 74953301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 74963301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 7497c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 7498b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 7499be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 7500441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 75013301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 7502b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 7503b96c3477SStefano Zampini } else { 7504b96c3477SStefano Zampini graph = pcbddc->mat_graph; 7505b96c3477SStefano Zampini } 7506e4d548c7SStefano Zampini /* print some info */ 7507e4d548c7SStefano Zampini if (pcbddc->dbg_flag) { 7508e4d548c7SStefano Zampini IS vertices; 7509e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 7510c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 7511e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 7512e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 7513e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7514e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 7515e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 7516e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 7517e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 7518e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7519e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7520c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 7521e4d548c7SStefano Zampini } 7522b96c3477SStefano Zampini 7523b96c3477SStefano Zampini /* sub_schurs init */ 7524b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 7525b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 7526b334f244SStefano Zampini } 7527b334f244SStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 7528a64f4aa4SStefano Zampini 7529b96c3477SStefano Zampini /* free graph struct */ 753008122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 7531b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 7532b96c3477SStefano Zampini } 7533b96c3477SStefano Zampini PetscFunctionReturn(0); 7534b96c3477SStefano Zampini } 7535fa34dd3eSStefano Zampini 7536fa34dd3eSStefano Zampini #undef __FUNCT__ 7537fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 7538fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 7539fa34dd3eSStefano Zampini { 7540fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7541fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7542fa34dd3eSStefano Zampini PetscErrorCode ierr; 7543fa34dd3eSStefano Zampini 7544fa34dd3eSStefano Zampini PetscFunctionBegin; 7545fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 7546fa34dd3eSStefano Zampini IS zerodiag = NULL; 75474f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 7548fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 75494f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 755075c01103SStefano Zampini PetscReal norm; 7551fa34dd3eSStefano Zampini PetscInt i; 7552fa34dd3eSStefano Zampini 7553fa34dd3eSStefano Zampini /* B0 and B0_B */ 7554fa34dd3eSStefano Zampini if (zerodiag) { 7555fa34dd3eSStefano Zampini IS dummy; 7556fa34dd3eSStefano Zampini 75574f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 75584f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 7559fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 7560fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 7561fa34dd3eSStefano Zampini } 7562fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 7563fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 7564fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 7565fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7566fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7567fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7568fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7569fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 7570fa34dd3eSStefano Zampini /* S_j */ 7571fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 7572fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 7573fa34dd3eSStefano Zampini 7574fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 7575fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 7576fa34dd3eSStefano Zampini /* continuous in primal space */ 7577fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 7578fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7579fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7580fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 75814f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 75824f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 7583fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 7584fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7585fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7586fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7587fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7588fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7589fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 7590fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 7591fa34dd3eSStefano Zampini 7592fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 7593fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 7594fa34dd3eSStefano Zampini /* local with Schur */ 7595fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 7596fa34dd3eSStefano Zampini if (zerodiag) { 7597fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 75984f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 7599fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 7600fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 7601fa34dd3eSStefano Zampini } 7602fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 7603fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7604fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7605fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7606fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 7607fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 7608fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 7609fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7610fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 7611fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7612fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7613fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7614fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7615fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7616fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 7617fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 7618fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 7619fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 7620fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7621fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7622fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7623fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7624fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 7625fa34dd3eSStefano Zampini if (zerodiag) { 7626fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 7627fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 76284f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 7629fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 7630fa34dd3eSStefano Zampini } 7631fa34dd3eSStefano Zampini /* BDDC */ 7632fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 7633fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 7634fa34dd3eSStefano Zampini 7635fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 7636fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 7637fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 7638fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 76394f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 76404f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 7641fa34dd3eSStefano Zampini } 76424f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 7643fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 7644fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 7645fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 7646fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 7647fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 7648fa34dd3eSStefano Zampini } 7649fa34dd3eSStefano Zampini PetscFunctionReturn(0); 7650fa34dd3eSStefano Zampini } 7651