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> 5674ae819SStefano Zampini 6906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y); 7906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y); 8906d46d4SStefano Zampini 9a3df083aSStefano Zampini #undef __FUNCT__ 10a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 11a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 12a3df083aSStefano Zampini { 13a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 14a3df083aSStefano Zampini PetscErrorCode ierr; 15a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 16a3df083aSStefano Zampini 17a3df083aSStefano Zampini PetscFunctionBegin; 18a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 19a3df083aSStefano Zampini if (transpose) { 20a3df083aSStefano Zampini apply_right = ctx->apply_left; 21a3df083aSStefano Zampini apply_left = ctx->apply_right; 22a3df083aSStefano Zampini } else { 23a3df083aSStefano Zampini apply_right = ctx->apply_right; 24a3df083aSStefano Zampini apply_left = ctx->apply_left; 25a3df083aSStefano Zampini } 26a3df083aSStefano Zampini reset_x = PETSC_FALSE; 27a3df083aSStefano Zampini if (apply_right) { 28a3df083aSStefano Zampini const PetscScalar *ax; 29a3df083aSStefano Zampini PetscInt nl,i; 30a3df083aSStefano Zampini 31a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 32a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 33a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 34a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 35a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 36a3df083aSStefano Zampini PetscScalar sum,val; 37a3df083aSStefano Zampini const PetscInt *idxs; 38a3df083aSStefano Zampini PetscInt nz,j; 39a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 40a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 41a3df083aSStefano Zampini sum = 0.; 42a3df083aSStefano Zampini if (ctx->apply_p0) { 43a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 44a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 45a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 46a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 47a3df083aSStefano Zampini } 48a3df083aSStefano Zampini } else { 49a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 50a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 51a3df083aSStefano Zampini } 52a3df083aSStefano Zampini } 53a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 54a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 55a3df083aSStefano Zampini } 56a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 57a3df083aSStefano Zampini reset_x = PETSC_TRUE; 58a3df083aSStefano Zampini } 59a3df083aSStefano Zampini if (transpose) { 60a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 61a3df083aSStefano Zampini } else { 62a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 63a3df083aSStefano Zampini } 64a3df083aSStefano Zampini if (reset_x) { 65a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 66a3df083aSStefano Zampini } 67a3df083aSStefano Zampini if (apply_left) { 68a3df083aSStefano Zampini PetscScalar *ay; 69a3df083aSStefano Zampini PetscInt i; 70a3df083aSStefano Zampini 71a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 72a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 73a3df083aSStefano Zampini PetscScalar sum,val; 74a3df083aSStefano Zampini const PetscInt *idxs; 75a3df083aSStefano Zampini PetscInt nz,j; 76a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 77a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 78a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 79a3df083aSStefano Zampini if (ctx->apply_p0) { 80a3df083aSStefano Zampini sum = 0.; 81a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 82a3df083aSStefano Zampini sum += ay[idxs[j]]; 83a3df083aSStefano Zampini ay[idxs[j]] += val; 84a3df083aSStefano Zampini } 85a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 86a3df083aSStefano Zampini } else { 87a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 88a3df083aSStefano Zampini ay[idxs[j]] += val; 89a3df083aSStefano Zampini } 90a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 91a3df083aSStefano Zampini } 92a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 93a3df083aSStefano Zampini } 94a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 95a3df083aSStefano Zampini } 96a3df083aSStefano Zampini PetscFunctionReturn(0); 97a3df083aSStefano Zampini } 98a3df083aSStefano Zampini 99a3df083aSStefano Zampini #undef __FUNCT__ 100a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 101a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 102a3df083aSStefano Zampini { 103a3df083aSStefano Zampini PetscErrorCode ierr; 104a3df083aSStefano Zampini 105a3df083aSStefano Zampini PetscFunctionBegin; 106a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 107a3df083aSStefano Zampini PetscFunctionReturn(0); 108a3df083aSStefano Zampini } 109a3df083aSStefano Zampini 110a3df083aSStefano Zampini #undef __FUNCT__ 111a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 112a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 113a3df083aSStefano Zampini { 114a3df083aSStefano Zampini PetscErrorCode ierr; 115a3df083aSStefano Zampini 116a3df083aSStefano Zampini PetscFunctionBegin; 117a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 118a3df083aSStefano Zampini PetscFunctionReturn(0); 119a3df083aSStefano Zampini } 120a3df083aSStefano Zampini 121a3df083aSStefano Zampini #undef __FUNCT__ 122a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 123a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 124a3df083aSStefano Zampini { 125a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 126a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 127a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 128a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 129a3df083aSStefano Zampini PetscErrorCode ierr; 130a3df083aSStefano Zampini 131a3df083aSStefano Zampini PetscFunctionBegin; 132a3df083aSStefano Zampini if (!restore) { 133a3df083aSStefano Zampini Mat A,A_IB,A_BI; 134a3df083aSStefano Zampini PetscScalar *work; 135df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs->reuse_solver; 136a3df083aSStefano Zampini 137a3df083aSStefano Zampini if (!reuse) { 138a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot setup shell matrices!"); 139a3df083aSStefano Zampini } 140a3df083aSStefano Zampini 141a3df083aSStefano Zampini /* local mat */ 142a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A);CHKERRQ(ierr); 143a3df083aSStefano Zampini ierr = MatSetSizes(A,pcis->n,pcis->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 144a3df083aSStefano Zampini ierr = MatSetType(A,MATSHELL);CHKERRQ(ierr); 145a3df083aSStefano Zampini ierr = MatShellSetOperation(A,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 146a3df083aSStefano Zampini ierr = MatShellSetOperation(A,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 147a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 148a3df083aSStefano Zampini ierr = MatShellSetContext(A,ctx);CHKERRQ(ierr); 149a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 150a3df083aSStefano Zampini ctx->apply_right = PETSC_TRUE; 151a3df083aSStefano Zampini ctx->apply_p0 = PETSC_TRUE; 152a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 153a3df083aSStefano Zampini ctx->benign_zerodiag_subs = pcbddc->benign_zerodiag_subs; 154a3df083aSStefano Zampini ctx->A = matis->A; 155a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 156a3df083aSStefano Zampini ctx->work = work; 157a3df083aSStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 158a3df083aSStefano Zampini ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 159a3df083aSStefano Zampini ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 160a3df083aSStefano Zampini matis->A = A; 161a3df083aSStefano Zampini 162a3df083aSStefano Zampini /* A_IB */ 163a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 164a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 165a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 166a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 167a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 168a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 169a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 170a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 171a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 172a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 173a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 174a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 175a3df083aSStefano Zampini ctx->A = pcis->A_IB; 176a3df083aSStefano Zampini ctx->work = work; 177a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 178a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 180a3df083aSStefano Zampini pcis->A_IB = A_IB; 181a3df083aSStefano Zampini 182a3df083aSStefano Zampini /* A_BI as A_IB^T */ 183a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 184a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 185a3df083aSStefano Zampini pcis->A_BI = A_BI; 186a3df083aSStefano Zampini } else { 187a3df083aSStefano Zampini ierr = MatShellGetContext(matis->A,&ctx);CHKERRQ(ierr); 188a3df083aSStefano Zampini ierr = MatDestroy(&matis->A);CHKERRQ(ierr); 189a3df083aSStefano Zampini matis->A = ctx->A; 190a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 191a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 192a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 193a3df083aSStefano Zampini pcis->A_IB = ctx->A; 194a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 195a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 196a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 197a3df083aSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 198a3df083aSStefano Zampini pcbddc->benign_original_mat = NULL; 199a3df083aSStefano Zampini } 200a3df083aSStefano Zampini PetscFunctionReturn(0); 201a3df083aSStefano Zampini } 202a3df083aSStefano Zampini 203a3df083aSStefano Zampini /* used just in bddc debug mode */ 204a3df083aSStefano Zampini #undef __FUNCT__ 205a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 206a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 207a3df083aSStefano Zampini { 208a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 209a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 210a3df083aSStefano Zampini Mat An; 211a3df083aSStefano Zampini PetscErrorCode ierr; 212a3df083aSStefano Zampini 213a3df083aSStefano Zampini PetscFunctionBegin; 214a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 215a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 216a3df083aSStefano Zampini if (is1) { 217a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 218a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 219a3df083aSStefano Zampini } else { 220a3df083aSStefano Zampini *B = An; 221a3df083aSStefano Zampini } 222a3df083aSStefano Zampini PetscFunctionReturn(0); 223a3df083aSStefano Zampini } 224a3df083aSStefano Zampini 2251cf9b237SStefano Zampini /* TODO: add reuse flag */ 2261cf9b237SStefano Zampini #undef __FUNCT__ 2271cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 2281cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 2291cf9b237SStefano Zampini { 2301cf9b237SStefano Zampini Mat Bt; 2311cf9b237SStefano Zampini PetscScalar *a,*bdata; 2321cf9b237SStefano Zampini const PetscInt *ii,*ij; 2331cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 2341cf9b237SStefano Zampini PetscBool flg_row; 2351cf9b237SStefano Zampini PetscErrorCode ierr; 2361cf9b237SStefano Zampini 2371cf9b237SStefano Zampini PetscFunctionBegin; 2381cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 2391cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 2401cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 2411cf9b237SStefano Zampini nnz = n; 2421cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 2431cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 2441cf9b237SStefano Zampini } 2451cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 2461cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 2471cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 2481cf9b237SStefano Zampini nnz = 0; 2491cf9b237SStefano Zampini bii[0] = 0; 2501cf9b237SStefano Zampini for (i=0;i<n;i++) { 2511cf9b237SStefano Zampini PetscInt j; 2521cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 2531cf9b237SStefano Zampini PetscScalar entry = a[j]; 2541cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 2551cf9b237SStefano Zampini bij[nnz] = ij[j]; 2561cf9b237SStefano Zampini bdata[nnz] = entry; 2571cf9b237SStefano Zampini nnz++; 2581cf9b237SStefano Zampini } 2591cf9b237SStefano Zampini } 2601cf9b237SStefano Zampini bii[i+1] = nnz; 2611cf9b237SStefano Zampini } 2621cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 2631cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 2641cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 2651cf9b237SStefano Zampini { 2661cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 2671cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 2681cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 2691cf9b237SStefano Zampini } 2701cf9b237SStefano Zampini *B = Bt; 2711cf9b237SStefano Zampini PetscFunctionReturn(0); 2721cf9b237SStefano Zampini } 2731cf9b237SStefano Zampini 274674ae819SStefano Zampini #undef __FUNCT__ 2754f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 2764f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 2774f1b2e48SStefano Zampini { 2784f1b2e48SStefano Zampini Mat B; 2794f1b2e48SStefano Zampini IS is_dummy,*cc_n; 2804f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 2814f1b2e48SStefano Zampini PCBDDCGraph graph; 2824f1b2e48SStefano Zampini PetscInt i,n; 2834f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 2844f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 2854f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 2864f1b2e48SStefano Zampini PetscErrorCode ierr; 2874f1b2e48SStefano Zampini 2884f1b2e48SStefano Zampini PetscFunctionBegin; 289*63c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 290*63c961adSStefano Zampini *ncc = 0; 291*63c961adSStefano Zampini *cc = NULL; 292*63c961adSStefano Zampini PetscFunctionReturn(0); 293*63c961adSStefano Zampini } 2944f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 2954f1b2e48SStefano Zampini if (!isseqaij && filter) { 2961cf9b237SStefano Zampini PetscBool isseqdense; 2971cf9b237SStefano Zampini 2981cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 2991cf9b237SStefano Zampini if (!isseqdense) { 3004f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 3011cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 3021cf9b237SStefano Zampini PetscScalar *array; 3031cf9b237SStefano Zampini PetscReal chop=1.e-6; 3041cf9b237SStefano Zampini 3051cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 3061cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 3071cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 3081cf9b237SStefano Zampini for (i=0;i<n;i++) { 3091cf9b237SStefano Zampini PetscInt j; 3101cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 3111cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 3121cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 3131cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 3141cf9b237SStefano Zampini } 3151cf9b237SStefano Zampini } 3161cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 3171cf9b237SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_REUSE_MATRIX,&B);CHKERRQ(ierr); 3181cf9b237SStefano Zampini } 3194f1b2e48SStefano Zampini } else { 3204f1b2e48SStefano Zampini B = A; 3214f1b2e48SStefano Zampini } 3224f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3234f1b2e48SStefano Zampini 3244f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 3254f1b2e48SStefano Zampini if (filter) { 3264f1b2e48SStefano Zampini PetscScalar *data; 3274f1b2e48SStefano Zampini PetscInt j,cum; 3284f1b2e48SStefano Zampini 3294f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 3304f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 3314f1b2e48SStefano Zampini cum = 0; 3324f1b2e48SStefano Zampini for (i=0;i<n;i++) { 3334f1b2e48SStefano Zampini PetscInt t; 3344f1b2e48SStefano Zampini 3354f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 3364f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 3374f1b2e48SStefano Zampini continue; 3384f1b2e48SStefano Zampini } 3394f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 3404f1b2e48SStefano Zampini } 3414f1b2e48SStefano Zampini t = xadj_filtered[i]; 3424f1b2e48SStefano Zampini xadj_filtered[i] = cum; 3434f1b2e48SStefano Zampini cum += t; 3444f1b2e48SStefano Zampini } 3454f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 3464f1b2e48SStefano Zampini } else { 3474f1b2e48SStefano Zampini xadj_filtered = NULL; 3484f1b2e48SStefano Zampini adjncy_filtered = NULL; 3494f1b2e48SStefano Zampini } 3504f1b2e48SStefano Zampini 3514f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 3524f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 3534f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 3544f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 3554f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 3564f1b2e48SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n);CHKERRQ(ierr); 3574f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 3584f1b2e48SStefano Zampini if (xadj_filtered) { 3594f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 3604f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 3614f1b2e48SStefano Zampini } else { 3624f1b2e48SStefano Zampini graph->xadj = xadj; 3634f1b2e48SStefano Zampini graph->adjncy = adjncy; 3644f1b2e48SStefano Zampini } 3654f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 3664f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 3674f1b2e48SStefano Zampini /* partial clean up */ 3684f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 3694f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3701cf9b237SStefano Zampini if (A != B) { 3714f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 3724f1b2e48SStefano Zampini } 3734f1b2e48SStefano Zampini 3744f1b2e48SStefano Zampini /* get back data */ 3751cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 3761cf9b237SStefano Zampini if (cc) { 3774f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 3784f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 3794f1b2e48SStefano 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); 3804f1b2e48SStefano Zampini } 3814f1b2e48SStefano Zampini *cc = cc_n; 3821cf9b237SStefano Zampini } 3834f1b2e48SStefano Zampini /* clean up graph */ 3844f1b2e48SStefano Zampini graph->xadj = 0; 3854f1b2e48SStefano Zampini graph->adjncy = 0; 3864f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 3874f1b2e48SStefano Zampini PetscFunctionReturn(0); 3884f1b2e48SStefano Zampini } 3894f1b2e48SStefano Zampini 3904f1b2e48SStefano Zampini #undef __FUNCT__ 3915408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 3925408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 3935408967cSStefano Zampini { 3945408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3955408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 396dee84bffSStefano Zampini IS dirIS = NULL; 3974f1b2e48SStefano Zampini PetscInt i; 3985408967cSStefano Zampini PetscErrorCode ierr; 3995408967cSStefano Zampini 4005408967cSStefano Zampini PetscFunctionBegin; 401dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 4025408967cSStefano Zampini if (zerodiag) { 4035408967cSStefano Zampini Mat A; 4045408967cSStefano Zampini Vec vec3_N; 4055408967cSStefano Zampini PetscScalar *vals; 4065408967cSStefano Zampini const PetscInt *idxs; 407d12d3064SStefano Zampini PetscInt nz,*count; 4085408967cSStefano Zampini 4095408967cSStefano Zampini /* p0 */ 4105408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 4115408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 4125408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 4135408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 4144f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 4155408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4165408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 4175408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 4185408967cSStefano Zampini /* v_I */ 4195408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 4205408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 4215408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4225408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 4235408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 4245408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 4255408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4265408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 4275408967cSStefano Zampini if (dirIS) { 4285408967cSStefano Zampini PetscInt n; 4295408967cSStefano Zampini 4305408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 4315408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 4325408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 4335408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4345408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 4355408967cSStefano Zampini } 4365408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 4375408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 4385408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 4395408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 4405408967cSStefano Zampini ierr = MatISGetLocalMat(pc->mat,&A);CHKERRQ(ierr); 4415408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 4425408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 4434f1b2e48SStefano Zampini if (PetscAbsScalar(vals[0]) > PETSC_SMALL) { 4445408967cSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! b(v_I,p_0) = %f (should be numerically 0.)",PetscAbsScalar(vals[0])); 4455408967cSStefano Zampini } 4465408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4475408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 448d12d3064SStefano Zampini 449d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 450d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 451d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 452d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 453d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 454d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 455d4d8cf7bSStefano Zampini for (i=0;i<nz;i++) { 456d12d3064SStefano Zampini if (count[idxs[i]]) { 457d12d3064SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! pressure dof %d is an interface dof",idxs[i]); 458d12d3064SStefano Zampini } 459d4d8cf7bSStefano Zampini } 460d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 461d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 4625408967cSStefano Zampini } 463dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 4645408967cSStefano Zampini 4655408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 4665408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 4674f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 4685408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 4694f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 4705408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 4714f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 4724f1b2e48SStefano Zampini if ((PetscInt)PetscRealPart(pcbddc->benign_p0[i]) != -PetscGlobalRank-i) { 4734f1b2e48SStefano Zampini SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error testing PCBDDCBenignGetOrSetP0! Found %1.4e at %d instead of %1.4e\n",pcbddc->benign_p0[i],i,-PetscGlobalRank-i);CHKERRQ(ierr); 4744f1b2e48SStefano Zampini } 4755408967cSStefano Zampini } 4765408967cSStefano Zampini PetscFunctionReturn(0); 4775408967cSStefano Zampini } 4785408967cSStefano Zampini 4795408967cSStefano Zampini #undef __FUNCT__ 480339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 481339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 482339f8db1SStefano Zampini { 483339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4844f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 485b0f5fe93SStefano Zampini PetscInt nz,n; 4864f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 487339f8db1SStefano Zampini PetscErrorCode ierr; 488339f8db1SStefano Zampini 489339f8db1SStefano Zampini PetscFunctionBegin; 4909f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 4919f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 492339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 493a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 494a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 495a3df083aSStefano Zampini } 496a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 497a3df083aSStefano Zampini pcbddc->benign_n = 0; 4984f1b2e48SStefano Zampini /* if a local info on dofs is present, assumes the last field is represented by "pressures" 4994f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 5004f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 5014f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 5024f1b2e48SStefano Zampini since the local Schur complements are SPD 5034f1b2e48SStefano Zampini */ 5044f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 5054f1b2e48SStefano Zampini have_null = PETSC_TRUE; 50640fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 5074f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 5084f1b2e48SStefano Zampini 5094f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 5104f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 5114f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 5124f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 513ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 51440fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 51540fa8d13SStefano Zampini if (!sorted) { 51640fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 51740fa8d13SStefano Zampini } 51840fa8d13SStefano Zampini } else { 51940fa8d13SStefano Zampini pressures = NULL; 52040fa8d13SStefano Zampini } 52197d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 52297d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 52397d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 524339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 525339f8db1SStefano Zampini if (!sorted) { 526339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 527339f8db1SStefano Zampini } 528339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 5294f1b2e48SStefano Zampini if (!nz) { 5304f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 5314f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 53240fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 53340fa8d13SStefano Zampini } 5344f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 5354f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 5364f1b2e48SStefano Zampini zerodiag_subs = NULL; 5374f1b2e48SStefano Zampini pcbddc->benign_n = 0; 5384f1b2e48SStefano Zampini if (has_null_pressures) { 5394f1b2e48SStefano Zampini IS *subs; 5404f1b2e48SStefano Zampini PetscInt nsubs,i; 5414f1b2e48SStefano Zampini 5424f1b2e48SStefano Zampini subs = pcbddc->local_subs; 5434f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 5444f1b2e48SStefano Zampini if (nsubs > 1) { 5454f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 5464f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 5474f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 5484f1b2e48SStefano Zampini IS t_zerodiag_subs; 5494f1b2e48SStefano Zampini PetscInt nl; 5504f1b2e48SStefano Zampini 5514f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 5524f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 5534f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 5544f1b2e48SStefano Zampini if (nl) { 5554f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 5564f1b2e48SStefano Zampini 5574f1b2e48SStefano Zampini if (pressures) { 5584f1b2e48SStefano Zampini IS t_pressure_subs; 5594f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 5604f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 5614f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 5624f1b2e48SStefano Zampini } 5634f1b2e48SStefano Zampini if (valid) { 5644f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 5654f1b2e48SStefano Zampini pcbddc->benign_n++; 5664f1b2e48SStefano Zampini } else { 5674f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 5684f1b2e48SStefano Zampini } 5694f1b2e48SStefano Zampini } 5704f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 5714f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 5724f1b2e48SStefano Zampini } 5734f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 5744f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 5754f1b2e48SStefano Zampini if (pressures) { 5764f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 5774f1b2e48SStefano Zampini } 5784f1b2e48SStefano Zampini if (valid) { 5794f1b2e48SStefano Zampini pcbddc->benign_n = 1; 580ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 5814f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 5824f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 5834f1b2e48SStefano Zampini } 5844f1b2e48SStefano Zampini } 5854f1b2e48SStefano Zampini } 5864f1b2e48SStefano Zampini 5874f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 5884f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 5894f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 5904f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 5914f1b2e48SStefano Zampini have_null = PETSC_FALSE; 5924f1b2e48SStefano Zampini } 5934f1b2e48SStefano Zampini 5944f1b2e48SStefano Zampini /* final check for null pressures */ 5954f1b2e48SStefano Zampini if (zerodiag && pressures) { 5964f1b2e48SStefano Zampini PetscInt nz,np; 5974f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 5984f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 5994f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 6004f1b2e48SStefano Zampini } 6014f1b2e48SStefano Zampini 6024f1b2e48SStefano Zampini if (recompute_zerodiag) { 6034f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 6044f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 6054f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 6064f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 6074f1b2e48SStefano Zampini } else { 6084f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 6094f1b2e48SStefano Zampini 6104f1b2e48SStefano Zampini nzn = 0; 6114f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 6124f1b2e48SStefano Zampini PetscInt ns; 6134f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 6144f1b2e48SStefano Zampini nzn += ns; 6154f1b2e48SStefano Zampini } 6164f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 6174f1b2e48SStefano Zampini nzn = 0; 6184f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 6194f1b2e48SStefano Zampini PetscInt ns,*idxs; 6204f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 6214f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 6224f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 6234f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 6244f1b2e48SStefano Zampini nzn += ns; 6254f1b2e48SStefano Zampini } 6264f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 6274f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 6284f1b2e48SStefano Zampini } 6294f1b2e48SStefano Zampini have_null = PETSC_FALSE; 6304f1b2e48SStefano Zampini } 6314f1b2e48SStefano Zampini 6324f1b2e48SStefano Zampini if (has_null_pressures) { 6334f1b2e48SStefano Zampini IS zerodiagc; 6344f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 6354f1b2e48SStefano Zampini PetscInt i,s,*nnz; 6364f1b2e48SStefano Zampini 6374f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 638339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 639339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 640339f8db1SStefano Zampini /* local change of basis for pressures */ 641339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 64297d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 643339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 644339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 645339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 6464f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 6474f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 6484f1b2e48SStefano Zampini PetscInt nzs,j; 6494f1b2e48SStefano Zampini 6504f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 6514f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 6524f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 6534f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 6544f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 6554f1b2e48SStefano Zampini } 656339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 657339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 658339f8db1SStefano Zampini /* set identity on velocities */ 659339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 660339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 661339f8db1SStefano Zampini } 6624f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 6634f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 6649f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 6654f1b2e48SStefano 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); 666339f8db1SStefano Zampini /* set change on pressures */ 6674f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 6684f1b2e48SStefano Zampini PetscScalar *array; 6694f1b2e48SStefano Zampini PetscInt nzs; 6704f1b2e48SStefano Zampini 6714f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 6724f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 6734f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 674339f8db1SStefano Zampini PetscScalar vals[2]; 675339f8db1SStefano Zampini PetscInt cols[2]; 676339f8db1SStefano Zampini 677339f8db1SStefano Zampini cols[0] = idxs[i]; 6784f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 679339f8db1SStefano Zampini vals[0] = 1.; 680b0f5fe93SStefano Zampini vals[1] = 1.; 6814f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 682339f8db1SStefano Zampini } 6834f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 6844f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 6854f1b2e48SStefano Zampini array[nzs-1] = 1.; 6864f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 6874f1b2e48SStefano Zampini /* store local idxs for p0 */ 6884f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 6894f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 690339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 6914f1b2e48SStefano Zampini } 692339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 693339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 694a3df083aSStefano Zampini /* project if needed */ 695a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 69697d764eeSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&pcbddc->benign_original_mat);CHKERRQ(ierr); 697339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 69897d764eeSStefano Zampini ierr = MatSeqAIJCompress(pcbddc->benign_original_mat,&pcbddc->local_mat);CHKERRQ(ierr); 69997d764eeSStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 700a3df083aSStefano Zampini } 7014f1b2e48SStefano Zampini /* store global idxs for p0 */ 7024f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 703339f8db1SStefano Zampini } 704ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 7054f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 706b0f5fe93SStefano Zampini 707b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 708b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 709339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 710339f8db1SStefano Zampini PetscFunctionReturn(0); 711339f8db1SStefano Zampini } 712339f8db1SStefano Zampini 713339f8db1SStefano Zampini #undef __FUNCT__ 714015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 715015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 716efc2fbd9SStefano Zampini { 717efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 718efc2fbd9SStefano Zampini PetscErrorCode ierr; 719efc2fbd9SStefano Zampini 720efc2fbd9SStefano Zampini PetscFunctionBegin; 721efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 722efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 7234f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 724efc2fbd9SStefano Zampini } 725015636ebSStefano Zampini if (get) { /* use SF to get values */ 726efc2fbd9SStefano Zampini PetscScalar *array; 727efc2fbd9SStefano Zampini 728efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 7294f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 7304f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 731efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 7324f1b2e48SStefano Zampini } else { /* use VecSetValues (not scalable, I should try to find a better solution (defining a new MPI_OP for reduction) */ 7334f1b2e48SStefano Zampini ierr = VecSetValues(v,pcbddc->benign_n,pcbddc->benign_p0_gidx,pcbddc->benign_p0,INSERT_VALUES);CHKERRQ(ierr); 734efc2fbd9SStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 735efc2fbd9SStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 736efc2fbd9SStefano Zampini } 737efc2fbd9SStefano Zampini PetscFunctionReturn(0); 738efc2fbd9SStefano Zampini } 739efc2fbd9SStefano Zampini 740efc2fbd9SStefano Zampini #undef __FUNCT__ 741c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 742c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 743c263805aSStefano Zampini { 744c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 745c263805aSStefano Zampini PetscErrorCode ierr; 746c263805aSStefano Zampini 747c263805aSStefano Zampini PetscFunctionBegin; 748c263805aSStefano Zampini /* TODO: add error checking 749c263805aSStefano Zampini - avoid nested pop (or push) calls. 750c263805aSStefano Zampini - cannot push before pop. 7511c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 752c263805aSStefano Zampini */ 7534f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 754efc2fbd9SStefano Zampini PetscFunctionReturn(0); 755efc2fbd9SStefano Zampini } 756c263805aSStefano Zampini if (pop) { 757a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 7584f1b2e48SStefano Zampini IS is_p0; 7594f1b2e48SStefano Zampini MatReuse reuse; 760c263805aSStefano Zampini 761c263805aSStefano Zampini /* extract B_0 */ 7624f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 7634f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 7644f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 7654f1b2e48SStefano Zampini } 7664f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 7674f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 768c263805aSStefano Zampini /* remove rows and cols from local problem */ 769c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 77097d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7714f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 7724f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 773a3df083aSStefano Zampini } else { 774a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 775a3df083aSStefano Zampini PetscScalar *vals; 776a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 777a3df083aSStefano Zampini 778a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 779a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 780a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 781a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 782a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 783a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 784a3df083aSStefano Zampini /* this matrix is very sparse: the nnz pattern is not known unless we do 2 sweeps of the next loop. 785a3df083aSStefano Zampini Setting nnz=100 should be more than enough */ 786a3df083aSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,100,NULL);CHKERRQ(ierr); 787a3df083aSStefano Zampini } 788a3df083aSStefano Zampini 789a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 790a3df083aSStefano Zampini PetscScalar *array; 791a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 792a3df083aSStefano Zampini 793a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 794a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 795a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 796a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 797a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 798a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 799a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 800a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 801a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 802a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 803a3df083aSStefano Zampini cum = 0; 804a3df083aSStefano Zampini for (j=0;j<n;j++) { 805a3df083aSStefano Zampini if (PetscUnlikely(PetscAbsReal(array[j]) > PETSC_SMALL)) { 806a3df083aSStefano Zampini vals[cum] = array[j]; 807a3df083aSStefano Zampini idxs_ins[cum] = j; 808a3df083aSStefano Zampini cum++; 809a3df083aSStefano Zampini } 810a3df083aSStefano Zampini } 811a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 812a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 813a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 814a3df083aSStefano Zampini } 815a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 816a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 817a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 818a3df083aSStefano Zampini } 819c263805aSStefano Zampini } else { /* push */ 820a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 8214f1b2e48SStefano Zampini PetscInt i; 8224f1b2e48SStefano Zampini 8234f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 8244f1b2e48SStefano Zampini PetscScalar *B0_vals; 8254f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 8264f1b2e48SStefano Zampini 8274f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 8284f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 8297b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 8304f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 8314f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 8324f1b2e48SStefano Zampini } 833c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 834c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 835a3df083aSStefano Zampini } else { 836a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 837a3df083aSStefano Zampini } 838c263805aSStefano Zampini } 839c263805aSStefano Zampini PetscFunctionReturn(0); 840c263805aSStefano Zampini } 841c263805aSStefano Zampini 842c263805aSStefano Zampini #undef __FUNCT__ 843b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 84408122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 845b1b3d7a2SStefano Zampini { 846b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 84708122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 84808122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 84908122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 85008122e43SStefano Zampini PetscScalar *work,lwork; 85108122e43SStefano Zampini PetscScalar *St,*S,*eigv; 85208122e43SStefano Zampini PetscScalar *Sarray,*Starray; 85308122e43SStefano Zampini PetscReal *eigs,thresh; 8541b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 855f6f667cfSStefano Zampini PetscBool allocated_S_St; 85608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 85708122e43SStefano Zampini PetscReal *rwork; 85808122e43SStefano Zampini #endif 859b1b3d7a2SStefano Zampini PetscErrorCode ierr; 860b1b3d7a2SStefano Zampini 861b1b3d7a2SStefano Zampini PetscFunctionBegin; 862df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 863df4d28bfSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 86408122e43SStefano Zampini } 86508122e43SStefano Zampini 86606a4e24aSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) { 86706a4e24aSStefano Zampini 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); 86806a4e24aSStefano Zampini } 86906a4e24aSStefano Zampini 870fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 871fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 872fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 873fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 8741575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 875fd14bc51SStefano Zampini } 876fd14bc51SStefano Zampini 877e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 878e496cd5dSStefano 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); 879e496cd5dSStefano Zampini } 880e496cd5dSStefano Zampini 88108122e43SStefano Zampini /* max size of subsets */ 88208122e43SStefano Zampini mss = 0; 88308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 88408122e43SStefano Zampini PetscInt subset_size; 885862806e4SStefano Zampini 88608122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 88708122e43SStefano Zampini mss = PetscMax(mss,subset_size); 88808122e43SStefano Zampini } 88908122e43SStefano Zampini 89008122e43SStefano Zampini /* min/max and threshold */ 89108122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 892f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 89308122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 894f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 895f6f667cfSStefano Zampini if (nmin) { 896f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 897f6f667cfSStefano Zampini } 89808122e43SStefano Zampini 89908122e43SStefano Zampini /* allocate lapack workspace */ 90008122e43SStefano Zampini cum = cum2 = 0; 90108122e43SStefano Zampini maxneigs = 0; 90208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 90308122e43SStefano Zampini PetscInt n,subset_size; 904f6f667cfSStefano Zampini 90508122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 90608122e43SStefano Zampini n = PetscMin(subset_size,nmax); 9079162d606SStefano Zampini cum += subset_size; 9089162d606SStefano Zampini cum2 += subset_size*n; 90908122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 91008122e43SStefano Zampini } 91108122e43SStefano Zampini if (mss) { 9129ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 91308122e43SStefano Zampini PetscBLASInt B_itype = 1; 91408122e43SStefano Zampini PetscBLASInt B_N = mss; 9154c6709b3SStefano Zampini PetscReal zero = 0.0; 9164c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 91708122e43SStefano Zampini 91808122e43SStefano Zampini B_lwork = -1; 91908122e43SStefano Zampini S = NULL; 92008122e43SStefano Zampini St = NULL; 921a58a30b4SStefano Zampini eigs = NULL; 922a58a30b4SStefano Zampini eigv = NULL; 923a58a30b4SStefano Zampini B_iwork = NULL; 924a58a30b4SStefano Zampini B_ifail = NULL; 925d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 926d1710679SStefano Zampini rwork = NULL; 927d1710679SStefano Zampini #endif 9288bec7fa6SStefano Zampini thresh = 1.0; 92908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 93008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 93108122e43SStefano 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)); 93208122e43SStefano Zampini #else 93308122e43SStefano 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)); 93408122e43SStefano Zampini #endif 93508122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 93608122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 93708122e43SStefano Zampini } else { 93808122e43SStefano Zampini /* TODO */ 93908122e43SStefano Zampini } 94008122e43SStefano Zampini } else { 94108122e43SStefano Zampini lwork = 0; 94208122e43SStefano Zampini } 94308122e43SStefano Zampini 94408122e43SStefano Zampini nv = 0; 945d62866d3SStefano 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) */ 946d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 94708122e43SStefano Zampini } 9484c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 949f6f667cfSStefano Zampini if (allocated_S_St) { 950f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 951f6f667cfSStefano Zampini } 952f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 95308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 95408122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 95508122e43SStefano Zampini #endif 9569162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 9579162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 9589162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 95908122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 9609162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 96108122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 96208122e43SStefano Zampini 96308122e43SStefano Zampini maxneigs = 0; 96408122e43SStefano Zampini cum = cum2 = cumarray = 0; 9659162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 9669162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 967d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 96808122e43SStefano Zampini const PetscInt *idxs; 96908122e43SStefano Zampini 970d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 97108122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 97208122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 97308122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 97408122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 9759162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 9769162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 97708122e43SStefano Zampini } 97808122e43SStefano Zampini cum2 = cum; 979d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 98008122e43SStefano Zampini } 98108122e43SStefano Zampini 98208122e43SStefano Zampini if (mss) { /* multilevel */ 98308122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 98408122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 98508122e43SStefano Zampini } 98608122e43SStefano Zampini 987ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 98808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 98908122e43SStefano Zampini const PetscInt *idxs; 990f6f667cfSStefano Zampini PetscReal infty = PETSC_MAX_REAL; 991862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 99208122e43SStefano Zampini PetscBLASInt B_N; 993aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 99408122e43SStefano Zampini 995862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 996ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 997f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 998f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 9999ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 1000aff50787SStefano Zampini PetscInt j,k; 1001aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 1002aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 1003aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 100408122e43SStefano Zampini } 100508122e43SStefano Zampini for (j=0;j<subset_size;j++) { 1006aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 1007aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 1008aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 1009aff50787SStefano Zampini } 101008122e43SStefano Zampini } 101108122e43SStefano Zampini } else { 101208122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 101308122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 101408122e43SStefano Zampini } 10158bec7fa6SStefano Zampini } else { 1016f6f667cfSStefano Zampini S = Sarray + cumarray; 1017f6f667cfSStefano Zampini St = Starray + cumarray; 10188bec7fa6SStefano Zampini } 101908122e43SStefano Zampini 1020aff50787SStefano Zampini /* see if we can save some work */ 1021aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { 1022aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 1023aff50787SStefano Zampini } 1024aff50787SStefano Zampini 1025aff50787SStefano Zampini if (same_data) { /* there's no need of constraints here, deluxe scaling is enough */ 1026aff50787SStefano Zampini B_neigs = 0; 1027aff50787SStefano Zampini } else { 10289ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 102908122e43SStefano Zampini PetscBLASInt B_itype = 1; 1030f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 10314c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 10329552c7c7SStefano Zampini PetscInt nmin_s; 103308122e43SStefano Zampini 1034fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 10358bec7fa6SStefano 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]]); 1036fd14bc51SStefano Zampini } 1037d16cbb6bSStefano Zampini 103808122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1039d16cbb6bSStefano Zampini if (thresh > 1.+PETSC_SMALL) { 1040d16cbb6bSStefano Zampini 1041d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 104208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1043f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 104408122e43SStefano Zampini #else 1045f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 104608122e43SStefano Zampini #endif 1047d16cbb6bSStefano Zampini } else { 1048d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 1049d16cbb6bSStefano Zampini B_IL = 1; 1050d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1051d16cbb6bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 1052d16cbb6bSStefano Zampini #else 1053d16cbb6bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 1054d16cbb6bSStefano Zampini #endif 1055d16cbb6bSStefano Zampini } 105608122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 105708122e43SStefano Zampini if (B_ierr) { 105808122e43SStefano Zampini if (B_ierr < 0 ) { 105908122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 106008122e43SStefano Zampini } else if (B_ierr <= B_N) { 106108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 106208122e43SStefano Zampini } else { 10639552c7c7SStefano Zampini 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); 106408122e43SStefano Zampini } 106508122e43SStefano Zampini } 106608122e43SStefano Zampini 106708122e43SStefano Zampini if (B_neigs > nmax) { 1068fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1069fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 1070fd14bc51SStefano Zampini } 1071f6f667cfSStefano Zampini eigs_start = B_neigs -nmax; 107208122e43SStefano Zampini B_neigs = nmax; 107308122e43SStefano Zampini } 107408122e43SStefano Zampini 10759552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 10769552c7c7SStefano Zampini if (B_neigs < nmin_s) { 107708122e43SStefano Zampini PetscBLASInt B_neigs2; 107808122e43SStefano Zampini 1079f6f667cfSStefano Zampini B_IU = B_N - B_neigs; 1080f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 1081fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1082fd14bc51SStefano 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); 1083fd14bc51SStefano Zampini } 10849ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 108508122e43SStefano Zampini PetscInt j; 108608122e43SStefano Zampini for (j=0;j<subset_size;j++) { 108708122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 108808122e43SStefano Zampini } 108908122e43SStefano Zampini for (j=0;j<subset_size;j++) { 109008122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 109108122e43SStefano Zampini } 109208122e43SStefano Zampini } else { 109308122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 109408122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 109508122e43SStefano Zampini } 109608122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 109708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1098f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&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)); 109908122e43SStefano Zampini #else 1100f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&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)); 110108122e43SStefano Zampini #endif 110208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 110308122e43SStefano Zampini B_neigs += B_neigs2; 110408122e43SStefano Zampini } 110508122e43SStefano Zampini if (B_ierr) { 110608122e43SStefano Zampini if (B_ierr < 0 ) { 110708122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 110808122e43SStefano Zampini } else if (B_ierr <= B_N) { 110908122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 111008122e43SStefano Zampini } else { 11119552c7c7SStefano Zampini 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); 111208122e43SStefano Zampini } 111308122e43SStefano Zampini } 1114fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1115ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 111608122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 111708122e43SStefano Zampini if (eigs[j] == 0.0) { 1118ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 111908122e43SStefano Zampini } else { 1120ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 1121fd14bc51SStefano Zampini } 112208122e43SStefano Zampini } 112308122e43SStefano Zampini } 112408122e43SStefano Zampini } else { 112508122e43SStefano Zampini /* TODO */ 112608122e43SStefano Zampini } 1127aff50787SStefano Zampini } 11288bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 11298bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 11309162d606SStefano Zampini if (B_neigs) { 11319162d606SStefano 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); 1132fd14bc51SStefano Zampini 1133fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 11349552c7c7SStefano Zampini PetscInt ii; 11359552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 1136ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 11379552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 1138ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1139ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1140ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1141ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 1142ac47001eSStefano Zampini #else 1143ac47001eSStefano 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); 1144ac47001eSStefano Zampini #endif 11459552c7c7SStefano Zampini } 11469552c7c7SStefano Zampini } 1147fd14bc51SStefano Zampini } 114808122e43SStefano Zampini #if 0 11499162d606SStefano Zampini for (j=0;j<B_neigs;j++) { 115008122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 115108122e43SStefano Zampini PetscScalar norm; 115208122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 11539162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size, 11549162d606SStefano Zampini &Blas_one,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 115508122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 115608122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 115708122e43SStefano Zampini } else { 115808122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 115908122e43SStefano Zampini } 11609162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 1161b1b3d7a2SStefano Zampini } 1162b1b3d7a2SStefano Zampini #endif 11639162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 11649162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 11659162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 11669162d606SStefano Zampini cum++; 116708122e43SStefano Zampini } 116808122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 116908122e43SStefano Zampini /* shift for next computation */ 117008122e43SStefano Zampini cumarray += subset_size*subset_size; 117108122e43SStefano Zampini } 1172fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1173fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1174fd14bc51SStefano Zampini } 117508122e43SStefano Zampini 117608122e43SStefano Zampini if (mss) { 117708122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 117808122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 1179f6f667cfSStefano Zampini /* destroy matrices (junk) */ 1180f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 1181f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 118208122e43SStefano Zampini } 1183f6f667cfSStefano Zampini if (allocated_S_St) { 1184f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 1185f6f667cfSStefano Zampini } 1186f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 118708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 118808122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 118908122e43SStefano Zampini #endif 119008122e43SStefano Zampini if (pcbddc->dbg_flag) { 11911b968477SStefano Zampini PetscInt maxneigs_r; 119208122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 11939b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 119408122e43SStefano Zampini } 119508122e43SStefano Zampini PetscFunctionReturn(0); 119608122e43SStefano Zampini } 1197b1b3d7a2SStefano Zampini 1198674ae819SStefano Zampini #undef __FUNCT__ 1199c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 1200c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 1201c8587f34SStefano Zampini { 1202c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 12038629588bSStefano Zampini PetscScalar *coarse_submat_vals; 1204c8587f34SStefano Zampini PetscErrorCode ierr; 1205c8587f34SStefano Zampini 1206c8587f34SStefano Zampini PetscFunctionBegin; 1207f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 12085e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 1209c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 1210c8587f34SStefano Zampini 1211684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 12120fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 1213684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 1214c8587f34SStefano Zampini 1215c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 1216b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 1217c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 1218c8587f34SStefano Zampini } 1219c8587f34SStefano Zampini 12208629588bSStefano Zampini /* 12218629588bSStefano Zampini Setup local correction and local part of coarse basis. 12228629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 12238629588bSStefano Zampini */ 122447f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 12258629588bSStefano Zampini 12268629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 12278629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 12288629588bSStefano Zampini 12298629588bSStefano Zampini /* free */ 12308629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 1231c8587f34SStefano Zampini PetscFunctionReturn(0); 1232c8587f34SStefano Zampini } 1233c8587f34SStefano Zampini 1234c8587f34SStefano Zampini #undef __FUNCT__ 1235674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 1236674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 1237674ae819SStefano Zampini { 1238674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1239674ae819SStefano Zampini PetscErrorCode ierr; 1240674ae819SStefano Zampini 1241674ae819SStefano Zampini PetscFunctionBegin; 1242674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1243674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 124430368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 1245674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 1246674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1247785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 1248674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1249f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1250f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1251785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 125263602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 125363602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 1254674ae819SStefano Zampini PetscFunctionReturn(0); 1255674ae819SStefano Zampini } 1256674ae819SStefano Zampini 1257674ae819SStefano Zampini #undef __FUNCT__ 1258674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 1259674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 1260674ae819SStefano Zampini { 1261674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12624f1b2e48SStefano Zampini PetscInt i; 1263674ae819SStefano Zampini PetscErrorCode ierr; 1264674ae819SStefano Zampini 1265674ae819SStefano Zampini PetscFunctionBegin; 1266b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 1267674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 1268674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1269674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 12704f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 12714f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 12724f1b2e48SStefano Zampini } 12734f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1274b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1275674ae819SStefano Zampini PetscFunctionReturn(0); 1276674ae819SStefano Zampini } 1277674ae819SStefano Zampini 1278674ae819SStefano Zampini #undef __FUNCT__ 1279674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1280674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1281674ae819SStefano Zampini { 1282674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1283674ae819SStefano Zampini PetscErrorCode ierr; 1284674ae819SStefano Zampini 1285674ae819SStefano Zampini PetscFunctionBegin; 1286674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 128758da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 1288ca92afb2SStefano Zampini PetscScalar *array; 128906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 129006656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 129158da7f69SStefano Zampini } 1292674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1293674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 129415aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 129515aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1296674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1297674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1298674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 129906656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1300674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1301674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 13028ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1303674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1304674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1305674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1306f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1307f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1308f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1309f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1310727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 13110e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1312f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 131370cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 13146e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 131581d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 13160369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 13178b9f24d4SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 13184f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 13198b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 1320ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 1321ca92afb2SStefano Zampini PetscInt i; 1322ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1323ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1324ca92afb2SStefano Zampini } 1325ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1326ca92afb2SStefano Zampini } 13274f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1328674ae819SStefano Zampini PetscFunctionReturn(0); 1329674ae819SStefano Zampini } 1330674ae819SStefano Zampini 1331674ae819SStefano Zampini #undef __FUNCT__ 1332f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1333f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 13346bfb1811SStefano Zampini { 13356bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 13366bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 13376bfb1811SStefano Zampini VecType impVecType; 13384f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 13396bfb1811SStefano Zampini PetscErrorCode ierr; 13406bfb1811SStefano Zampini 13416bfb1811SStefano Zampini PetscFunctionBegin; 1342f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 1343019a44ceSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1344f4ddd8eeSStefano Zampini } 1345e7b262bdSStefano Zampini /* get sizes */ 13464f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1347b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 13486bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1349e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1350e7b262bdSStefano Zampini /* R nodes */ 1351e7b262bdSStefano Zampini old_size = -1; 1352e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1353e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1354e7b262bdSStefano Zampini } 1355e7b262bdSStefano Zampini if (n_R != old_size) { 1356e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1357e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 13586bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 13596bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 13606bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 13616bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1362e7b262bdSStefano Zampini } 1363e7b262bdSStefano Zampini /* local primal dofs */ 1364e7b262bdSStefano Zampini old_size = -1; 1365e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1366e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1367e7b262bdSStefano Zampini } 1368e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1369e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 137083b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1371e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 13726bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1373e7b262bdSStefano Zampini } 1374e7b262bdSStefano Zampini /* local explicit constraints */ 1375e7b262bdSStefano Zampini old_size = -1; 1376e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1377e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1378e7b262bdSStefano Zampini } 1379e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1380e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 138183b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 138283b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 138383b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 138483b7ccabSStefano Zampini } 13856bfb1811SStefano Zampini PetscFunctionReturn(0); 13866bfb1811SStefano Zampini } 13876bfb1811SStefano Zampini 13886bfb1811SStefano Zampini #undef __FUNCT__ 138947f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 139047f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 139188ebb749SStefano Zampini { 139225084f0cSStefano Zampini PetscErrorCode ierr; 139325084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 139488ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 139588ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1396d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 139725084f0cSStefano Zampini /* submatrices of local problem */ 139880677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 1399019a44ceSStefano Zampini /* submatrices of benign trick */ 1400d16cbb6bSStefano Zampini Mat B0_V = NULL; 140106656605SStefano Zampini /* submatrices of local coarse problem */ 140206656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 140325084f0cSStefano Zampini /* working matrices */ 140406656605SStefano Zampini Mat C_CR; 140525084f0cSStefano Zampini /* additional working stuff */ 140606656605SStefano Zampini PC pc_R; 14074f1b2e48SStefano Zampini Mat F; 1408a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 140906656605SStefano Zampini 141025084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 141106656605SStefano Zampini PetscScalar *work; 141206656605SStefano Zampini PetscInt *idx_V_B; 1413ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 141406656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1415ffd830a3SStefano Zampini 141625084f0cSStefano Zampini /* some shortcuts to scalars */ 141706656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 141888ebb749SStefano Zampini 141988ebb749SStefano Zampini PetscFunctionBegin; 1420ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal && pcbddc->benign_n) { 1421ffd830a3SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-symmetric primal basis computation with benign trick not yet implemented"); 1422ffd830a3SStefano Zampini } 1423ffd830a3SStefano Zampini 1424ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 1425b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 14264f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 1427b371cd4fSStefano Zampini n_B = pcis->n_B; 1428b371cd4fSStefano Zampini n_D = pcis->n - n_B; 142988ebb749SStefano Zampini n_R = pcis->n - n_vertices; 143088ebb749SStefano Zampini 143188ebb749SStefano Zampini /* vertices in boundary numbering */ 1432785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 14330e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 143488ebb749SStefano Zampini if (i != n_vertices) { 143522d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 143688ebb749SStefano Zampini } 143788ebb749SStefano Zampini 143806656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1439019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 144006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 144106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 144206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 144306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 144406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 144506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 144606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 144706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 144806656605SStefano Zampini 144906656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 145006656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 145106656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 145206656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 145306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 1454ffd830a3SStefano Zampini lda_rhs = n_R; 1455a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 145606656605SStefano Zampini if (isLU || isILU || isCHOL) { 145706656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1458df4d28bfSStefano Zampini } else if (sub_schurs->reuse_solver) { 1459df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1460d62866d3SStefano Zampini MatFactorType type; 1461d62866d3SStefano Zampini 1462df4d28bfSStefano Zampini F = reuse_solver->F; 14636816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1464d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 1465ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 1466df4d28bfSStefano Zampini need_benign_correction = !!reuse_solver->benign_n; 146706656605SStefano Zampini } else { 146806656605SStefano Zampini F = NULL; 146906656605SStefano Zampini } 147006656605SStefano Zampini 1471ffd830a3SStefano Zampini /* allocate workspace */ 1472ffd830a3SStefano Zampini n = 0; 1473ffd830a3SStefano Zampini if (n_constraints) { 1474ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 1475ffd830a3SStefano Zampini } 1476ffd830a3SStefano Zampini if (n_vertices) { 1477ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 1478ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 1479ffd830a3SStefano Zampini } 1480ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1481ffd830a3SStefano Zampini 148288ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 148388ebb749SStefano Zampini if (n_constraints) { 148406656605SStefano Zampini Mat M1,M2,M3; 148580677318SStefano Zampini Mat auxmat; 148606656605SStefano Zampini IS is_aux; 148780677318SStefano Zampini PetscScalar *array,*array2; 148806656605SStefano Zampini 1489f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 149080677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 149188ebb749SStefano Zampini 149225084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 149325084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 14948ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 149580677318SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&auxmat);CHKERRQ(ierr); 149688ebb749SStefano Zampini 149780677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 149880677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 1499ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 150088ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 150106656605SStefano Zampini const PetscScalar *row_cmat_values; 150206656605SStefano Zampini const PetscInt *row_cmat_indices; 150306656605SStefano Zampini PetscInt size_of_constraint,j; 150488ebb749SStefano Zampini 150506656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 150606656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1507ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 150806656605SStefano Zampini } 150906656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 151006656605SStefano Zampini } 1511ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 151206656605SStefano Zampini if (F) { 151306656605SStefano Zampini Mat B; 151406656605SStefano Zampini 1515ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 1516a3df083aSStefano Zampini if (need_benign_correction) { 1517a3df083aSStefano Zampini PetscScalar *marr; 1518df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1519a3df083aSStefano Zampini 1520a3df083aSStefano Zampini ierr = MatDenseGetArray(B,&marr);CHKERRQ(ierr); 1521a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1522a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1523df4d28bfSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE);CHKERRQ(ierr); 1524a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1525a3df083aSStefano Zampini } 1526a3df083aSStefano Zampini ierr = MatDenseRestoreArray(B,&marr);CHKERRQ(ierr); 1527a3df083aSStefano Zampini } 152880677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 1529a3df083aSStefano Zampini if (need_benign_correction) { 1530a3df083aSStefano Zampini PetscScalar *marr; 1531df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1532a3df083aSStefano Zampini 1533a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1534a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1535a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1536df4d28bfSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE);CHKERRQ(ierr); 1537a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1538a3df083aSStefano Zampini } 1539a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1540a3df083aSStefano Zampini } 154106656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 154206656605SStefano Zampini } else { 154380677318SStefano Zampini PetscScalar *marr; 154480677318SStefano Zampini 154580677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 154606656605SStefano Zampini for (i=0;i<n_constraints;i++) { 1547ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1548ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 154906656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 155006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 155106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 155206656605SStefano Zampini } 155380677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 155406656605SStefano Zampini } 155580677318SStefano Zampini if (!pcbddc->switch_static) { 155680677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 155780677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 155880677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 155980677318SStefano Zampini for (i=0;i<n_constraints;i++) { 1560ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 156180677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 156280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 156380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 156480677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 156580677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 156680677318SStefano Zampini } 156780677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 156880677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 156980677318SStefano Zampini ierr = MatMatMult(auxmat,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 157080677318SStefano Zampini } else { 1571ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1572ffd830a3SStefano Zampini IS dummy; 1573ffd830a3SStefano Zampini 1574ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 1575ffd830a3SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,dummy,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 1576ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1577ffd830a3SStefano Zampini } else { 157880677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 157980677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 1580ffd830a3SStefano Zampini } 158125084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 158280677318SStefano Zampini } 158380677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 158480677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 158580677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 158606656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 158706656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 158880677318SStefano Zampini if (isCHOL) { 158980677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 159080677318SStefano Zampini } else { 159125084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 159280677318SStefano Zampini } 159380677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 159406656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 159525084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 159625084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 159725084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 159880677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 159980677318SStefano Zampini ierr = MatMatMult(M1,auxmat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 160080677318SStefano Zampini ierr = MatDestroy(&auxmat);CHKERRQ(ierr); 160106656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 160206656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1603f4ddd8eeSStefano Zampini } 160488ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 16054f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1606d16cbb6bSStefano Zampini IS dummy; 1607d16cbb6bSStefano Zampini Mat B0_R; 1608d16cbb6bSStefano Zampini PetscReal norm; 1609d16cbb6bSStefano Zampini 16104f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 16114f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&B0_R);CHKERRQ(ierr); 1612d16cbb6bSStefano Zampini ierr = MatNorm(B0_R,NORM_INFINITY,&norm);CHKERRQ(ierr); 1613d16cbb6bSStefano Zampini if (norm > PETSC_SMALL) { 1614d16cbb6bSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! ||B0_R|| = %f (should be numerically 0.)",norm); 1615d16cbb6bSStefano Zampini } 1616d16cbb6bSStefano Zampini ierr = MatDestroy(&B0_R);CHKERRQ(ierr); 1617d16cbb6bSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1618d16cbb6bSStefano Zampini } 1619d16cbb6bSStefano Zampini 162088ebb749SStefano Zampini if (n_vertices) { 162106656605SStefano Zampini IS is_aux; 16223a50541eSStefano Zampini 1623df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 16246816873aSStefano Zampini IS tis; 16256816873aSStefano Zampini 16266816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 16276816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 16286816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 16296816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 16306816873aSStefano Zampini } else { 16313a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 16326816873aSStefano Zampini } 16339577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 16349577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 163504708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 16364f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1637019a44ceSStefano Zampini IS dummy; 1638019a44ceSStefano Zampini 16394f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 16404f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,is_aux,MAT_INITIAL_MATRIX,&B0_V);CHKERRQ(ierr); 1641019a44ceSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1642019a44ceSStefano Zampini } 164325084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 164488ebb749SStefano Zampini } 164588ebb749SStefano Zampini 164688ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1647f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 164806656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 164906656605SStefano Zampini if (pcbddc->coarse_phi_D) { 165006656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 165106656605SStefano Zampini } 1652f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 165306656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 165406656605SStefano Zampini PetscScalar *marray; 165506656605SStefano Zampini 165606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 165706656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1658f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1659f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1660f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1661f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1662f4ddd8eeSStefano Zampini } 1663f4ddd8eeSStefano Zampini } 166406656605SStefano Zampini 1665f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 166606656605SStefano Zampini PetscScalar *marray; 166788ebb749SStefano Zampini 166806656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 16698eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 167006656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 167188ebb749SStefano Zampini } 16723301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 167306656605SStefano Zampini n *= 2; 167488ebb749SStefano Zampini } 167506656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 167606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 167706656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 16788eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 167906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 168006656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 168188ebb749SStefano Zampini } 16823301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 168306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 16848eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 168506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 168606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 168788ebb749SStefano Zampini } 168888ebb749SStefano Zampini } else { 1689c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1690c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 16911b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1692c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1693c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1694c0553b1fSStefano Zampini } 169588ebb749SStefano Zampini } 169606656605SStefano Zampini } 1697019a44ceSStefano Zampini 169806656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 16994f1b2e48SStefano Zampini p0_lidx_I = NULL; 17004f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1701d12edf2fSStefano Zampini const PetscInt *idxs; 1702d12edf2fSStefano Zampini 1703d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 17044f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 17054f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 17064f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 17074f1b2e48SStefano Zampini } 1708d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1709d12edf2fSStefano Zampini } 1710d16cbb6bSStefano Zampini 171106656605SStefano Zampini /* vertices */ 171206656605SStefano Zampini if (n_vertices) { 171316f15bc4SStefano Zampini 1714ffd830a3SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 171504708bb6SStefano Zampini 171616f15bc4SStefano Zampini if (n_R) { 171714393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 171806656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 171916f15bc4SStefano Zampini PetscScalar *x,*y; 172004708bb6SStefano Zampini PetscBool isseqaij; 172106656605SStefano Zampini 172221eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 172314393ed6SStefano Zampini if (need_benign_correction) { 172414393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 172514393ed6SStefano Zampini IS is_p0; 172614393ed6SStefano Zampini PetscInt *idxs_p0,n; 172714393ed6SStefano Zampini 172814393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 172914393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 173014393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 173114393ed6SStefano Zampini if (n != pcbddc->benign_n) { 173214393ed6SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in R numbering for benign p0! %d != %d\n",n,pcbddc->benign_n); 173314393ed6SStefano Zampini } 173414393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 173514393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 173614393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 173714393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 173814393ed6SStefano Zampini } 173914393ed6SStefano Zampini 1740ffd830a3SStefano Zampini if (lda_rhs == n_R) { 1741ffd830a3SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 1742ffd830a3SStefano Zampini } else { 1743ca92afb2SStefano Zampini PetscScalar *av,*array; 1744ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 1745ca92afb2SStefano Zampini PetscInt n; 1746ca92afb2SStefano Zampini PetscBool flg_row; 1747ffd830a3SStefano Zampini 1748ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 1749ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 1750ca92afb2SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 1751ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1752ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 1753ca92afb2SStefano Zampini for (i=0;i<n;i++) { 1754ca92afb2SStefano Zampini PetscInt j; 1755ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 1756ffd830a3SStefano Zampini } 1757ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1758ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 1759ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 1760ffd830a3SStefano Zampini } 1761ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 176214393ed6SStefano Zampini if (F) { 1763a3df083aSStefano Zampini if (need_benign_correction) { 1764df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1765a3df083aSStefano Zampini PetscScalar *marr; 1766a3df083aSStefano Zampini 1767a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 176814393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 176914393ed6SStefano Zampini 177014393ed6SStefano Zampini | 0 0 0 | (V) 177114393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 177214393ed6SStefano Zampini | 0 0 -1 | (p0) 177314393ed6SStefano Zampini 177414393ed6SStefano Zampini */ 1775df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 177614393ed6SStefano Zampini const PetscScalar *vals; 177714393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 177814393ed6SStefano Zampini PetscInt n,j,nz; 177914393ed6SStefano Zampini 1780df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1781df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 178214393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 178314393ed6SStefano Zampini for (j=0;j<n;j++) { 178414393ed6SStefano Zampini PetscScalar val = vals[j]; 178514393ed6SStefano Zampini PetscInt k,col = idxs[j]; 178614393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 178714393ed6SStefano Zampini } 178814393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 1789df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 179014393ed6SStefano Zampini } 179114393ed6SStefano Zampini /* need to correct the rhs */ 1792a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 1793a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1794df4d28bfSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE);CHKERRQ(ierr); 1795a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1796a3df083aSStefano Zampini } 1797a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 1798a3df083aSStefano Zampini } 179906656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 180014393ed6SStefano Zampini /* need to correct the solution */ 1801a3df083aSStefano Zampini if (need_benign_correction) { 1802df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1803a3df083aSStefano Zampini PetscScalar *marr; 1804a3df083aSStefano Zampini 1805a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 1806a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 1807a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1808df4d28bfSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE);CHKERRQ(ierr); 1809a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1810a3df083aSStefano Zampini } 1811a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 1812a3df083aSStefano Zampini } 181306656605SStefano Zampini } else { 181406656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 181506656605SStefano Zampini for (i=0;i<n_vertices;i++) { 1816ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 1817ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 181806656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 181906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 182006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 182106656605SStefano Zampini } 182206656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 182306656605SStefano Zampini } 182480677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 1825ffd830a3SStefano Zampini /* S_VV and S_CV */ 182606656605SStefano Zampini if (n_constraints) { 182706656605SStefano Zampini Mat B; 182880677318SStefano Zampini 1829ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 183080677318SStefano Zampini for (i=0;i<n_vertices;i++) { 1831ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1832ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 183380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 183480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 183580677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 183680677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 183780677318SStefano Zampini } 1838ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 183980677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 184080677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1841ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 184280677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 184306656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 1844ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 1845ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 184606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 184706656605SStefano Zampini } 184804708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 184904708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 185004708bb6SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 185104708bb6SStefano Zampini } 1852ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1853ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 1854ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 1855ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 1856ffd830a3SStefano Zampini } 185706656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 185814393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 185914393ed6SStefano Zampini if (need_benign_correction) { 1860df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 186114393ed6SStefano Zampini PetscScalar *marr,*sums; 186214393ed6SStefano Zampini 186314393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 186414393ed6SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr); 1865df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 186614393ed6SStefano Zampini const PetscScalar *vals; 186714393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 186814393ed6SStefano Zampini PetscInt n,j,nz; 186914393ed6SStefano Zampini 1870df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1871df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 187214393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 187314393ed6SStefano Zampini PetscInt k; 187414393ed6SStefano Zampini sums[j] = 0.; 187514393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 187614393ed6SStefano Zampini } 187714393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 187814393ed6SStefano Zampini for (j=0;j<n;j++) { 187914393ed6SStefano Zampini PetscScalar val = vals[j]; 188014393ed6SStefano Zampini PetscInt k; 188114393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 188214393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 188314393ed6SStefano Zampini } 188414393ed6SStefano Zampini } 188514393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 1886df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 188714393ed6SStefano Zampini } 188814393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 188914393ed6SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr); 189014393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 189114393ed6SStefano Zampini } 189280677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 189306656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 189406656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 189506656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 189606656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 189706656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 189806656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 189906656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1900d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 1901019a44ceSStefano Zampini } else { 1902d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1903d16cbb6bSStefano Zampini } 19044f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1905019a44ceSStefano Zampini const PetscScalar *vals; 1906019a44ceSStefano Zampini const PetscInt *idxs; 19074f1b2e48SStefano Zampini PetscInt n,j,primal_idx; 1908019a44ceSStefano Zampini 19094f1b2e48SStefano Zampini ierr = MatGetRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 19104f1b2e48SStefano Zampini primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + i; 1911d16cbb6bSStefano Zampini for (j=0;j<n;j++) { 19124f1b2e48SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+idxs[j]] = vals[j]; 19134f1b2e48SStefano Zampini coarse_submat_vals[idxs[j]*pcbddc->local_primal_size+primal_idx] = vals[j]; 1914019a44ceSStefano Zampini } 19154f1b2e48SStefano Zampini ierr = MatRestoreRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 191616f15bc4SStefano Zampini } 191721eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 1918d16cbb6bSStefano Zampini 191906656605SStefano Zampini /* coarse basis functions */ 192006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 192116f15bc4SStefano Zampini PetscScalar *y; 192216f15bc4SStefano Zampini 1923ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 192406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 192506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 192606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 192706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 192806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 192906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 193006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 193106656605SStefano Zampini 193206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 19334f1b2e48SStefano Zampini PetscInt j; 19344f1b2e48SStefano Zampini 193506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 193606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 193706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 193806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 193906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 19404f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 194106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 194206656605SStefano Zampini } 194306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 194406656605SStefano Zampini } 194504708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 194604708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 194706656605SStefano Zampini } 194806656605SStefano Zampini 194906656605SStefano Zampini if (n_constraints) { 195006656605SStefano Zampini Mat B; 195106656605SStefano Zampini 1952ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 195306656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 195480677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 195506656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 195606656605SStefano Zampini if (n_vertices) { 195780677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 195880677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 195980677318SStefano Zampini } else { 196080677318SStefano Zampini Mat S_VCt; 196180677318SStefano Zampini 1962ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1963ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1964ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B);CHKERRQ(ierr); 1965ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 1966ffd830a3SStefano Zampini } 196780677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 196880677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 196980677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 197080677318SStefano Zampini } 197106656605SStefano Zampini } 197206656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 197306656605SStefano Zampini /* coarse basis functions */ 197406656605SStefano Zampini for (i=0;i<n_constraints;i++) { 197506656605SStefano Zampini PetscScalar *y; 197606656605SStefano Zampini 1977ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 197806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 197906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 198006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 198106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 198206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 198306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 198406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 19854f1b2e48SStefano Zampini PetscInt j; 19864f1b2e48SStefano Zampini 198706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 198806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 198906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 199106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 19924f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 199306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 199406656605SStefano Zampini } 199506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 199606656605SStefano Zampini } 199706656605SStefano Zampini } 199880677318SStefano Zampini if (n_constraints) { 199980677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 200080677318SStefano Zampini } 20014f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 2002019a44ceSStefano Zampini ierr = MatDestroy(&B0_V);CHKERRQ(ierr); 2003019a44ceSStefano Zampini 200406656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 20053301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 2006ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 2007ffd830a3SStefano Zampini PetscScalar *marray; 200806656605SStefano Zampini 200906656605SStefano Zampini if (n_constraints) { 2010ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 201106656605SStefano Zampini 2012ffd830a3SStefano Zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 201306656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 2014ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 201516f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 201606656605SStefano Zampini if (n_vertices) { 2017ffd830a3SStefano Zampini Mat S_VCT; 201806656605SStefano Zampini 201906656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 2020ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 202116f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 202206656605SStefano Zampini } 2023ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 202406656605SStefano Zampini } 202516f15bc4SStefano Zampini if (n_vertices && n_R) { 2026ffd830a3SStefano Zampini PetscScalar *av,*marray; 2027ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 2028ffd830a3SStefano Zampini PetscInt n; 2029ffd830a3SStefano Zampini PetscBool flg_row; 203006656605SStefano Zampini 2031ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 2032ffd830a3SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 2033ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2034ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 2035ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2036ffd830a3SStefano Zampini for (i=0;i<n;i++) { 2037ffd830a3SStefano Zampini PetscInt j; 2038ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 2039ffd830a3SStefano Zampini } 2040ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2041ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2042ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 204306656605SStefano Zampini } 204406656605SStefano Zampini 2045ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 2046ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2047ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 2048ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 2049ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 205006656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 205106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 205206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 205306656605SStefano Zampini } 2054ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2055ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 2056ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 2057ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 2058ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 2059ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 2060ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2061ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 206206656605SStefano Zampini } 2063ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 206406656605SStefano Zampini /* coarse basis functions */ 206506656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 206606656605SStefano Zampini PetscScalar *y; 206706656605SStefano Zampini 2068ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 206906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 207006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 207106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 207206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 207306656605SStefano Zampini if (i<n_vertices) { 207406656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 207506656605SStefano Zampini } 207606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 207706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 207806656605SStefano Zampini 207906656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 208006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 208106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 208206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 208306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 208406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 208506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 208606656605SStefano Zampini } 208706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 208806656605SStefano Zampini } 2089ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 2090ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 209106656605SStefano Zampini } 2092d62866d3SStefano Zampini /* free memory */ 209388ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 209406656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 209506656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 209606656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 209706656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 2098d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2099d62866d3SStefano Zampini if (n_vertices) { 2100d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 2101d62866d3SStefano Zampini } 2102d62866d3SStefano Zampini if (n_constraints) { 2103d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 2104d62866d3SStefano Zampini } 210588ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 210688ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 210788ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 2108d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 210988ebb749SStefano Zampini Mat coarse_sub_mat; 211025084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 211188ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 211288ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 211388ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 21148bec7fa6SStefano Zampini Mat C_B,CPHI; 21158bec7fa6SStefano Zampini IS is_dummy; 21168bec7fa6SStefano Zampini Vec mones; 211788ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 211888ebb749SStefano Zampini PetscReal real_value; 211988ebb749SStefano Zampini 2120a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 2121a3df083aSStefano Zampini Mat A; 2122a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 2123a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 2124a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 2125a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 2126a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2127a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 2128a3df083aSStefano Zampini } else { 212988ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 213088ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 213188ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 213288ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2133a3df083aSStefano Zampini } 213488ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 213588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 2136ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 213788ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 213888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 213988ebb749SStefano Zampini } 214088ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 214188ebb749SStefano Zampini 214225084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 21433301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 214425084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2145ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 214688ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 214788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 214888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 214988ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 215088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 215188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 215288ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 215388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 215488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 215588ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 215688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 215788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 215888ebb749SStefano Zampini } else { 215988ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 216088ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 216188ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 216288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 216388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 216488ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 216588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 216688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 216788ebb749SStefano Zampini } 216888ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 216988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 217088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 217188ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 21724f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2173d12edf2fSStefano Zampini Mat B0_I,B0_B,B0_BPHI,B0_IPHI; 2174d12edf2fSStefano Zampini PetscScalar *data,*data2; 21754f1b2e48SStefano Zampini PetscInt j; 2176d12edf2fSStefano Zampini 21774f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 21784f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B); 21794f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_I_local,MAT_INITIAL_MATRIX,&B0_I); 2180d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 2181d12edf2fSStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_REUSE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 2182d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 2183d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 21844f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 21854f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 2186d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 21874f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 21884f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 21894f1b2e48SStefano Zampini } 2190d12edf2fSStefano Zampini } 2191d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 2192d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 2193d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 2194d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2195d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 2196d12edf2fSStefano Zampini ierr = MatMatMult(B0_I,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&B0_IPHI);CHKERRQ(ierr); 2197d12edf2fSStefano Zampini ierr = MatDestroy(&B0_I);CHKERRQ(ierr); 2198d12edf2fSStefano Zampini ierr = MatNorm(B0_IPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2199d12edf2fSStefano Zampini ierr = MatDestroy(&B0_IPHI);CHKERRQ(ierr); 2200d12edf2fSStefano Zampini } 2201d12edf2fSStefano Zampini #if 0 2202d12edf2fSStefano Zampini { 2203d12edf2fSStefano Zampini PetscViewer viewer; 2204d12edf2fSStefano Zampini char filename[256]; 2205ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 2206d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 2207d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2208ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 2209ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 2210ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 2211d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 2212ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 2213ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 2214ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 2215ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 2216ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 2217ffd830a3SStefano Zampini } 2218ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 2219ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 2220ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 2221ffd830a3SStefano Zampini } 2222ffd830a3SStefano Zampini if (pcbddc->coarse_phi_B) { 2223ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 2224ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 2225ffd830a3SStefano Zampini } 2226d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2227d12edf2fSStefano Zampini } 2228d12edf2fSStefano Zampini #endif 222981d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 22308bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 22311575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 223206656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 22338bec7fa6SStefano Zampini 22348bec7fa6SStefano Zampini /* check constraints */ 22354f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 22368bec7fa6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&is_dummy);CHKERRQ(ierr); 22378bec7fa6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B); 22388bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 22398bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 22408bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 22418bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 22428bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2243bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 2244ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 2245bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2246bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 2247bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 2248bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2249bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 225088ebb749SStefano Zampini } 22518bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 22528bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 22538bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 22548bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 2255d12edf2fSStefano Zampini } 225625084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 225788ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 225888ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 225988ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 226088ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 226188ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 226288ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 226388ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 226488ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 226588ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 226688ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 2267ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 226888ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 226988ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 227088ebb749SStefano Zampini } 227188ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 227288ebb749SStefano Zampini } 22738629588bSStefano Zampini /* get back data */ 22748629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 227588ebb749SStefano Zampini PetscFunctionReturn(0); 227688ebb749SStefano Zampini } 227788ebb749SStefano Zampini 227888ebb749SStefano Zampini #undef __FUNCT__ 2279d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 2280d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 2281aa0d41d4SStefano Zampini { 2282d65f70fdSStefano Zampini Mat *work_mat; 2283d65f70fdSStefano Zampini IS isrow_s,iscol_s; 2284d65f70fdSStefano Zampini PetscBool rsorted,csorted; 2285d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 2286aa0d41d4SStefano Zampini PetscErrorCode ierr; 2287aa0d41d4SStefano Zampini 2288aa0d41d4SStefano Zampini PetscFunctionBegin; 2289d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 2290d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 2291d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 2292d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 2293aa0d41d4SStefano Zampini 2294d65f70fdSStefano Zampini if (!rsorted) { 2295906d46d4SStefano Zampini const PetscInt *idxs; 2296906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 2297aa0d41d4SStefano Zampini 2298d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 2299d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 2300d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2301d65f70fdSStefano Zampini idxs_perm_r[i] = i; 2302aa0d41d4SStefano Zampini } 2303d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 2304d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 2305d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2306d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 2307aa0d41d4SStefano Zampini } 2308d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 2309d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 2310d65f70fdSStefano Zampini } else { 2311d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 2312d65f70fdSStefano Zampini isrow_s = isrow; 2313aa0d41d4SStefano Zampini } 2314906d46d4SStefano Zampini 2315d65f70fdSStefano Zampini if (!csorted) { 2316d65f70fdSStefano Zampini if (isrow == iscol) { 2317d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 2318d65f70fdSStefano Zampini iscol_s = isrow_s; 2319d65f70fdSStefano Zampini } else { 2320d65f70fdSStefano Zampini const PetscInt *idxs; 2321d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 2322906d46d4SStefano Zampini 2323d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 2324d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 2325d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2326d65f70fdSStefano Zampini idxs_perm_c[i] = i; 2327d65f70fdSStefano Zampini } 2328d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 2329d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 2330d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2331d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 2332d65f70fdSStefano Zampini } 2333d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 2334d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 2335d65f70fdSStefano Zampini } 2336d65f70fdSStefano Zampini } else { 2337d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 2338d65f70fdSStefano Zampini iscol_s = iscol; 2339d65f70fdSStefano Zampini } 2340d65f70fdSStefano Zampini 2341d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2342d65f70fdSStefano Zampini 2343d65f70fdSStefano Zampini if (!rsorted || !csorted) { 2344906d46d4SStefano Zampini Mat new_mat; 2345d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 2346906d46d4SStefano Zampini 2347d65f70fdSStefano Zampini if (!rsorted) { 2348d65f70fdSStefano Zampini PetscInt *idxs_r,i; 2349d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 2350d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2351d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 2352906d46d4SStefano Zampini } 2353d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 2354d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 2355d65f70fdSStefano Zampini } else { 2356d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 2357906d46d4SStefano Zampini } 2358d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 2359d65f70fdSStefano Zampini 2360d65f70fdSStefano Zampini if (!csorted) { 2361d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 2362d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 2363d65f70fdSStefano Zampini is_perm_c = is_perm_r; 2364d65f70fdSStefano Zampini } else { 2365d65f70fdSStefano Zampini PetscInt *idxs_c,i; 2366d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 2367d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2368d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 2369d65f70fdSStefano Zampini } 2370d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 2371d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 2372d65f70fdSStefano Zampini } 2373d65f70fdSStefano Zampini } else { 2374d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 2375d65f70fdSStefano Zampini } 2376d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 2377d65f70fdSStefano Zampini 2378d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 2379d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 2380d65f70fdSStefano Zampini work_mat[0] = new_mat; 2381d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 2382d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 2383d65f70fdSStefano Zampini } 2384d65f70fdSStefano Zampini 2385d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 2386d65f70fdSStefano Zampini *B = work_mat[0]; 2387d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 2388d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 2389d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 2390d65f70fdSStefano Zampini PetscFunctionReturn(0); 2391d65f70fdSStefano Zampini } 2392d65f70fdSStefano Zampini 2393d65f70fdSStefano Zampini #undef __FUNCT__ 23945e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 23955e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 2396aa0d41d4SStefano Zampini { 2397aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 23985e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2399d65f70fdSStefano Zampini Mat new_mat; 24005e8657edSStefano Zampini IS is_local,is_global; 2401d65f70fdSStefano Zampini PetscInt local_size; 2402d65f70fdSStefano Zampini PetscBool isseqaij; 2403aa0d41d4SStefano Zampini PetscErrorCode ierr; 2404aa0d41d4SStefano Zampini 2405aa0d41d4SStefano Zampini PetscFunctionBegin; 2406aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 24075e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 24085e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 2409b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 2410aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 2411d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 2412aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 2413906d46d4SStefano Zampini 2414906d46d4SStefano Zampini /* check */ 2415906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2416906d46d4SStefano Zampini Vec x,x_change; 2417906d46d4SStefano Zampini PetscReal error; 2418906d46d4SStefano Zampini 24195e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 2420906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 24215e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 2422e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2423e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2424d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 2425e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2426e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2427906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2428906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2429906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2430906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 2431906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2432906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2433906d46d4SStefano Zampini } 2434906d46d4SStefano Zampini 243522d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 24369b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 243722d5777bSStefano Zampini if (isseqaij) { 24381cf9b237SStefano Zampini Mat M; 24391cf9b237SStefano Zampini 24401cf9b237SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 24411cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 24421cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2443aa0d41d4SStefano Zampini } else { 24441cf9b237SStefano Zampini Mat work_mat,M; 24451cf9b237SStefano Zampini 2446aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 24471cf9b237SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 24481cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 24491cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2450aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 2451aa0d41d4SStefano Zampini } 24523301b35fSStefano Zampini if (matis->A->symmetric_set) { 24533301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 2454e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 24553301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 2456e496cd5dSStefano Zampini #endif 24573301b35fSStefano Zampini } 245845a1bb75SStefano Zampini /* 245945a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2460d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 246145a1bb75SStefano Zampini */ 2462d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 2463aa0d41d4SStefano Zampini PetscFunctionReturn(0); 2464aa0d41d4SStefano Zampini } 2465aa0d41d4SStefano Zampini 2466aa0d41d4SStefano Zampini #undef __FUNCT__ 2467a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 24688ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2469a64d13efSStefano Zampini { 2470a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2471a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2472d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 247353892102SStefano Zampini PetscInt *idx_R_local=NULL; 24743a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 24753a50541eSStefano Zampini PetscInt vbs,bs; 24766816873aSStefano Zampini PetscBT bitmask=NULL; 2477a64d13efSStefano Zampini PetscErrorCode ierr; 2478a64d13efSStefano Zampini 2479a64d13efSStefano Zampini PetscFunctionBegin; 2480b23d619eSStefano Zampini /* 2481b23d619eSStefano Zampini No need to setup local scatters if 2482b23d619eSStefano Zampini - primal space is unchanged 2483b23d619eSStefano Zampini AND 2484b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2485b23d619eSStefano Zampini AND 2486b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2487b23d619eSStefano Zampini */ 2488b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2489f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2490f4ddd8eeSStefano Zampini } 2491f4ddd8eeSStefano Zampini /* destroy old objects */ 2492f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2493f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2494f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2495a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2496b371cd4fSStefano Zampini n_B = pcis->n_B; 2497b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2498b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 24993a50541eSStefano Zampini 2500a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 25016816873aSStefano Zampini 250253892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 2503df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 2504854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2505a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2506a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 25070e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2508a64d13efSStefano Zampini } 2509a64d13efSStefano Zampini 2510a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 25114641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 25126816873aSStefano Zampini idx_R_local[n_R++] = i; 2513a64d13efSStefano Zampini } 2514a64d13efSStefano Zampini } 2515df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 2516df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 25176816873aSStefano Zampini 2518df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2519df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 25206816873aSStefano Zampini } 25213a50541eSStefano Zampini 25223a50541eSStefano Zampini /* Block code */ 25233a50541eSStefano Zampini vbs = 1; 25243a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 25253a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 25263a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 25273a50541eSStefano Zampini PetscInt *vary; 2528df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 2529785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 25303a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2531d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2532d3df7717SStefano 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 */ 25330e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2534d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 25353a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 25363a50541eSStefano Zampini is_blocked = PETSC_FALSE; 25373a50541eSStefano Zampini break; 25383a50541eSStefano Zampini } 25393a50541eSStefano Zampini } 2540d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2541d3df7717SStefano Zampini } else { 2542d3df7717SStefano Zampini /* Verify directly the R set */ 2543d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2544d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2545d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2546d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2547d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2548d3df7717SStefano Zampini break; 2549d3df7717SStefano Zampini } 2550d3df7717SStefano Zampini } 2551d3df7717SStefano Zampini } 2552d3df7717SStefano Zampini } 25533a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 25543a50541eSStefano Zampini vbs = bs; 25553a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 25563a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 25573a50541eSStefano Zampini } 25583a50541eSStefano Zampini } 25593a50541eSStefano Zampini } 25603a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 2561df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 2562df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 256353892102SStefano Zampini 2564df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2565df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 256653892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 2567df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 256853892102SStefano Zampini } else { 25693a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 257053892102SStefano Zampini } 2571a64d13efSStefano Zampini 2572a64d13efSStefano Zampini /* print some info if requested */ 2573a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 2574a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2575a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 25761575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2577a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 2578a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 25794f1b2e48SStefano 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); 2580a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2581a64d13efSStefano Zampini } 2582a64d13efSStefano Zampini 2583a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 2584df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 25856816873aSStefano Zampini IS is_aux1,is_aux2; 25866816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 25876816873aSStefano Zampini 25883a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2589854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 2590854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 2591a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 25924641a718SStefano Zampini for (i=0; i<n_D; i++) { 25934641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 25944641a718SStefano Zampini } 2595a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2596a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 25974641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 25984641a718SStefano Zampini aux_array1[j++] = i; 2599a64d13efSStefano Zampini } 2600a64d13efSStefano Zampini } 2601a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2602a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2603a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 26044641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 26054641a718SStefano Zampini aux_array2[j++] = i; 2606a64d13efSStefano Zampini } 2607a64d13efSStefano Zampini } 2608a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2609a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 2610a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 2611a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2612a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 2613a64d13efSStefano Zampini 26148eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2615785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 2616a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 26174641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 26184641a718SStefano Zampini aux_array1[j++] = i; 2619a64d13efSStefano Zampini } 2620a64d13efSStefano Zampini } 2621a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2622a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 2623a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2624a64d13efSStefano Zampini } 26254641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 26263a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2627d62866d3SStefano Zampini } else { 2628df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 26296816873aSStefano Zampini IS tis; 26306816873aSStefano Zampini PetscInt schur_size; 26316816873aSStefano Zampini 2632df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 26336816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 2634df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 26356816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 26366816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 26376816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 26386816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 26396816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2640d62866d3SStefano Zampini } 2641d62866d3SStefano Zampini } 2642a64d13efSStefano Zampini PetscFunctionReturn(0); 2643a64d13efSStefano Zampini } 2644a64d13efSStefano Zampini 2645304d26faSStefano Zampini 2646304d26faSStefano Zampini #undef __FUNCT__ 2647304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 2648684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 2649304d26faSStefano Zampini { 2650304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2651304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2652304d26faSStefano Zampini PC pc_temp; 2653304d26faSStefano Zampini Mat A_RR; 2654f4ddd8eeSStefano Zampini MatReuse reuse; 2655304d26faSStefano Zampini PetscScalar m_one = -1.0; 2656304d26faSStefano Zampini PetscReal value; 265704708bb6SStefano Zampini PetscInt n_D,n_R; 26589577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 2659304d26faSStefano Zampini PetscErrorCode ierr; 2660e604994aSStefano Zampini /* prefixes stuff */ 2661312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 2662e604994aSStefano Zampini size_t len; 2663304d26faSStefano Zampini 2664304d26faSStefano Zampini PetscFunctionBegin; 2665304d26faSStefano Zampini 2666e604994aSStefano Zampini /* compute prefixes */ 2667e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 2668e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 2669e604994aSStefano Zampini if (!pcbddc->current_level) { 2670e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2671e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2672e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2673e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2674e604994aSStefano Zampini } else { 2675e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 2676312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 2677e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 2678e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 2679312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 2680312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 268134d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 268234d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 2683e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2684e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2685e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 2686e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 2687e604994aSStefano Zampini } 2688e604994aSStefano Zampini 2689304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 2690684f6988SStefano Zampini if (dirichlet) { 2691d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2692a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit && pcbddc->dbg_flag) { 2693a3df083aSStefano Zampini Mat A_IIn; 2694a3df083aSStefano Zampini 2695a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 2696a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 2697a3df083aSStefano Zampini pcis->A_II = A_IIn; 2698a3df083aSStefano Zampini } 26993301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 27003301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 2701964fefecSStefano Zampini } 2702ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 2703964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 2704304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 2705304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 2706304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 2707304d26faSStefano Zampini /* default */ 2708304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 2709e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 27109577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 2711304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 27129577ea80SStefano Zampini if (issbaij) { 27139577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 27149577ea80SStefano Zampini } else { 2715304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 27169577ea80SStefano Zampini } 2717304d26faSStefano Zampini /* Allow user's customization */ 2718304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 2719304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2720304d26faSStefano Zampini } 2721d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 2722df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 2723df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2724d62866d3SStefano Zampini 2725df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 2726d5574798SStefano Zampini } 2727304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2728304d26faSStefano Zampini if (!n_D) { 2729304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 2730304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2731304d26faSStefano Zampini } 2732304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 2733304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 2734304d26faSStefano Zampini /* set ksp_D into pcis data */ 2735304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 2736304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 2737304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 2738684f6988SStefano Zampini } 2739304d26faSStefano Zampini 2740304d26faSStefano Zampini /* NEUMANN PROBLEM */ 2741684f6988SStefano Zampini A_RR = 0; 2742684f6988SStefano Zampini if (neumann) { 2743d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 274404708bb6SStefano Zampini PetscInt ibs,mbs; 274504708bb6SStefano Zampini PetscBool issbaij; 274604708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2747f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 27488ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 2749f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 2750f4ddd8eeSStefano Zampini PetscInt nn_R; 275181d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 2752f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2753f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 2754f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 2755f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 2756f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2757f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2758f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 2759727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 2760f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2761f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2762f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 2763f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 2764f4ddd8eeSStefano Zampini } 2765f4ddd8eeSStefano Zampini } 2766f4ddd8eeSStefano Zampini /* last check */ 2767d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 2768f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2769f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2770f4ddd8eeSStefano Zampini } 2771f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 2772f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2773f4ddd8eeSStefano Zampini } 2774f4ddd8eeSStefano Zampini /* extract A_RR */ 2775af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 2776af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 277704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 277804708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 277904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 278004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 278104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 2782af732b37SStefano Zampini } else { 278304708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 27846816873aSStefano Zampini } 278504708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 278604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 278704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 278804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 278904708bb6SStefano Zampini } else { 279004708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 279104708bb6SStefano Zampini } 279204708bb6SStefano Zampini } 2793f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 27943301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 27953301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 27966816873aSStefano Zampini } 2797a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit && pcbddc->dbg_flag) { 2798a3df083aSStefano Zampini Mat A_RRn; 2799a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RRn);CHKERRQ(ierr); 2800a3df083aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2801a3df083aSStefano Zampini A_RR = A_RRn; 2802a3df083aSStefano Zampini } 2803f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 2804304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 2805304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 2806304d26faSStefano Zampini /* default */ 2807304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 2808e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 2809304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 28109577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 28119577ea80SStefano Zampini if (issbaij) { 28129577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 28139577ea80SStefano Zampini } else { 2814304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 28159577ea80SStefano Zampini } 2816304d26faSStefano Zampini /* Allow user's customization */ 2817304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 2818304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2819304d26faSStefano Zampini } 2820304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2821304d26faSStefano Zampini if (!n_R) { 2822304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 2823304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2824304d26faSStefano Zampini } 2825df4d28bfSStefano Zampini /* Reuse solver if it is present */ 2826df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 2827df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2828d62866d3SStefano Zampini 2829df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 2830d62866d3SStefano Zampini } 2831ffd830a3SStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 2832304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 2833304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 2834684f6988SStefano Zampini } 28356816873aSStefano Zampini /* free Neumann problem's matrix */ 28366816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2837304d26faSStefano Zampini 2838304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 28390fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 2840684f6988SStefano Zampini if (pcbddc->dbg_flag) { 2841684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 28421575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2843684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2844684f6988SStefano Zampini } 2845684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 28460fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 28470fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 28480fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 28490fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 28500fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 2851304d26faSStefano Zampini /* need to be adapted? */ 2852b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2853b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2854b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 2855304d26faSStefano Zampini /* print info */ 2856304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2857e604994aSStefano 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); 2858304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2859304d26faSStefano Zampini } 2860b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 2861298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 2862304d26faSStefano Zampini } 2863684f6988SStefano Zampini } 2864684f6988SStefano Zampini if (neumann) { /* Neumann */ 28656816873aSStefano Zampini ierr = KSPGetOperators(pcbddc->ksp_R,&A_RR,NULL);CHKERRQ(ierr); 28660fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 28670fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 28680fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 28690fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 28700fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 2871304d26faSStefano Zampini /* need to be adapted? */ 2872b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2873b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2874304d26faSStefano Zampini /* print info */ 2875304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2876e604994aSStefano 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); 2877304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2878304d26faSStefano Zampini } 2879b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 2880298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 2881304d26faSStefano Zampini } 28820fccc4e9SStefano Zampini } 2883684f6988SStefano Zampini } 2884304d26faSStefano Zampini PetscFunctionReturn(0); 2885304d26faSStefano Zampini } 2886304d26faSStefano Zampini 2887304d26faSStefano Zampini #undef __FUNCT__ 2888ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 288980677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 2890674ae819SStefano Zampini { 2891674ae819SStefano Zampini PetscErrorCode ierr; 2892674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2893be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2894674ae819SStefano Zampini 2895674ae819SStefano Zampini PetscFunctionBegin; 2896df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 289780677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 289820c7b377SStefano Zampini } 289980677318SStefano Zampini if (!pcbddc->switch_static) { 290080677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 290180677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 290280677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 290320c7b377SStefano Zampini } 2904df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 290580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 290680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 290720c7b377SStefano Zampini } else { 2908df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2909be83ff47SStefano Zampini 2910df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2911df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 291220c7b377SStefano Zampini } 2913be83ff47SStefano Zampini } else { 291480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 291580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 291680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 291780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 291880677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 291980677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 292080677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 292180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 292280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2923674ae819SStefano Zampini } 2924674ae819SStefano Zampini } 2925df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 292680677318SStefano Zampini if (applytranspose) { 292780677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 292880677318SStefano Zampini } else { 292980677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 293080677318SStefano Zampini } 2931be83ff47SStefano Zampini } else { 2932df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2933be83ff47SStefano Zampini 2934be83ff47SStefano Zampini if (applytranspose) { 2935df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 2936be83ff47SStefano Zampini } else { 2937df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 2938be83ff47SStefano Zampini } 2939be83ff47SStefano Zampini } 294080677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 294180677318SStefano Zampini if (!pcbddc->switch_static) { 2942df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 294380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 294480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2945be83ff47SStefano Zampini } else { 2946df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2947be83ff47SStefano Zampini 2948df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2949df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2950be83ff47SStefano Zampini } 295180677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 295280677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 295380677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 295480677318SStefano Zampini } 295580677318SStefano Zampini } else { 295680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 295780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 295880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 295980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 296080677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 296180677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 296280677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 296380677318SStefano Zampini } 296480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 296580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 296680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 296780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2968674ae819SStefano Zampini } 2969674ae819SStefano Zampini PetscFunctionReturn(0); 2970674ae819SStefano Zampini } 2971674ae819SStefano Zampini 2972dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 2973674ae819SStefano Zampini #undef __FUNCT__ 2974674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 2975dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 2976674ae819SStefano Zampini { 2977674ae819SStefano Zampini PetscErrorCode ierr; 2978674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2979674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 2980674ae819SStefano Zampini const PetscScalar zero = 0.0; 2981674ae819SStefano Zampini 2982674ae819SStefano Zampini PetscFunctionBegin; 2983dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 2984dc359a40SStefano Zampini if (applytranspose) { 2985674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 29868eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 2987dc359a40SStefano Zampini } else { 2988674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 2989674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 299015aaf578SStefano Zampini } 2991efc2fbd9SStefano Zampini 2992efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 29934f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2994efc2fbd9SStefano Zampini PetscScalar *array; 29954f1b2e48SStefano Zampini PetscInt j; 2996efc2fbd9SStefano Zampini 2997efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 29984f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 2999efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3000efc2fbd9SStefano Zampini } 3001efc2fbd9SStefano Zampini 300212edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 300312edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 300412edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 300512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 300612edc857SStefano Zampini 30079f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 300812edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 300912edc857SStefano Zampini if (pcbddc->coarse_ksp) { 301051694757SStefano Zampini Mat coarse_mat; 3011964fefecSStefano Zampini Vec rhs,sol; 301251694757SStefano Zampini MatNullSpace nullsp; 3013964fefecSStefano Zampini 3014964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 3015964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 301651694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 301751694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 301851694757SStefano Zampini if (nullsp) { 301951694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 302051694757SStefano Zampini } 302112edc857SStefano Zampini if (applytranspose) { 3022964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 302312edc857SStefano Zampini } else { 3024964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 302512edc857SStefano Zampini } 302651694757SStefano Zampini if (nullsp) { 302751694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 302851694757SStefano Zampini } 302912edc857SStefano Zampini } 3030674ae819SStefano Zampini 3031674ae819SStefano Zampini /* Local solution on R nodes */ 303280677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 303380677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 30349f00e9b4SStefano Zampini } 3035674ae819SStefano Zampini 30369f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 30379f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 303812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3039674ae819SStefano Zampini 3040674ae819SStefano Zampini /* Sum contributions from two levels */ 3041dc359a40SStefano Zampini if (applytranspose) { 3042dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 3043dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3044dc359a40SStefano Zampini } else { 3045674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 30468eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3047dc359a40SStefano Zampini } 3048efc2fbd9SStefano Zampini /* store p0 */ 30494f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3050efc2fbd9SStefano Zampini PetscScalar *array; 30514f1b2e48SStefano Zampini PetscInt j; 3052efc2fbd9SStefano Zampini 3053efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 30544f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 3055efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3056efc2fbd9SStefano Zampini } 3057674ae819SStefano Zampini PetscFunctionReturn(0); 3058674ae819SStefano Zampini } 3059674ae819SStefano Zampini 3060674ae819SStefano Zampini #undef __FUNCT__ 3061674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 306212edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 3063674ae819SStefano Zampini { 3064674ae819SStefano Zampini PetscErrorCode ierr; 3065674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 306658da7f69SStefano Zampini PetscScalar *array; 306712edc857SStefano Zampini Vec from,to; 3068674ae819SStefano Zampini 3069674ae819SStefano Zampini PetscFunctionBegin; 307012edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 307112edc857SStefano Zampini from = pcbddc->coarse_vec; 307212edc857SStefano Zampini to = pcbddc->vec1_P; 307312edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 307412edc857SStefano Zampini Vec tvec; 307558da7f69SStefano Zampini 307658da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 307758da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 307812edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 307958da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 308058da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 308158da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 308212edc857SStefano Zampini } 308312edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 308412edc857SStefano Zampini from = pcbddc->vec1_P; 308512edc857SStefano Zampini to = pcbddc->coarse_vec; 308612edc857SStefano Zampini } 308712edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 3088674ae819SStefano Zampini PetscFunctionReturn(0); 3089674ae819SStefano Zampini } 3090674ae819SStefano Zampini 3091674ae819SStefano Zampini #undef __FUNCT__ 3092674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 309312edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 3094674ae819SStefano Zampini { 3095674ae819SStefano Zampini PetscErrorCode ierr; 3096674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 309758da7f69SStefano Zampini PetscScalar *array; 309812edc857SStefano Zampini Vec from,to; 3099674ae819SStefano Zampini 3100674ae819SStefano Zampini PetscFunctionBegin; 310112edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 310212edc857SStefano Zampini from = pcbddc->coarse_vec; 310312edc857SStefano Zampini to = pcbddc->vec1_P; 310412edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 310512edc857SStefano Zampini from = pcbddc->vec1_P; 310612edc857SStefano Zampini to = pcbddc->coarse_vec; 310712edc857SStefano Zampini } 310812edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 310912edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 311012edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 311112edc857SStefano Zampini Vec tvec; 311258da7f69SStefano Zampini 311312edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 311458da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 311558da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 311658da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 311758da7f69SStefano Zampini } 311858da7f69SStefano Zampini } else { 311958da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 312058da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 312112edc857SStefano Zampini } 312212edc857SStefano Zampini } 3123674ae819SStefano Zampini PetscFunctionReturn(0); 3124674ae819SStefano Zampini } 3125674ae819SStefano Zampini 3126984c4197SStefano Zampini /* uncomment for testing purposes */ 3127984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 3128674ae819SStefano Zampini #undef __FUNCT__ 3129674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 3130674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 3131674ae819SStefano Zampini { 3132674ae819SStefano Zampini PetscErrorCode ierr; 3133674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3134674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3135674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3136984c4197SStefano Zampini /* one and zero */ 3137984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 3138984c4197SStefano Zampini /* space to store constraints and their local indices */ 31399162d606SStefano Zampini PetscScalar *constraints_data; 31409162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 31419162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 31429162d606SStefano Zampini PetscInt *constraints_n; 3143984c4197SStefano Zampini /* iterators */ 3144b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 3145984c4197SStefano Zampini /* BLAS integers */ 3146e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 3147e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 3148c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 3149727cdba6SStefano Zampini /* reuse */ 31500e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 31510e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 3152984c4197SStefano Zampini /* change of basis */ 3153b3d85658SStefano Zampini PetscBool qr_needed; 31549162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 3155984c4197SStefano Zampini /* auxiliary stuff */ 315664efe560SStefano Zampini PetscInt *nnz,*is_indices; 31578a0068c3SStefano Zampini PetscInt ncc; 3158984c4197SStefano Zampini /* some quantities */ 315945a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 3160a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 3161984c4197SStefano Zampini 3162674ae819SStefano Zampini PetscFunctionBegin; 31638e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 31648e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 31658e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3166088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 3167088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 31680e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 31690e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 31700e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 31710e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 31720e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3173088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3174cf5a6209SStefano Zampini 3175cf5a6209SStefano Zampini /* print some info */ 3176cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 3177cf5a6209SStefano Zampini IS vertices; 3178cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 3179cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 3180cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 3181cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 31821575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3183cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3184cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 3185fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 3186fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 3187cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 31881575c14dSBarry Smith ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3189cf5a6209SStefano Zampini } 3190cf5a6209SStefano Zampini 3191cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 31929162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 3193cf5a6209SStefano Zampini MatNullSpace nearnullsp; 3194cf5a6209SStefano Zampini const Vec *nearnullvecs; 3195cf5a6209SStefano Zampini Vec *localnearnullsp; 3196cf5a6209SStefano Zampini PetscScalar *array; 3197cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 3198cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 3199674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 3200b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 3201674ae819SStefano Zampini PetscScalar *work; 3202674ae819SStefano Zampini PetscReal *singular_vals; 3203674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3204674ae819SStefano Zampini PetscReal *rwork; 3205674ae819SStefano Zampini #endif 3206674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3207674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 3208674ae819SStefano Zampini #else 3209964fefecSStefano Zampini PetscBLASInt dummy_int=1; 3210964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 3211674ae819SStefano Zampini #endif 3212674ae819SStefano Zampini 3213674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 3214d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 3215d06fc5fdSStefano Zampini /* free unneeded index sets */ 3216d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 3217d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 3218674ae819SStefano Zampini } 3219d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 3220d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3221d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3222d06fc5fdSStefano Zampini } 3223d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3224d06fc5fdSStefano Zampini n_ISForEdges = 0; 3225d06fc5fdSStefano Zampini } 3226d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 3227d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3228d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3229d06fc5fdSStefano Zampini } 3230d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3231d06fc5fdSStefano Zampini n_ISForFaces = 0; 3232d06fc5fdSStefano Zampini } 323370022509SStefano Zampini 323470022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 323570022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 323670022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 323770022509SStefano Zampini if (pcbddc->NullSpace) { 323870022509SStefano Zampini PetscBool tbool[2],gbool[2]; 323970022509SStefano Zampini 324070022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 3241b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 3242d06fc5fdSStefano Zampini if (!ISForEdges) { 3243d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 3244d06fc5fdSStefano Zampini } 3245b8ffe317SStefano Zampini } 3246d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 3247d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 3248d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3249d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 3250d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 325198a51de6SStefano Zampini } 325270022509SStefano Zampini #endif 325308122e43SStefano Zampini 3254674ae819SStefano Zampini /* check if near null space is attached to global mat */ 3255674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 3256674ae819SStefano Zampini if (nearnullsp) { 3257674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 3258f4ddd8eeSStefano Zampini /* remove any stored info */ 3259f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3260f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3261f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 3262f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 3263f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 3264473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3265f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 3266f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 3267f4ddd8eeSStefano Zampini } 3268984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 3269984c4197SStefano Zampini nnsp_size = 0; 3270674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 3271674ae819SStefano Zampini } 3272984c4197SStefano Zampini /* get max number of constraints on a single cc */ 3273984c4197SStefano Zampini max_constraints = nnsp_size; 3274984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 3275984c4197SStefano Zampini 3276674ae819SStefano Zampini /* 3277674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 32789162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 32799162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 32809162d606SStefano Zampini There can be multiple constraints per connected component 3281674ae819SStefano Zampini */ 3282674ae819SStefano Zampini n_vertices = 0; 3283674ae819SStefano Zampini if (ISForVertices) { 3284674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 3285674ae819SStefano Zampini } 32869162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 32879162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 32889162d606SStefano Zampini 32899162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 32909162d606SStefano Zampini total_counts *= max_constraints; 3291674ae819SStefano Zampini total_counts += n_vertices; 32924641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 32939162d606SStefano Zampini 3294674ae819SStefano Zampini total_counts = 0; 3295674ae819SStefano Zampini max_size_of_constraint = 0; 3296674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 32979162d606SStefano Zampini IS used_is; 3298674ae819SStefano Zampini if (i<n_ISForEdges) { 32999162d606SStefano Zampini used_is = ISForEdges[i]; 3300674ae819SStefano Zampini } else { 33019162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 3302674ae819SStefano Zampini } 33039162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 3304674ae819SStefano Zampini total_counts += j; 3305674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 3306674ae819SStefano Zampini } 33079162d606SStefano 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); 33089162d606SStefano Zampini 3309984c4197SStefano Zampini /* get local part of global near null space vectors */ 3310785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 3311984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3312984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 3313e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3314e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3315984c4197SStefano Zampini } 3316674ae819SStefano Zampini 3317242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 3318242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 3319a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 3320242a89d7SStefano Zampini 3321984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 3322a773dcb8SStefano Zampini if (!skip_lapack) { 3323674ae819SStefano Zampini PetscScalar temp_work; 3324911cabfeSStefano Zampini 3325674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3326984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 3327785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 3328785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 3329785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 3330674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3331785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 3332674ae819SStefano Zampini #endif 3333674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3334c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 3335c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 3336674ae819SStefano Zampini lwork = -1; 3337674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3338674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3339c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 3340674ae819SStefano Zampini #else 3341c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 3342674ae819SStefano Zampini #endif 3343674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3344984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 3345674ae819SStefano Zampini #else /* on missing GESVD */ 3346674ae819SStefano Zampini /* SVD */ 3347674ae819SStefano Zampini PetscInt max_n,min_n; 3348674ae819SStefano Zampini max_n = max_size_of_constraint; 3349984c4197SStefano Zampini min_n = max_constraints; 3350984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 3351674ae819SStefano Zampini min_n = max_size_of_constraint; 3352984c4197SStefano Zampini max_n = max_constraints; 3353674ae819SStefano Zampini } 3354785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 3355674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3356785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 3357674ae819SStefano Zampini #endif 3358674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3359674ae819SStefano Zampini lwork = -1; 3360e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 3361e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 3362b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 3363674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3364674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 33659162d606SStefano 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)); 3366674ae819SStefano Zampini #else 33679162d606SStefano 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)); 3368674ae819SStefano Zampini #endif 3369674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3370984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 3371984c4197SStefano Zampini #endif /* on missing GESVD */ 3372674ae819SStefano Zampini /* Allocate optimal workspace */ 3373674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 3374854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 3375674ae819SStefano Zampini } 3376674ae819SStefano Zampini /* Now we can loop on constraining sets */ 3377674ae819SStefano Zampini total_counts = 0; 33789162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 33799162d606SStefano Zampini constraints_data_ptr[0] = 0; 3380674ae819SStefano Zampini /* vertices */ 33819162d606SStefano Zampini if (n_vertices) { 3382674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 33839162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 3384674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 33859162d606SStefano Zampini constraints_n[total_counts] = 1; 33869162d606SStefano Zampini constraints_data[total_counts] = 1.0; 33879162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 33889162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 3389674ae819SStefano Zampini total_counts++; 3390674ae819SStefano Zampini } 3391674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3392674ae819SStefano Zampini n_vertices = total_counts; 3393674ae819SStefano Zampini } 3394984c4197SStefano Zampini 3395674ae819SStefano Zampini /* edges and faces */ 33969162d606SStefano Zampini total_counts_cc = total_counts; 3397911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 33989162d606SStefano Zampini IS used_is; 33999162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 34009162d606SStefano Zampini 3401911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 34029162d606SStefano Zampini used_is = ISForEdges[ncc]; 3403984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 3404674ae819SStefano Zampini } else { 34059162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 3406984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 3407674ae819SStefano Zampini } 3408674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 34099162d606SStefano Zampini 34109162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 34119162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3412984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 3413984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 3414674ae819SStefano Zampini if (nnsp_has_cnst) { 34155b08dc53SStefano Zampini PetscScalar quad_value; 34169162d606SStefano Zampini 34179162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 34189162d606SStefano Zampini idxs_copied = PETSC_TRUE; 34199162d606SStefano Zampini 3420a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 3421674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 3422a773dcb8SStefano Zampini } else { 3423a773dcb8SStefano Zampini quad_value = 1.0; 3424a773dcb8SStefano Zampini } 3425674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 34269162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 3427674ae819SStefano Zampini } 34289162d606SStefano Zampini temp_constraints++; 3429674ae819SStefano Zampini total_counts++; 3430674ae819SStefano Zampini } 3431674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 3432984c4197SStefano Zampini PetscReal real_value; 34339162d606SStefano Zampini PetscScalar *ptr_to_data; 34349162d606SStefano Zampini 3435984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 34369162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 3437674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 34389162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 3439674ae819SStefano Zampini } 3440984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 3441984c4197SStefano Zampini /* check if array is null on the connected component */ 3442e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 34439162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 34445b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 3445674ae819SStefano Zampini temp_constraints++; 3446674ae819SStefano Zampini total_counts++; 34479162d606SStefano Zampini if (!idxs_copied) { 34489162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 34499162d606SStefano Zampini idxs_copied = PETSC_TRUE; 3450674ae819SStefano Zampini } 3451674ae819SStefano Zampini } 34529162d606SStefano Zampini } 34539162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 345445a1bb75SStefano Zampini valid_constraints = temp_constraints; 3455eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 3456a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 34579162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 34589162d606SStefano Zampini 34599162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3460a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 34619162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 3462a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 34639162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 3464a773dcb8SStefano Zampini } else { /* perform SVD */ 3465984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 34669162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3467674ae819SStefano Zampini 3468674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3469984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3470984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3471984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3472984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3473984c4197SStefano Zampini from that computed using LAPACKgesvd 3474984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3475984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3476984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3477674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3478e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3479984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3480674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3481674ae819SStefano Zampini for (k=0;k<j+1;k++) { 34829162d606SStefano 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)); 3483674ae819SStefano Zampini } 3484674ae819SStefano Zampini } 3485e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3486e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3487e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3488674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3489c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3490674ae819SStefano Zampini #else 3491c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3492674ae819SStefano Zampini #endif 3493674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3494984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3495984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3496674ae819SStefano Zampini j = 0; 3497984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3498674ae819SStefano Zampini total_counts = total_counts-j; 349945a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3500e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3501c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3502c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3503c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3504c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3505c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3506c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3507674ae819SStefano Zampini if (j<temp_constraints) { 3508984c4197SStefano Zampini PetscInt ii; 3509984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3510674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 35119162d606SStefano 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)); 3512674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3513984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3514674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 35159162d606SStefano 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]; 3516674ae819SStefano Zampini } 3517674ae819SStefano Zampini } 3518674ae819SStefano Zampini } 3519674ae819SStefano Zampini #else /* on missing GESVD */ 3520e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3521e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3522b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3523674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3524674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 35259162d606SStefano 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)); 3526674ae819SStefano Zampini #else 35279162d606SStefano 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)); 3528674ae819SStefano Zampini #endif 3529984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 3530674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3531984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 3532e310c8b4SStefano Zampini k = temp_constraints; 3533e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 3534674ae819SStefano Zampini j = 0; 3535e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 353645a1bb75SStefano Zampini valid_constraints = k-j; 3537911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 3538984c4197SStefano Zampini #endif /* on missing GESVD */ 3539674ae819SStefano Zampini } 3540a773dcb8SStefano Zampini } 35419162d606SStefano Zampini /* update pointers information */ 35429162d606SStefano Zampini if (valid_constraints) { 35439162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 35449162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 35459162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 35469162d606SStefano Zampini /* set change_of_basis flag */ 354745a1bb75SStefano Zampini if (boolforchange) { 3548b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 35499162d606SStefano Zampini } 3550b3d85658SStefano Zampini total_counts_cc++; 355145a1bb75SStefano Zampini } 355245a1bb75SStefano Zampini } 3553984c4197SStefano Zampini /* free workspace */ 35548f1c130eSStefano Zampini if (!skip_lapack) { 3555984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3556984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3557984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 3558984c4197SStefano Zampini #endif 3559984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 3560984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3561984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 3562984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 3563984c4197SStefano Zampini #endif 3564984c4197SStefano Zampini } 3565984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3566984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 3567984c4197SStefano Zampini } 3568984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 3569cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 3570cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3571cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3572cf5a6209SStefano Zampini } 3573cf5a6209SStefano Zampini if (n_ISForFaces) { 3574cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3575cf5a6209SStefano Zampini } 3576cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3577cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3578cf5a6209SStefano Zampini } 3579cf5a6209SStefano Zampini if (n_ISForEdges) { 3580cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3581cf5a6209SStefano Zampini } 3582cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 358308122e43SStefano Zampini } else { 358408122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3585984c4197SStefano Zampini 358608122e43SStefano Zampini total_counts = 0; 358708122e43SStefano Zampini n_vertices = 0; 3588d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 3589d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 359008122e43SStefano Zampini } 359108122e43SStefano Zampini max_constraints = 0; 35929162d606SStefano Zampini total_counts_cc = 0; 359308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 359408122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 35959162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 359608122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 359708122e43SStefano Zampini } 35989162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 35999162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 36009162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 36019162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 360274d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 36039162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 36049162d606SStefano Zampini total_counts_cc = 0; 36059162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 36069162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 36079162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 360808122e43SStefano Zampini } 360908122e43SStefano Zampini } 36109162d606SStefano Zampini #if 0 36119162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 36129162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 36139162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 36149162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 36159162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 36169162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 36179162d606SStefano Zampini } 36189162d606SStefano Zampini printf("\n"); 36199162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 36209162d606SStefano Zampini } 36211b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 36228bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 36231b968477SStefano Zampini } 36241b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 36258bec7fa6SStefano 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]); 36261b968477SStefano Zampini } 362708122e43SStefano Zampini #endif 362808122e43SStefano Zampini 36298bec7fa6SStefano Zampini max_size_of_constraint = 0; 36309162d606SStefano 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]); 36319162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 363208122e43SStefano Zampini /* Change of basis */ 3633b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 363408122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 363508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 363608122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 3637b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 363808122e43SStefano Zampini } 363908122e43SStefano Zampini } 364008122e43SStefano Zampini } 364108122e43SStefano Zampini } 3642984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 36434f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 364408122e43SStefano Zampini 36459162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 36469162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 36479162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 36489162d606SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %d != %d\n",constraints_idxs_ptr[total_counts_cc],i); 364908122e43SStefano Zampini } 3650674ae819SStefano Zampini 3651674ae819SStefano Zampini /* Create constraint matrix */ 3652674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 365316f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 3654984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 3655984c4197SStefano Zampini 3656984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 3657a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 3658a717540cSStefano Zampini qr_needed = PETSC_FALSE; 365974d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 3660984c4197SStefano Zampini total_primal_vertices=0; 3661b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 36629162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 36639162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3664984c4197SStefano Zampini if (size_of_constraint == 1) { 36659162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 3666b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 366764efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 36689162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 36699162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 3670a717540cSStefano Zampini } 3671b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 367274d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 3673a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 3674a717540cSStefano Zampini qr_needed = PETSC_TRUE; 3675a717540cSStefano Zampini } 3676fa434743SStefano Zampini } else { 3677b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 3678fa434743SStefano Zampini } 3679a717540cSStefano Zampini } 3680b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 3681b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 3682674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 368370022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3684b3d85658SStefano Zampini 36854f1b2e48SStefano 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); 36860e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 36870e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 3688984c4197SStefano Zampini 3689984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 369074d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 3691785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 3692984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 369374d5cdf7SStefano Zampini 3694984c4197SStefano Zampini j = total_primal_vertices; 369574d5cdf7SStefano Zampini total_counts = total_primal_vertices; 3696b3d85658SStefano Zampini cum = total_primal_vertices; 36979162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 36984641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 3699b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 3700b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 3701b3d85658SStefano Zampini cum++; 37029162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 370374d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 370474d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 370574d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 370674d5cdf7SStefano Zampini } 37079162d606SStefano Zampini j += constraints_n[i]; 3708674ae819SStefano Zampini } 3709674ae819SStefano Zampini } 3710674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 3711674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3712088faed8SStefano Zampini 3713674ae819SStefano Zampini /* set values in constraint matrix */ 3714984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 37150e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 3716674ae819SStefano Zampini } 3717984c4197SStefano Zampini total_counts = total_primal_vertices; 37189162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 37194641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 37209162d606SStefano Zampini PetscInt *cols; 37219162d606SStefano Zampini 37229162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 37239162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 37249162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 37259162d606SStefano Zampini PetscInt row = total_counts+k; 37269162d606SStefano Zampini PetscScalar *vals; 37279162d606SStefano Zampini 37289162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 37299162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 37309162d606SStefano Zampini } 37319162d606SStefano Zampini total_counts += constraints_n[i]; 3732674ae819SStefano Zampini } 3733674ae819SStefano Zampini } 3734674ae819SStefano Zampini /* assembling */ 3735674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3736674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3737088faed8SStefano Zampini 3738984c4197SStefano Zampini /* 373945a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3740984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 3741984c4197SStefano Zampini */ 3742674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 3743674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 3744026de310SStefano Zampini /* dual and primal dofs on a single cc */ 3745984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 3746984c4197SStefano Zampini /* working stuff for GEQRF */ 374781d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 3748984c4197SStefano Zampini PetscBLASInt lqr_work; 3749984c4197SStefano Zampini /* working stuff for UNGQR */ 3750984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 3751984c4197SStefano Zampini PetscBLASInt lgqr_work; 3752984c4197SStefano Zampini /* working stuff for TRTRS */ 3753984c4197SStefano Zampini PetscScalar *trs_rhs; 37543f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 3755984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 3756984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 3757984c4197SStefano Zampini PetscScalar *start_vals; 3758984c4197SStefano Zampini /* working stuff for values insertion */ 37594641a718SStefano Zampini PetscBT is_primal; 376064efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 3761906d46d4SStefano Zampini /* matrix sizes */ 3762906d46d4SStefano Zampini PetscInt global_size,local_size; 3763906d46d4SStefano Zampini /* temporary change of basis */ 3764906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 3765cf5a6209SStefano Zampini /* extra space for debugging */ 3766cf5a6209SStefano Zampini PetscScalar *dbg_work; 3767984c4197SStefano Zampini 3768906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 3769906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 377016f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 3771bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 3772906d46d4SStefano Zampini /* nonzeros for local mat */ 3773bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 3774bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 37759162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 3776a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 37779162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3778a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 37799162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 3780a717540cSStefano Zampini } else { 37819162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 37829162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 3783a717540cSStefano Zampini } 3784a717540cSStefano Zampini } 3785a717540cSStefano Zampini } 3786906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 3787bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3788a717540cSStefano Zampini /* Set initial identity in the matrix */ 3789bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 3790906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 3791a717540cSStefano Zampini } 3792a717540cSStefano Zampini 3793a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3794a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3795a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3796a717540cSStefano Zampini } 3797a717540cSStefano Zampini 3798a717540cSStefano Zampini 3799a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 3800a717540cSStefano Zampini /* 3801a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 3802a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 3803a717540cSStefano Zampini 3804a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 3805a717540cSStefano Zampini 3806a6b551f4SStefano 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) 3807a6b551f4SStefano Zampini 3808a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 3809a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 3810a717540cSStefano Zampini | ... | 3811a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 3812a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 3813a717540cSStefano Zampini 3814a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 3815a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 3816a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 3817a6b551f4SStefano Zampini 3818a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 3819a717540cSStefano Zampini */ 3820a717540cSStefano Zampini if (qr_needed) { 3821984c4197SStefano Zampini /* space to store Q */ 3822854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 3823984c4197SStefano Zampini /* first we issue queries for optimal work */ 38243f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 38253f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 38263f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3827984c4197SStefano Zampini lqr_work = -1; 38283f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 3829984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 3830984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 3831785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 3832984c4197SStefano Zampini lgqr_work = -1; 38333f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 38343f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 38353f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 38363f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 38373f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 38383f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 3839984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 3840984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 3841785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 3842984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 3843785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 3844984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 3845785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 3846a717540cSStefano Zampini /* allocating workspace for check */ 3847a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3848cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 3849a717540cSStefano Zampini } 3850a717540cSStefano Zampini } 3851984c4197SStefano Zampini /* array to store whether a node is primal or not */ 38524641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 3853473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 38540e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 385539e2fb2aSStefano Zampini if (i != total_primal_vertices) { 385639e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 38574641a718SStefano Zampini } 385839e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 385939e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 386039e2fb2aSStefano Zampini } 386139e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 3862984c4197SStefano Zampini 3863a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 38649162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 38659162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 38664641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 3867984c4197SStefano Zampini /* get constraint info */ 38689162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 3869984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 3870984c4197SStefano Zampini 3871984c4197SStefano Zampini if (pcbddc->dbg_flag) { 38729162d606SStefano 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); 3873674ae819SStefano Zampini } 3874984c4197SStefano Zampini 3875fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 3876a717540cSStefano Zampini 3877a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 3878a717540cSStefano Zampini if (pcbddc->dbg_flag) { 38799162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3880a717540cSStefano Zampini } 3881984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 38829162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3883984c4197SStefano Zampini 3884984c4197SStefano Zampini /* compute QR decomposition of constraints */ 38853f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 38863f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 38873f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3888674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 38893f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 3890984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 3891674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3892984c4197SStefano Zampini 3893984c4197SStefano Zampini /* explictly compute R^-T */ 3894984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 3895984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 38963f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 38973f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 38983f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 38993f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 3900984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 39013f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 3902984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 3903984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3904984c4197SStefano Zampini 3905a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 39063f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 39073f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 39083f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 39093f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3910984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 39113f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 3912984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 3913984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3914984c4197SStefano Zampini 3915984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 3916984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 3917984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 39183f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 39193f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 39203f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 39213f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 39223f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 39233f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3924984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 39259162d606SStefano 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)); 3926984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 39279162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3928984c4197SStefano Zampini 3929984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 39309162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 3931984c4197SStefano Zampini /* insert cols for primal dofs */ 3932984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 3933984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 39349162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3935906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3936984c4197SStefano Zampini } 3937984c4197SStefano Zampini /* insert cols for dual dofs */ 3938984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 39399162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 3940984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 39419162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3942906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3943984c4197SStefano Zampini j++; 3944674ae819SStefano Zampini } 3945674ae819SStefano Zampini } 3946984c4197SStefano Zampini 3947984c4197SStefano Zampini /* check change of basis */ 3948984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3949984c4197SStefano Zampini PetscInt ii,jj; 3950984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 3951c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 3952c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3953c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 3954c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3955c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 3956c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 3957984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3958cf5a6209SStefano 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)); 3959984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3960984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3961984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3962cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 3963cf5a6209SStefano 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; 3964674ae819SStefano Zampini } 3965674ae819SStefano Zampini } 3966984c4197SStefano Zampini if (!valid_qr) { 396722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 3968984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3969984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3970cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 3971cf5a6209SStefano 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])); 3972674ae819SStefano Zampini } 3973cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 3974cf5a6209SStefano 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])); 3975984c4197SStefano Zampini } 3976984c4197SStefano Zampini } 3977984c4197SStefano Zampini } 3978674ae819SStefano Zampini } else { 397922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 3980674ae819SStefano Zampini } 3981674ae819SStefano Zampini } 3982a717540cSStefano Zampini } else { /* simple transformation block */ 3983a717540cSStefano Zampini PetscInt row,col; 3984a6b551f4SStefano Zampini PetscScalar val,norm; 3985a6b551f4SStefano Zampini 3986a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 39879162d606SStefano 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)); 3988a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 39899162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 39909162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3991bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 39929162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 3993906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 39949162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 3995a717540cSStefano Zampini } else { 3996a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 39979162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3998a717540cSStefano Zampini if (row != col) { 39999162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 4000a717540cSStefano Zampini } else { 40019162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 4002a717540cSStefano Zampini } 4003906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 4004a717540cSStefano Zampini } 4005a717540cSStefano Zampini } 4006a717540cSStefano Zampini } 400798a51de6SStefano Zampini if (pcbddc->dbg_flag) { 400822d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 4009a717540cSStefano Zampini } 4010674ae819SStefano Zampini } 4011984c4197SStefano Zampini } else { 4012984c4197SStefano Zampini if (pcbddc->dbg_flag) { 40139162d606SStefano 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); 4014674ae819SStefano Zampini } 4015674ae819SStefano Zampini } 4016674ae819SStefano Zampini } 4017a717540cSStefano Zampini 4018a717540cSStefano Zampini /* free workspace */ 4019a717540cSStefano Zampini if (qr_needed) { 4020984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4021cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 4022984c4197SStefano Zampini } 4023984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 4024984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 4025984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 4026984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 4027984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 4028674ae819SStefano Zampini } 4029a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 4030906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4031906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4032906d46d4SStefano Zampini 4033906d46d4SStefano Zampini /* assembling of global change of variable */ 4034bbb9e6c6SStefano Zampini { 4035bbb9e6c6SStefano Zampini Mat tmat; 403616f15bc4SStefano Zampini PetscInt bs; 403716f15bc4SStefano Zampini 4038906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 4039906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 4040bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 4041bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 4042bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4043bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 404416f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 404516f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 4046906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 4047bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 4048bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4049bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4050bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4051bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 4052e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4053e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4054bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 4055bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 4056906d46d4SStefano Zampini } 4057906d46d4SStefano Zampini /* check */ 4058906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4059906d46d4SStefano Zampini PetscReal error; 4060906d46d4SStefano Zampini Vec x,x_change; 4061906d46d4SStefano Zampini 4062906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 4063906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 4064906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 4065906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 4066e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4067e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4068bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 4069e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4070e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4071906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 4072906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4073906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4074906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4075bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 4076906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4077906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4078906d46d4SStefano Zampini } 4079b96c3477SStefano Zampini 4080b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 4081b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 4082b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4083b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 4084ac632422SStefano Zampini Mat S_new,tmat; 4085b087196eSStefano Zampini ISLocalToGlobalMapping NtoSall; 4086b087196eSStefano Zampini IS is_all_N,is_V,is_V_Sall; 4087b087196eSStefano Zampini const PetscScalar *array; 4088b087196eSStefano Zampini const PetscInt *idxs_V,*idxs_all; 4089b087196eSStefano Zampini PetscInt i,n_V; 4090bbb9e6c6SStefano Zampini 4091bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 40926816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 4093b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 4094b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 4095b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 4096b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 4097bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 4098b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 4099ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4100b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 4101ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4102b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4103b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 4104b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4105b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4106b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 4107b087196eSStefano Zampini for (i=0;i<n_V;i++) { 4108b087196eSStefano Zampini PetscScalar val; 4109b087196eSStefano Zampini PetscInt idx; 4110b087196eSStefano Zampini 4111b087196eSStefano Zampini idx = idxs_V[i]; 4112b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 4113b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 4114b087196eSStefano Zampini } 4115b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4116b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4117ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 4118ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4119ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 4120ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4121b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 4122ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4123b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4124ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 4125ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4126ac632422SStefano Zampini } 4127b087196eSStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 4128b087196eSStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4129b087196eSStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4130b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4131b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 4132b96c3477SStefano Zampini } 4133b96c3477SStefano Zampini } 4134906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 4135906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 4136b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4137b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 4138b9b85e73SStefano Zampini } 4139906d46d4SStefano Zampini 4140906d46d4SStefano Zampini /* set up change of basis context */ 4141906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 4142906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4143906d46d4SStefano Zampini 4144906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 4145906d46d4SStefano Zampini PetscInt global_size,local_size; 4146906d46d4SStefano Zampini 4147906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 4148906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 4149906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 4150906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 4151906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 4152906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 4153906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 4154906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 4155906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 4156906d46d4SStefano Zampini } else { 4157906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 4158906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 4159906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 4160906d46d4SStefano Zampini } 4161906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 4162906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4163906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 4164906d46d4SStefano Zampini } else { 4165906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4166906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 4167906d46d4SStefano Zampini } 4168906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 4169906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 4170906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4171906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4172a8661815SStefano Zampini } else { 4173a8661815SStefano Zampini ierr = MatDestroy(&pcbddc->new_global_mat);CHKERRQ(ierr); 4174b9b85e73SStefano Zampini } 4175a717540cSStefano Zampini 41764f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 41774f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 41784f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 41794f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 4180019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 4181019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 4182019a44ceSStefano Zampini pcbddc->local_primal_size++; 4183019a44ceSStefano Zampini } 4184019a44ceSStefano Zampini 4185019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 4186727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 4187727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 41889f47a83aSStefano 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); 4189c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 41900e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 41919f47a83aSStefano 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); 4192727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 4193727cdba6SStefano Zampini } 41940e6343abSStefano Zampini } 41950e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 4196727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 4197727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4198727cdba6SStefano Zampini 4199a717540cSStefano Zampini /* flush dbg viewer */ 4200b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 4201b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4202b8ffe317SStefano Zampini } 4203a717540cSStefano Zampini 4204e310c8b4SStefano Zampini /* free workspace */ 4205a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 42064641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 420708122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 42089162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 42099162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 421008122e43SStefano Zampini } else { 42119162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 42129162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 42139162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 421408122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 421508122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 42169162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 42179162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 421808122e43SStefano Zampini } 4219674ae819SStefano Zampini PetscFunctionReturn(0); 4220674ae819SStefano Zampini } 4221674ae819SStefano Zampini 4222674ae819SStefano Zampini #undef __FUNCT__ 4223674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 4224674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 4225674ae819SStefano Zampini { 4226674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4227674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4228674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 42297fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 4230674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 4231674ae819SStefano Zampini 4232674ae819SStefano Zampini PetscFunctionBegin; 42338e61c736SStefano Zampini /* Reset previously computed graph */ 42348e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 4235674ae819SStefano Zampini /* Init local Graph struct */ 42367fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 42373bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 4238674ae819SStefano Zampini 4239575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 42405099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 42415099eff2SStefano Zampini 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); 4242575ad6abSStefano Zampini } 42439577ea80SStefano Zampini 4244674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 4245d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 42464d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 42474d379d7bSStefano Zampini PetscInt nvtxs; 4248e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 4249674ae819SStefano Zampini 42502fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 42512fffb893SStefano Zampini if (flg_row) { 42524d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 4253b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 42542fffb893SStefano Zampini } 42552fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4256674ae819SStefano Zampini } 42579b28b941SStefano Zampini if (pcbddc->dbg_flag) { 42589b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4259674ae819SStefano Zampini } 4260674ae819SStefano Zampini 426163602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 4262674ae819SStefano Zampini vertex_size = 1; 426363602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 426463602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 426595ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 426663602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 4267e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 426863602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 4269674ae819SStefano Zampini } 427063602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 427163602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 427263602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 4273674ae819SStefano Zampini } 427463602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 4275674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 427663602bcaSStefano Zampini } else { 427763602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 427863602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 4279854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 428063602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 428163602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 428263602bcaSStefano Zampini } 428363602bcaSStefano Zampini } 4284674ae819SStefano Zampini } 4285674ae819SStefano Zampini 4286674ae819SStefano Zampini /* Setup of Graph */ 4287785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 4288e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 4289785d1243SStefano Zampini } 4290785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 4291e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 4292785d1243SStefano Zampini } 429330368db7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { /* need to convert from global to local */ 429430368db7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 429530368db7SStefano Zampini } 429630368db7SStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 4297674ae819SStefano Zampini 42984f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 42994f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 43004f1b2e48SStefano Zampini PetscInt *local_subs; 43014f1b2e48SStefano Zampini 43024f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 43034f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 43044f1b2e48SStefano Zampini const PetscInt *idxs; 43054f1b2e48SStefano Zampini PetscInt nl,j; 43064f1b2e48SStefano Zampini 43074f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 43084f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 43094f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 43104f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 43114f1b2e48SStefano Zampini } 43124f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 43134f1b2e48SStefano Zampini } 43144f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 43154f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 43164f1b2e48SStefano Zampini } 43174f1b2e48SStefano Zampini 4318674ae819SStefano Zampini /* Graph's connected components analysis */ 4319674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 4320674ae819SStefano Zampini 4321674ae819SStefano Zampini /* print some info to stdout */ 4322674ae819SStefano Zampini if (pcbddc->dbg_flag) { 4323302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 4324674ae819SStefano Zampini } 4325fb180af4SStefano Zampini 4326fb180af4SStefano Zampini /* mark topography has done */ 4327fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 4328674ae819SStefano Zampini PetscFunctionReturn(0); 4329674ae819SStefano Zampini } 4330674ae819SStefano Zampini 4331dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 4332674ae819SStefano Zampini #undef __FUNCT__ 4333674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 4334dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 4335674ae819SStefano Zampini { 4336dc456d91SStefano Zampini PetscSF sf; 4337dc456d91SStefano Zampini PetscLayout map; 4338dc456d91SStefano Zampini const PetscInt *idxs; 4339dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 4340dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 4341dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 4342dc456d91SStefano Zampini PetscMPIInt commsize; 4343674ae819SStefano Zampini PetscBool first_found; 4344674ae819SStefano Zampini PetscErrorCode ierr; 4345674ae819SStefano Zampini 4346674ae819SStefano Zampini PetscFunctionBegin; 4347dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 4348dc456d91SStefano Zampini if (subset_mult) { 4349dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 4350dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 4351dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 4352674ae819SStefano Zampini } 4353dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 4354dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 4355dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 4356dc456d91SStefano Zampini for (i=0;i<n;i++) { 4357dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 4358dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 4359674ae819SStefano Zampini } 4360dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 4361dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4362dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 4363dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 4364dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 4365dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 4366dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 4367dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 4368dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 4369dc456d91SStefano Zampini 4370dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 4371dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 4372dc456d91SStefano Zampini if (subset_mult) { 4373dc456d91SStefano Zampini const PetscInt* idxs_mult; 4374dc456d91SStefano Zampini 4375dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4376dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 4377dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4378674ae819SStefano Zampini } else { 4379dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 4380674ae819SStefano Zampini } 4381dc456d91SStefano Zampini /* local size of new subset */ 4382dc456d91SStefano Zampini n_n = 0; 4383dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 4384dc456d91SStefano Zampini 4385dc456d91SStefano Zampini /* global indexes in layout */ 4386dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 4387dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 4388dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 4389dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4390dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4391dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4392dc456d91SStefano Zampini 4393dc456d91SStefano Zampini /* reduce from leaves to roots */ 4394dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 439564a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 439664a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4397dc456d91SStefano Zampini 4398dc456d91SStefano Zampini /* count indexes in local part of layout */ 4399674ae819SStefano Zampini nlocals = 0; 4400674ae819SStefano Zampini first_index = -1; 4401674ae819SStefano Zampini first_found = PETSC_FALSE; 4402dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4403dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4404674ae819SStefano Zampini first_found = PETSC_TRUE; 4405674ae819SStefano Zampini first_index = i; 4406674ae819SStefano Zampini } 4407dc456d91SStefano Zampini nlocals += root_data[i]; 4408674ae819SStefano Zampini } 4409dc456d91SStefano Zampini 4410dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 44115fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4412dc456d91SStefano Zampini start = 0; 441364a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 44145fa240b1SStefano Zampini #else 441564a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 44165fa240b1SStefano Zampini start = start-nlocals; 44175fa240b1SStefano Zampini #endif 44185fa240b1SStefano Zampini 4419dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4420dc456d91SStefano Zampini *N_n = start + nlocals; 4421dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4422dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4423674ae819SStefano Zampini } 44245fa240b1SStefano Zampini 44255fa240b1SStefano Zampini /* adapt root data with cumulative */ 4426674ae819SStefano Zampini if (first_found) { 4427dc456d91SStefano Zampini PetscInt old_index; 4428dc456d91SStefano Zampini 4429dc456d91SStefano Zampini root_data[first_index] += start; 4430674ae819SStefano Zampini old_index = first_index; 4431dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4432dc456d91SStefano Zampini if (root_data[i]) { 4433dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4434674ae819SStefano Zampini old_index = i; 4435674ae819SStefano Zampini } 4436674ae819SStefano Zampini } 4437674ae819SStefano Zampini } 4438dc456d91SStefano Zampini 4439dc456d91SStefano Zampini /* from roots to leaves */ 4440dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4441dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4442dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4443dc456d91SStefano Zampini 4444dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4445dc456d91SStefano Zampini if (subset_mult) { 4446dc456d91SStefano Zampini const PetscInt* idxs_mult; 4447dc456d91SStefano Zampini PetscInt cum; 4448dc456d91SStefano Zampini 4449dc456d91SStefano Zampini cum = 0; 4450dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4451dc456d91SStefano Zampini for (i=0;i<n;i++) { 4452dc456d91SStefano Zampini PetscInt j; 4453dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4454674ae819SStefano Zampini } 4455dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4456674ae819SStefano Zampini } else { 4457dc456d91SStefano Zampini for (i=0;i<n;i++) { 4458dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4459674ae819SStefano Zampini } 4460674ae819SStefano Zampini } 4461dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4462dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4463674ae819SStefano Zampini PetscFunctionReturn(0); 4464674ae819SStefano Zampini } 44659a7d3425SStefano Zampini 44669a7d3425SStefano Zampini #undef __FUNCT__ 44679a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 44689a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 44699a7d3425SStefano Zampini { 44709a7d3425SStefano Zampini PetscInt i,j; 44719a7d3425SStefano Zampini PetscScalar *alphas; 44729a7d3425SStefano Zampini PetscErrorCode ierr; 44739a7d3425SStefano Zampini 44749a7d3425SStefano Zampini PetscFunctionBegin; 44759a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 4476785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 44779a7d3425SStefano Zampini for (i=0;i<n;i++) { 44789a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 44799a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 44809a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 44819a7d3425SStefano Zampini } 44829a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 44839a7d3425SStefano Zampini PetscFunctionReturn(0); 44849a7d3425SStefano Zampini } 44859a7d3425SStefano Zampini 4486e7931f94SStefano Zampini #undef __FUNCT__ 448770cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 4488b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 4489e7931f94SStefano Zampini { 449052e5ac9dSStefano Zampini IS ranks_send_to; 4491e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 4492e7931f94SStefano Zampini PetscMPIInt size,rank,color; 449352e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 449452e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 44953837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 44962b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 4497e7931f94SStefano Zampini PetscSubcomm subcomm; 449852e5ac9dSStefano Zampini PetscErrorCode ierr; 4499a57a6d2fSStefano Zampini 4500e7931f94SStefano Zampini PetscFunctionBegin; 45012b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 45022b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 45032b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 4504e7931f94SStefano Zampini 4505e7931f94SStefano Zampini /* Get info on mapping */ 45063bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 45073bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4508e7931f94SStefano Zampini 4509e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 4510785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 4511e7931f94SStefano Zampini xadj[0] = 0; 4512e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 4513785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 4514785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 4515e7931f94SStefano Zampini 45162b510759SStefano Zampini if (threshold) { 4517d023bfaeSStefano Zampini PetscInt xadj_count = 0; 45182b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 4519d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 4520d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 4521d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 4522d023bfaeSStefano Zampini xadj_count++; 4523e7931f94SStefano Zampini } 4524e7931f94SStefano Zampini } 4525d023bfaeSStefano Zampini xadj[1] = xadj_count; 4526c8587f34SStefano Zampini } else { 4527e7931f94SStefano Zampini if (xadj[1]) { 4528e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 4529e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 4530c8587f34SStefano Zampini } 4531e7931f94SStefano Zampini } 45323bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4533e7931f94SStefano Zampini if (use_square) { 4534e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4535e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 4536e7931f94SStefano Zampini } 4537e7931f94SStefano Zampini } 4538e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4539e7931f94SStefano Zampini 45403837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 4541e7931f94SStefano Zampini 4542e7931f94SStefano Zampini /* 4543e7931f94SStefano Zampini Restrict work on active processes only. 4544e7931f94SStefano Zampini */ 4545e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 4546e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 4547e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 45482b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 4549d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4550e7931f94SStefano Zampini if (color) { 4551e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 4552e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 4553e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4554c8587f34SStefano Zampini } else { 455552e5ac9dSStefano Zampini Mat subdomain_adj; 455652e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 455752e5ac9dSStefano Zampini MatPartitioning partitioner; 455852e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 455952e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 4560b0c7d250SStefano Zampini PetscBool aggregate; 4561b0c7d250SStefano Zampini 4562306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 4563785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 4564e7931f94SStefano Zampini prank = rank; 4565306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 45668002ef2cSStefano Zampini /* 4567e7931f94SStefano Zampini for (i=0;i<size;i++) { 4568e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 4569c8587f34SStefano Zampini } 45708002ef2cSStefano Zampini */ 4571e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4572e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 4573c8587f34SStefano Zampini } 4574e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4575b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 4576b0c7d250SStefano Zampini if (aggregate) { 4577b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 4578b0c7d250SStefano Zampini PetscMPIInt nrank; 4579b0c7d250SStefano Zampini PetscScalar *vals; 4580b0c7d250SStefano Zampini 4581b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 4582b0c7d250SStefano Zampini lrows = 0; 4583b0c7d250SStefano Zampini if (nrank<redprocs) { 4584b0c7d250SStefano Zampini lrows = size/redprocs; 4585b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 4586b0c7d250SStefano Zampini } 45875fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 4588b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 4589b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4590b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4591b0c7d250SStefano Zampini row = nrank; 4592b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 4593b0c7d250SStefano Zampini cols = adjncy; 4594b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 4595b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 4596b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 4597b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4598b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 459952e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 460052e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 460152e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4602b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4603b0c7d250SStefano Zampini } else { 4604306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 4605b0c7d250SStefano Zampini } 460622b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 4607e7931f94SStefano Zampini 4608e7931f94SStefano Zampini /* Partition */ 4609306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 4610e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 4611e7931f94SStefano Zampini if (use_vwgt) { 46123837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 4613e7931f94SStefano Zampini v_wgt[0] = local_size; 4614e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 4615c8587f34SStefano Zampini } 461628143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 461728143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 4618e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 4619e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 462022b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 4621e7931f94SStefano Zampini 462252e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 462352e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 462452e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 462552e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4626b0c7d250SStefano Zampini if (!redprocs) { 4627b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 462828143c3dSStefano Zampini } else { 4629b0c7d250SStefano Zampini PetscInt idxs[1]; 4630b0c7d250SStefano Zampini PetscMPIInt tag; 4631b0c7d250SStefano Zampini MPI_Request *reqs; 4632b0c7d250SStefano Zampini 4633b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 4634b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 4635b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 4636b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 463728143c3dSStefano Zampini } 4638b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 4639b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4640b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 4641b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 4642e7931f94SStefano Zampini } 464352e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4644e7931f94SStefano Zampini /* clean up */ 4645e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 464652e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 4647e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 4648e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 4649e7931f94SStefano Zampini } 4650e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 4651e7931f94SStefano Zampini 4652e7931f94SStefano Zampini /* assemble parallel IS for sends */ 4653e7931f94SStefano Zampini i = 1; 4654e7931f94SStefano Zampini if (color) i=0; 4655e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 4656e7931f94SStefano Zampini /* get back IS */ 4657e7931f94SStefano Zampini *is_sends = ranks_send_to; 4658e7931f94SStefano Zampini PetscFunctionReturn(0); 4659e7931f94SStefano Zampini } 4660e7931f94SStefano Zampini 4661e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 4662e7931f94SStefano Zampini 4663e7931f94SStefano Zampini #undef __FUNCT__ 4664e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 466553a05cb3SStefano Zampini PetscErrorCode MatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, PetscBool restrict_full, MatReuse reuse, Mat *mat_n, PetscInt nis, IS isarray[]) 4666e7931f94SStefano Zampini { 466770cf5478SStefano Zampini Mat local_mat; 4668e7931f94SStefano Zampini IS is_sends_internal; 46699d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 467028143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 46719d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 4672e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 4673e7931f94SStefano Zampini PetscInt* l2gmap_indices; 4674e7931f94SStefano Zampini const PetscInt* is_indices; 4675e7931f94SStefano Zampini MatType new_local_type; 4676e7931f94SStefano Zampini /* buffers */ 4677e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 467828143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 46799d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 4680e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 4681e7931f94SStefano Zampini /* MPI */ 468228143c3dSStefano Zampini MPI_Comm comm,comm_n; 468328143c3dSStefano Zampini PetscSubcomm subcomm; 4684e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 468528143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 468628143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 468728143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 468828143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 468928143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 4690e7931f94SStefano Zampini PetscErrorCode ierr; 4691e7931f94SStefano Zampini 4692e7931f94SStefano Zampini PetscFunctionBegin; 469328143c3dSStefano Zampini /* TODO: add missing checks */ 469428143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 469528143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 469628143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 469728143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 4698e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 469928143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 4700e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4701e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 4702e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 4703e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 4704e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 470528143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 470670cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 470770cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 470828143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 470970cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 471070cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 471170cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 471270cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 471370cf5478SStefano Zampini } 4714e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 4715e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 4716e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 4717e7931f94SStefano Zampini if (!is_sends) { 471828143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 4719b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 4720c8587f34SStefano Zampini } else { 4721e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 4722e7931f94SStefano Zampini is_sends_internal = is_sends; 4723c8587f34SStefano Zampini } 4724e7931f94SStefano Zampini 4725e7931f94SStefano Zampini /* get comm */ 4726a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 4727e7931f94SStefano Zampini 4728e7931f94SStefano Zampini /* compute number of sends */ 4729e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 4730e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 4731e7931f94SStefano Zampini 4732e7931f94SStefano Zampini /* compute number of receives */ 4733e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 4734785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 4735e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 4736e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4737e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 4738e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 4739e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 4740e7931f94SStefano Zampini 474128143c3dSStefano Zampini /* restrict comm if requested */ 474228143c3dSStefano Zampini subcomm = 0; 474328143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 474428143c3dSStefano Zampini if (restrict_comm) { 4745779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 4746779c1cceSStefano Zampini 474728143c3dSStefano Zampini color = 0; 474853a05cb3SStefano Zampini if (restrict_full) { 474953a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 475053a05cb3SStefano Zampini } else { 475153a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 475253a05cb3SStefano Zampini } 475328143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 475428143c3dSStefano Zampini subcommsize = commsize - subcommsize; 475528143c3dSStefano Zampini /* check if reuse has been requested */ 475628143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 475728143c3dSStefano Zampini if (*mat_n) { 475828143c3dSStefano Zampini PetscMPIInt subcommsize2; 475928143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 476028143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 476128143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 476228143c3dSStefano Zampini } else { 476328143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 476428143c3dSStefano Zampini } 476528143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 4766779c1cceSStefano Zampini PetscMPIInt rank; 4767779c1cceSStefano Zampini 4768779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 476928143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 477028143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 477128143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4772306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 477328143c3dSStefano Zampini } 477428143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 477528143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 477628143c3dSStefano Zampini } else { 477728143c3dSStefano Zampini comm_n = comm; 477828143c3dSStefano Zampini } 477928143c3dSStefano Zampini 4780e7931f94SStefano Zampini /* prepare send/receive buffers */ 4781785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 4782e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 4783785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 4784e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 478528143c3dSStefano Zampini if (nis) { 4786854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 478728143c3dSStefano Zampini } 4788e7931f94SStefano Zampini 478928143c3dSStefano Zampini /* Get data from local matrices */ 4790e7931f94SStefano Zampini if (!isdense) { 4791a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 4792e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 4793e7931f94SStefano Zampini /* 4794e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 4795e7931f94SStefano Zampini send_buffer_idxs should contain: 4796e7931f94SStefano Zampini - MatType_PRIVATE type 4797e7931f94SStefano Zampini - PetscInt size_of_l2gmap 4798e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 4799e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 4800e7931f94SStefano Zampini */ 4801e7931f94SStefano Zampini } else { 4802e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 48033bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 4804854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 4805e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 4806e7931f94SStefano Zampini send_buffer_idxs[1] = i; 48073bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4808e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 48093bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4810e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 4811e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4812e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 4813e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 4814c8587f34SStefano Zampini } 4815c8587f34SStefano Zampini } 4816e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 481728143c3dSStefano Zampini /* additional is (if any) */ 481828143c3dSStefano Zampini if (nis) { 481928143c3dSStefano Zampini PetscMPIInt psum; 482028143c3dSStefano Zampini PetscInt j; 482128143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 482228143c3dSStefano Zampini PetscInt plen; 482328143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 482428143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 482528143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 482628143c3dSStefano Zampini } 4827854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 482828143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 482928143c3dSStefano Zampini PetscInt plen; 483028143c3dSStefano Zampini const PetscInt *is_array_idxs; 483128143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 483228143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 483328143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 483428143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 483528143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 483628143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 483728143c3dSStefano Zampini } 483828143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 483928143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 484028143c3dSStefano Zampini } 484128143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 484228143c3dSStefano Zampini } 484328143c3dSStefano Zampini 4844e7931f94SStefano Zampini buf_size_idxs = 0; 4845e7931f94SStefano Zampini buf_size_vals = 0; 484628143c3dSStefano Zampini buf_size_idxs_is = 0; 4847e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4848e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 4849e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 485028143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 4851e7931f94SStefano Zampini } 4852785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 4853785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 485495ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 4855e7931f94SStefano Zampini 4856e7931f94SStefano Zampini /* get new tags for clean communications */ 4857e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 4858e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 485928143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 4860e7931f94SStefano Zampini 4861e7931f94SStefano Zampini /* allocate for requests */ 4862785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 4863785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 486495ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 4865785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 4866785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 486795ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 4868e7931f94SStefano Zampini 4869e7931f94SStefano Zampini /* communications */ 4870e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4871e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 487228143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 4873e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4874e7931f94SStefano Zampini source_dest = onodes[i]; 4875e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 4876e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 4877e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4878e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 487928143c3dSStefano Zampini if (nis) { 488028143c3dSStefano 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); 488128143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 488228143c3dSStefano Zampini } 4883e7931f94SStefano Zampini } 4884e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4885e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 4886e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 4887e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 488828143c3dSStefano Zampini if (nis) { 488928143c3dSStefano 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); 489028143c3dSStefano Zampini } 4891e7931f94SStefano Zampini } 4892e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4893e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 4894e7931f94SStefano Zampini 4895e7931f94SStefano Zampini /* assemble new l2g map */ 4896e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4897e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 48989d30be91SStefano Zampini new_local_rows = 0; 4899e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 49009d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4901e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4902e7931f94SStefano Zampini } 49039d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 4904e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 49059d30be91SStefano Zampini new_local_rows = 0; 4906e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 49079d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 49089d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4909e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4910e7931f94SStefano Zampini } 49119d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 49129d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 4913e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 4914e7931f94SStefano Zampini 4915e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 4916e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 4917e7931f94SStefano 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) */ 4918e7931f94SStefano Zampini if (n_recvs) { 491928143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 4920e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4921e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4922e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 4923e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 4924e7931f94SStefano Zampini break; 4925e7931f94SStefano Zampini } 4926e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4927e7931f94SStefano Zampini } 4928e7931f94SStefano Zampini switch (new_local_type_private) { 492928143c3dSStefano Zampini case MATDENSE_PRIVATE: 493028143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 4931e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4932e7931f94SStefano Zampini bs = 1; 493328143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 493428143c3dSStefano Zampini new_local_type = MATSEQDENSE; 493528143c3dSStefano Zampini bs = 1; 493628143c3dSStefano Zampini } 4937e7931f94SStefano Zampini break; 4938e7931f94SStefano Zampini case MATAIJ_PRIVATE: 4939e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4940e7931f94SStefano Zampini bs = 1; 4941e7931f94SStefano Zampini break; 4942e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 4943e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 4944e7931f94SStefano Zampini break; 4945e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 4946e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 4947e7931f94SStefano Zampini break; 4948e7931f94SStefano Zampini default: 49499d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 4950e7931f94SStefano Zampini break; 4951e7931f94SStefano Zampini } 495228143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 495328143c3dSStefano Zampini new_local_type = MATSEQDENSE; 495428143c3dSStefano Zampini bs = 1; 4955e7931f94SStefano Zampini } 4956e7931f94SStefano Zampini 495770cf5478SStefano Zampini /* create MATIS object if needed */ 495870cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 4959e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 4960e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 496170cf5478SStefano Zampini } else { 496270cf5478SStefano Zampini /* it also destroys the local matrices */ 496370cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 496470cf5478SStefano Zampini } 496570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 4966e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 49679d30be91SStefano Zampini 49689d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 49699d30be91SStefano Zampini 49709d30be91SStefano Zampini /* Global to local map of received indices */ 49719d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 49729d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 49739d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 49749d30be91SStefano Zampini 49759d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 49769d30be91SStefano Zampini buf_size_idxs = 0; 49779d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 49789d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 49799d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 49809d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 49819d30be91SStefano Zampini } 49829d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 49839d30be91SStefano Zampini 49849d30be91SStefano Zampini /* set preallocation */ 49859d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 49869d30be91SStefano Zampini if (!newisdense) { 49879d30be91SStefano Zampini PetscInt *new_local_nnz=0; 49889d30be91SStefano Zampini 49899d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 49909d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 49919d30be91SStefano Zampini if (n_recvs) { 49929d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 49939d30be91SStefano Zampini } 49949d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 49959d30be91SStefano Zampini PetscInt j; 49969d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 49979d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 49989d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 49999d30be91SStefano Zampini } 50009d30be91SStefano Zampini } else { 50019d30be91SStefano Zampini /* TODO */ 50029d30be91SStefano Zampini } 50039d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 50049d30be91SStefano Zampini } 50059d30be91SStefano Zampini if (new_local_nnz) { 50069d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 50079d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 50089d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 50099d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 50109d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 50119d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 50129d30be91SStefano Zampini } else { 50139d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 50149d30be91SStefano Zampini } 50159d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 50169d30be91SStefano Zampini } else { 50179d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 50189d30be91SStefano Zampini } 5019e7931f94SStefano Zampini 5020e7931f94SStefano Zampini /* set values */ 5021e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 50229d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 5023e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5024e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 5025e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 50269d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 5027e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5028e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5029e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 503028143c3dSStefano Zampini } else { 503128143c3dSStefano Zampini /* TODO */ 5032e7931f94SStefano Zampini } 5033e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5034e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 5035e7931f94SStefano Zampini } 5036e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5037e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 503870cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 503970cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 50409d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 50419d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 5042e7931f94SStefano Zampini 5043dfd14d43SStefano Zampini #if 0 504428143c3dSStefano Zampini if (!restrict_comm) { /* check */ 5045e7931f94SStefano Zampini Vec lvec,rvec; 5046e7931f94SStefano Zampini PetscReal infty_error; 5047e7931f94SStefano Zampini 50482a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 5049e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 5050e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 5051e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 505270cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 5053e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 5054e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 5055e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 5056e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 5057e7931f94SStefano Zampini } 505828143c3dSStefano Zampini #endif 5059e7931f94SStefano Zampini 506028143c3dSStefano Zampini /* assemble new additional is (if any) */ 506128143c3dSStefano Zampini if (nis) { 506228143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 506328143c3dSStefano Zampini 506428143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5065854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 506628143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 506728143c3dSStefano Zampini psum = 0; 506828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 506928143c3dSStefano Zampini for (j=0;j<nis;j++) { 507028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 507128143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 507228143c3dSStefano Zampini psum += plen; 507328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 507428143c3dSStefano Zampini } 507528143c3dSStefano Zampini } 5076854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 5077854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 507828143c3dSStefano Zampini for (i=1;i<nis;i++) { 507928143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 508028143c3dSStefano Zampini } 508128143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 508228143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 508328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 508428143c3dSStefano Zampini for (j=0;j<nis;j++) { 508528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 508628143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 508728143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 508828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 508928143c3dSStefano Zampini } 509028143c3dSStefano Zampini } 509128143c3dSStefano Zampini for (i=0;i<nis;i++) { 509228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 509328143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 509428143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 509528143c3dSStefano Zampini } 509628143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 509728143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 509828143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 509928143c3dSStefano Zampini } 5100e7931f94SStefano Zampini /* free workspace */ 510128143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 5102e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5103e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 5104e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5105e7931f94SStefano Zampini if (isdense) { 5106e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5107e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 5108e7931f94SStefano Zampini } else { 5109e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 5110e7931f94SStefano Zampini } 511128143c3dSStefano Zampini if (nis) { 511228143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 511328143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 511428143c3dSStefano Zampini } 5115e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 5116e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 511728143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 5118e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 5119e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 512028143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 5121e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 5122e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 5123e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 5124e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 5125e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 512628143c3dSStefano Zampini if (nis) { 512728143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 512828143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 512928143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 513028143c3dSStefano Zampini } 513128143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 513228143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 513328143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 513428143c3dSStefano Zampini for (i=0;i<nis;i++) { 513528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 513628143c3dSStefano Zampini } 513753a05cb3SStefano Zampini *mat_n = NULL; 513828143c3dSStefano Zampini } 5139e7931f94SStefano Zampini PetscFunctionReturn(0); 5140e7931f94SStefano Zampini } 5141a57a6d2fSStefano Zampini 514212edc857SStefano Zampini /* temporary hack into ksp private data structure */ 5143af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 514412edc857SStefano Zampini 5145c8587f34SStefano Zampini #undef __FUNCT__ 5146c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 5147c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 5148c8587f34SStefano Zampini { 5149c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5150c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 515120a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 51529881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 515320a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 51546e683305SStefano Zampini IS coarse_is,*isarray; 51556e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 515630368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 5157f9eb5b7dSStefano Zampini PC pc_temp; 5158c8587f34SStefano Zampini PCType coarse_pc_type; 5159c8587f34SStefano Zampini KSPType coarse_ksp_type; 5160f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 51614f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 51626e683305SStefano Zampini Mat t_coarse_mat_is; 51636e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 51646e683305SStefano Zampini PetscMPIInt all_procs; 516574e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 516668457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 516722bc73bbSStefano Zampini PetscScalar *array; 51689881197aSStefano Zampini PetscErrorCode ierr; 5169fdc09c96SStefano Zampini 5170c8587f34SStefano Zampini PetscFunctionBegin; 5171c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 517268457ee5SStefano 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 */ 5173fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 51745a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 5175fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 5176f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 5177f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 5178f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 5179fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 518051bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 518151bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 5182dc4bcba2SStefano Zampini PC pc; 5183dc4bcba2SStefano Zampini PetscBool isbddc; 5184dc4bcba2SStefano Zampini 5185dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 5186dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 5187dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 5188dc4bcba2SStefano Zampini if (isbddc) { 5189*63c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 5190*63c961adSStefano Zampini } else { 5191727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 5192*63c961adSStefano Zampini } 5193fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5194fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 5195fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5196f4ddd8eeSStefano Zampini } 5197fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 5198fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5199f4ddd8eeSStefano Zampini } 520070cf5478SStefano Zampini /* reset any subassembling information */ 520170cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 52026e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 52036e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 5204fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5205f4ddd8eeSStefano Zampini } 5206c8587f34SStefano Zampini 52076e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 52082b510759SStefano Zampini im_active = !!(pcis->n); 52092b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 52106e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 52116e683305SStefano Zampini void_procs = all_procs-active_procs; 52126e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 521374e2c79eSStefano Zampini redist = PETSC_FALSE; 521422bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 52156e683305SStefano Zampini csin_ml = PETSC_TRUE; 52166e683305SStefano Zampini ncoarse_ml = void_procs; 5217779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 5218779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 52196e683305SStefano Zampini csin_ds = PETSC_TRUE; 522018a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 522118a45a71SStefano Zampini redist = PETSC_TRUE; 522218a45a71SStefano Zampini } else { 52236e683305SStefano Zampini csin_ds = PETSC_TRUE; 5224779c1cceSStefano Zampini ncoarse_ds = active_procs; 5225779c1cceSStefano Zampini redist = PETSC_TRUE; 522618a45a71SStefano Zampini } 52276e683305SStefano Zampini } else { 52286e683305SStefano Zampini csin_ml = PETSC_FALSE; 52296e683305SStefano Zampini ncoarse_ml = all_procs; 52306e683305SStefano Zampini if (void_procs) { 52316e683305SStefano Zampini csin_ds = PETSC_TRUE; 52326e683305SStefano Zampini ncoarse_ds = void_procs; 52336e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 52346e683305SStefano Zampini } else { 5235779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 523674e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 523774e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 523874e2c79eSStefano Zampini redist = PETSC_TRUE; 523974e2c79eSStefano Zampini } else { 52406e683305SStefano Zampini csin_ds = PETSC_FALSE; 52416e683305SStefano Zampini ncoarse_ds = all_procs; 52426e683305SStefano Zampini } 52436e683305SStefano Zampini } 524474e2c79eSStefano Zampini } 52456e683305SStefano Zampini 52466e683305SStefano Zampini /* 52476e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 52486e683305SStefano Zampini - we have not exceeded the number of levels requested 52496e683305SStefano Zampini - we can actually subassemble the active processes 52506e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 52516e683305SStefano Zampini */ 52526e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 52536e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 52546e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 52556e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 52566e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 5257f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 52582b510759SStefano Zampini } else { 5259f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 5260c8587f34SStefano Zampini } 5261c8587f34SStefano Zampini } 52626e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 52636e683305SStefano Zampini if (multilevel_allowed) { 52646e683305SStefano Zampini ncoarse = ncoarse_ml; 52656e683305SStefano Zampini csin = csin_ml; 526658da7f69SStefano Zampini redist = PETSC_FALSE; 52676e683305SStefano Zampini } else { 52686e683305SStefano Zampini ncoarse = ncoarse_ds; 52696e683305SStefano Zampini csin = csin_ds; 52706e683305SStefano Zampini } 5271e7931f94SStefano Zampini 5272abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 5273abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 5274abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 5275abbbba34SStefano Zampini 5276abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 527722bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 527822bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 527922bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 528022bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 5281e176bc59SStefano 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); 52826e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 52836e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 52846e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5285abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 5286abbbba34SStefano Zampini 52876e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 528830368db7SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local))) { /* protects from unneded computations */ 52896e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 52906e683305SStefano Zampini const PetscInt *idxs; 52916e683305SStefano Zampini ISLocalToGlobalMapping tmap; 52926e683305SStefano Zampini 52936e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 52940be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 52956e683305SStefano Zampini /* allocate space for temporary storage */ 5296854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 5297854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 52986e683305SStefano Zampini /* allocate for IS array */ 52996e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 53006e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 530130368db7SStefano Zampini nisvert = 0; 530230368db7SStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local) { 530330368db7SStefano Zampini nisvert = 1; 530430368db7SStefano Zampini } 530530368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 5306854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 53076e683305SStefano Zampini /* dofs splitting */ 53086e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 53096e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 53106e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 53116e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 53126e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 53136e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 53146e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 531530368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 53166e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 53176e683305SStefano Zampini } 53186e683305SStefano Zampini /* neumann boundaries */ 53196e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 53206e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 53216e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 53226e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 53236e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 53246e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 53256e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 532630368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 53276e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 53286e683305SStefano Zampini } 532930368db7SStefano Zampini /* primal vertices (benign) */ 533030368db7SStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local) { 533130368db7SStefano Zampini ierr = ISGetLocalSize(pcbddc->user_primal_vertices_local,&tsize);CHKERRQ(ierr); 533230368db7SStefano Zampini ierr = ISGetIndices(pcbddc->user_primal_vertices_local,&idxs);CHKERRQ(ierr); 533330368db7SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 533430368db7SStefano Zampini ierr = ISRestoreIndices(pcbddc->user_primal_vertices_local,&idxs);CHKERRQ(ierr); 533530368db7SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 533630368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nis-1]);CHKERRQ(ierr); 533730368db7SStefano Zampini } 53386e683305SStefano Zampini /* free memory */ 53396e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 53406e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 53416e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 53426e683305SStefano Zampini } else { 53436e683305SStefano Zampini nis = 0; 53446e683305SStefano Zampini nisdofs = 0; 53456e683305SStefano Zampini nisneu = 0; 534630368db7SStefano Zampini nisvert = 0; 53476e683305SStefano Zampini isarray = NULL; 53486e683305SStefano Zampini } 53496e683305SStefano Zampini /* destroy no longer needed map */ 53506e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 53516e683305SStefano Zampini 53526e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 53536e683305SStefano Zampini coarse_mat_is = NULL; 53546e683305SStefano Zampini if (csin) { 53556e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 535674e2c79eSStefano Zampini if (redist) { 535774e2c79eSStefano Zampini PetscMPIInt rank; 5358779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 535974e2c79eSStefano Zampini 536074e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 536158da7f69SStefano Zampini spc = active_procs/ncoarse; 536258da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 5363779c1cceSStefano Zampini if (im_active) { 5364779c1cceSStefano Zampini destsize = 1; 536574e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 536674e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 536774e2c79eSStefano Zampini } else { 536874e2c79eSStefano Zampini dest[0] = rank/(spc+1); 536974e2c79eSStefano Zampini } 537074e2c79eSStefano Zampini } else { 5371779c1cceSStefano Zampini destsize = 0; 53726e683305SStefano Zampini } 5373779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 5374779c1cceSStefano Zampini } else if (csin_type_simple) { 53756e683305SStefano Zampini PetscMPIInt rank; 53766e683305SStefano Zampini PetscInt issize,isidx; 5377779c1cceSStefano Zampini 53786e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 53796e683305SStefano Zampini if (im_active) { 53806e683305SStefano Zampini issize = 1; 53816e683305SStefano Zampini isidx = (PetscInt)rank; 53826e683305SStefano Zampini } else { 53836e683305SStefano Zampini issize = 0; 53846e683305SStefano Zampini isidx = -1; 53856e683305SStefano Zampini } 53866e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 5387779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 5388b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 53896e683305SStefano Zampini } 5390779c1cceSStefano Zampini 5391779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 5392779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 5393779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 5394779c1cceSStefano Zampini PetscInt *coarse_candidates; 5395779c1cceSStefano Zampini const PetscInt* tisindices; 5396779c1cceSStefano Zampini 5397779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 5398779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 5399779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5400779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 5401779c1cceSStefano Zampini if (!coarse_candidates[i]) { 5402779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 5403779c1cceSStefano Zampini } 5404779c1cceSStefano Zampini } 5405779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 5406779c1cceSStefano Zampini 5407779c1cceSStefano Zampini 54086e683305SStefano Zampini if (pcbddc->dbg_flag) { 54096e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54106e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 54116e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 54126e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 5413779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 54146e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 54156e683305SStefano Zampini } 54166e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 54176e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54186e683305SStefano Zampini } 54196e683305SStefano Zampini /* shift the pattern on coarse candidates */ 54206e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 54216e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 5422854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 54236e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 54246e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 54256e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 54266e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 54276e683305SStefano Zampini } 54286e683305SStefano Zampini if (pcbddc->dbg_flag) { 54296e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54306e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 54316e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 54326e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54336e683305SStefano Zampini } 5434779c1cceSStefano Zampini } 54356e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 543653a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 543753a05cb3SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,PETSC_FALSE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 543853a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 543953a05cb3SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,PETSC_TRUE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 544053a05cb3SStefano Zampini } 54416e683305SStefano Zampini } else { 54426e683305SStefano Zampini if (pcbddc->dbg_flag) { 54436e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54446e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 54456e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54466e683305SStefano Zampini } 54476e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 54486e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 54496e683305SStefano Zampini } 54506e683305SStefano Zampini 54516e683305SStefano Zampini /* create local to global scatters for coarse problem */ 545268457ee5SStefano Zampini if (compute_vecs) { 54536e683305SStefano Zampini PetscInt lrows; 54546e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 54556e683305SStefano Zampini if (coarse_mat_is) { 54566e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 54576e683305SStefano Zampini } else { 54586e683305SStefano Zampini lrows = 0; 54596e683305SStefano Zampini } 54606e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 54616e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 54626e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 54636e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 54646e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 54656e683305SStefano Zampini } 54666e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 54676e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 5468c8587f34SStefano Zampini 5469f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 5470f9eb5b7dSStefano Zampini if (multilevel_allowed) { 5471f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 5472f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 5473f9eb5b7dSStefano Zampini } else { 5474f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 5475f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 5476c8587f34SStefano Zampini } 5477c8587f34SStefano Zampini 54786e683305SStefano Zampini /* print some info if requested */ 54796e683305SStefano Zampini if (pcbddc->dbg_flag) { 54806e683305SStefano Zampini if (!multilevel_allowed) { 54816e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54826e683305SStefano Zampini if (multilevel_requested) { 54836e683305SStefano 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); 54846e683305SStefano Zampini } else if (pcbddc->max_levels) { 54856e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 54866e683305SStefano Zampini } 54876e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54886e683305SStefano Zampini } 54896e683305SStefano Zampini } 54906e683305SStefano Zampini 5491f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 54926e683305SStefano Zampini if (coarse_mat_is) { 54936e683305SStefano Zampini MatReuse coarse_mat_reuse; 54946a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 54956e683305SStefano Zampini if (pcbddc->dbg_flag) { 54966e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 54976e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 54986e683305SStefano Zampini } 5499f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 5500312be037SStefano Zampini char prefix[256],str_level[16]; 5501e604994aSStefano Zampini size_t len; 55026e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 5503422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 5504c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5505f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 55065f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 5507c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 55086e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 5509c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 5510c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5511e604994aSStefano Zampini /* prefix */ 5512e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 5513e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 5514e604994aSStefano Zampini if (!pcbddc->current_level) { 5515e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5516e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 5517c8587f34SStefano Zampini } else { 5518e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5519312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5520312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 552134d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5522312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 5523e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 5524e604994aSStefano Zampini } 5525e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 55263e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 55273e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 55283e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 55293e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 5530f9eb5b7dSStefano Zampini /* allow user customization */ 5531f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 55323e3c6dadSStefano Zampini } 55333e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 553451bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 55353e3c6dadSStefano Zampini if (nisdofs) { 55363e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 55373e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 55383e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 55393e3c6dadSStefano Zampini } 55403e3c6dadSStefano Zampini } 55413e3c6dadSStefano Zampini if (nisneu) { 55423e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 55433e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 5544312be037SStefano Zampini } 554530368db7SStefano Zampini if (nisvert) { 554630368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 554730368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 554830368db7SStefano Zampini } 5549f9eb5b7dSStefano Zampini 5550f9eb5b7dSStefano Zampini /* get some info after set from options */ 5551f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 5552f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 55534f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 55546e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 5555f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5556f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 5557f9eb5b7dSStefano Zampini } 555839f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 55594f3a063dSStefano Zampini if (isredundant) { 55604f3a063dSStefano Zampini KSP inner_ksp; 55614f3a063dSStefano Zampini PC inner_pc; 55624f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 55634f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 55644f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 55654f3a063dSStefano Zampini } 5566f9eb5b7dSStefano Zampini 5567f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 5568fa7f1dd8SStefano Zampini if (coarse_reuse) { 556981d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 5570fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 55716e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 5572fa7f1dd8SStefano Zampini } else { 55736e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 5574fa7f1dd8SStefano Zampini } 5575c8587f34SStefano Zampini if (isbddc || isnn) { 5576d4d8cf7bSStefano Zampini if (isbddc) { /* currently there's no API for this */ 5577d4d8cf7bSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc_temp->data; 5578d4d8cf7bSStefano Zampini pcbddc->detect_disconnected = PETSC_TRUE; 5579d4d8cf7bSStefano Zampini } 558022bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 558170cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 5582b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 558322b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 55846e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 55856e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 55866e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 55876e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 558822b6e8a2SStefano Zampini } 558970cf5478SStefano Zampini } 559053a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 559170cf5478SStefano Zampini } else { 559222bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 559322bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 559422bc73bbSStefano Zampini } 559522bc73bbSStefano Zampini } else { 55962e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 5597c8587f34SStefano Zampini } 5598c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 5599c8587f34SStefano Zampini 56003301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 56015a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 56023301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 56033301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 56043301b35fSStefano Zampini } 56053301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 56063301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 56073301b35fSStefano Zampini } 56083301b35fSStefano Zampini if (pc->pmat->spd_set) { 56093301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 56103301b35fSStefano Zampini } 56116e683305SStefano Zampini /* set operators */ 56125f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 56136e683305SStefano Zampini if (pcbddc->dbg_flag) { 56146e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 56156e683305SStefano Zampini } 56166e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 56176e683305SStefano Zampini coarse_mat = 0; 56186e683305SStefano Zampini } 56196e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 5620b1ecc7b1SStefano Zampini #if 0 5621b9b85e73SStefano Zampini { 5622b9b85e73SStefano Zampini PetscViewer viewer; 5623b9b85e73SStefano Zampini char filename[256]; 5624b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 5625b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 5626b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5627b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 5628b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5629b9b85e73SStefano Zampini } 5630b9b85e73SStefano Zampini #endif 5631c8587f34SStefano Zampini 5632c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 5633298c0119SStefano Zampini #if 0 5634c8587f34SStefano Zampini if (pcbddc->NullSpace) { 5635c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 563698a51de6SStefano Zampini } 5637298c0119SStefano Zampini #endif 5638b0f5fe93SStefano Zampini /* hack */ 563998a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 564098a51de6SStefano Zampini Vec crhs,csol; 564104708bb6SStefano Zampini 5642f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 5643f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 5644f347579bSStefano Zampini if (!csol) { 56452a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 5646f9eb5b7dSStefano Zampini } 5647f347579bSStefano Zampini if (!crhs) { 56482a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 5649f347579bSStefano Zampini } 5650b0f5fe93SStefano Zampini } 5651b0f5fe93SStefano Zampini 5652b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 5653b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 5654b0f5fe93SStefano Zampini 5655b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 56564f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 56574f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 56584f1b2e48SStefano Zampini } 5659b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 5660b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 5661b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5662b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5663b0f5fe93SStefano Zampini if (coarse_mat) { 5664b0f5fe93SStefano Zampini Vec nullv; 5665b0f5fe93SStefano Zampini PetscScalar *array,*array2; 5666b0f5fe93SStefano Zampini PetscInt nl; 5667b0f5fe93SStefano Zampini 5668b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 5669b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 5670b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5671b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 5672b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 5673b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 5674b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5675b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 5676b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 5677b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 5678b0f5fe93SStefano Zampini } 5679b0f5fe93SStefano Zampini } 5680b0f5fe93SStefano Zampini 5681b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 5682b0f5fe93SStefano Zampini PetscBool ispreonly; 5683b0f5fe93SStefano Zampini 5684b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5685b0f5fe93SStefano Zampini PetscBool isnull; 5686b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 5687d4d8cf7bSStefano Zampini if (0) { 568830368db7SStefano Zampini if (isbddc && !pcbddc->benign_saddle_point) { 5689b0f5fe93SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 5690b0f5fe93SStefano Zampini } else { 5691b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 5692b0f5fe93SStefano Zampini } 5693b0f5fe93SStefano Zampini } else { 5694b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5695b0f5fe93SStefano Zampini } 5696b0f5fe93SStefano Zampini } 5697b0f5fe93SStefano Zampini /* setup coarse ksp */ 5698b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 5699cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 5700cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 57016e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 5702c8587f34SStefano Zampini KSP check_ksp; 57032b510759SStefano Zampini KSPType check_ksp_type; 5704c8587f34SStefano Zampini PC check_pc; 57056e683305SStefano Zampini Vec check_vec,coarse_vec; 57066a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 57072b510759SStefano Zampini PetscInt its; 57086e683305SStefano Zampini PetscBool compute_eigs; 57096e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 57106e683305SStefano Zampini PetscInt neigs; 57118e185a42SStefano Zampini const char *prefix; 5712c8587f34SStefano Zampini 57132b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 57146e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 5715422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 571623ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 5717f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 57182b510759SStefano Zampini if (ispreonly) { 57192b510759SStefano Zampini check_ksp_type = KSPPREONLY; 57206e683305SStefano Zampini compute_eigs = PETSC_FALSE; 57212b510759SStefano Zampini } else { 5722cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 57236e683305SStefano Zampini compute_eigs = PETSC_TRUE; 5724c8587f34SStefano Zampini } 5725c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 57266e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 57276e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 57286e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 5729a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 5730a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 5731a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 5732a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 5733c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 5734c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 5735c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 5736c8587f34SStefano Zampini /* create random vec */ 57376e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 57386e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 5739c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 5740c8587f34SStefano Zampini if (CoarseNullSpace) { 5741c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 5742c8587f34SStefano Zampini } 57436e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 5744c8587f34SStefano Zampini /* solve coarse problem */ 57456e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 5746c8587f34SStefano Zampini if (CoarseNullSpace) { 57476e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 5748c8587f34SStefano Zampini } 5749cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 57506e683305SStefano Zampini if (compute_eigs) { 5751854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 5752854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 57536e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 57546e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 57556e683305SStefano Zampini lambda_min = eigs_r[0]; 57566e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 57576e683305SStefano Zampini if (lambda_max>lambda_min) { 5758cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 5759cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 5760cbcc2c2aSStefano Zampini } 5761c8587f34SStefano Zampini } 5762c8587f34SStefano Zampini } 5763cbcc2c2aSStefano Zampini 5764c8587f34SStefano Zampini /* check coarse problem residual error */ 57656e683305SStefano Zampini if (pcbddc->dbg_flag) { 57666e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 57676e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 57686e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 5769c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 57706e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 57716e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 5772c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 5773779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 57746e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 57756e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 57766e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 57776e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 5778b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5779b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 5780b0f5fe93SStefano Zampini } 57816e683305SStefano Zampini if (compute_eigs) { 57826e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 5783deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 5784c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 57856e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 57866e683305SStefano 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); 57876e683305SStefano Zampini for (i=0;i<neigs;i++) { 57886e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 5789c8587f34SStefano Zampini } 57906e683305SStefano Zampini } 57916e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 57926e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 57936e683305SStefano Zampini } 5794c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 57956e683305SStefano Zampini if (compute_eigs) { 57966e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 57976e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 5798c8587f34SStefano Zampini } 57996e683305SStefano Zampini } 58006e683305SStefano Zampini } 5801cbcc2c2aSStefano Zampini /* print additional info */ 5802cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 58036e683305SStefano Zampini /* waits until all processes reaches this point */ 58046e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 5805cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 5806cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5807cbcc2c2aSStefano Zampini } 5808cbcc2c2aSStefano Zampini 58092b510759SStefano Zampini /* free memory */ 5810c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5811fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 5812c8587f34SStefano Zampini PetscFunctionReturn(0); 5813c8587f34SStefano Zampini } 5814674ae819SStefano Zampini 5815f34684f1SStefano Zampini #undef __FUNCT__ 5816f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 5817f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 5818f34684f1SStefano Zampini { 5819f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5820f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 5821f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5822dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 5823dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 582473be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 5825dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 5826f34684f1SStefano Zampini PetscErrorCode ierr; 5827f34684f1SStefano Zampini 5828f34684f1SStefano Zampini PetscFunctionBegin; 5829f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 58300e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 58310e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 5832727cdba6SStefano Zampini } 5833dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 58343bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 5835dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5836dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 5837dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 5838dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 5839dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 5840dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 58410e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 58420e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 58430e6343abSStefano Zampini } 5844dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 5845dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5846dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 5847dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5848dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5849f34684f1SStefano Zampini 5850f34684f1SStefano Zampini /* check numbering */ 5851f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 5852019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 5853dc456d91SStefano Zampini PetscInt i; 5854b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 5855f34684f1SStefano Zampini 5856f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5857f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5858f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 58591575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5860019a44ceSStefano Zampini /* counter */ 5861019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5862019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5863019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5864019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5865019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5866019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5867f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 5868f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 5869727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5870f34684f1SStefano Zampini } 5871f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5872f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5873f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5874e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5875e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5876e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5877e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5878f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5879019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5880f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5881019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 588275c01103SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]); 588375c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 5884b9b85e73SStefano Zampini set_error = PETSC_TRUE; 5885019a44ceSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d: local index %d owned by a %d processes instead of %d!\n",PetscGlobalRank,i,owned,neigh);CHKERRQ(ierr); 5886f34684f1SStefano Zampini } 5887f34684f1SStefano Zampini } 5888019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5889b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5890f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5891f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5892f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 5893f34684f1SStefano Zampini } 5894f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5895f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5896e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5897e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5898f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 5899f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 5900b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 5901ca8b9ea9SStefano Zampini PetscInt *gidxs; 5902ca8b9ea9SStefano Zampini 5903ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 59043bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 5905f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 5906f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5907f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5908f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 59094bc2dc4bSStefano 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); 5910f34684f1SStefano Zampini } 5911f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5912ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 5913f34684f1SStefano Zampini } 5914f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 59151575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5916302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 5917f34684f1SStefano Zampini } 59188bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 5919f34684f1SStefano Zampini /* get back data */ 5920f34684f1SStefano Zampini *coarse_size_n = coarse_size; 5921f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 5922674ae819SStefano Zampini PetscFunctionReturn(0); 5923674ae819SStefano Zampini } 5924674ae819SStefano Zampini 5925e456f2a8SStefano Zampini #undef __FUNCT__ 5926e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 5927a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 5928e456f2a8SStefano Zampini { 5929e456f2a8SStefano Zampini IS localis_t; 5930a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 5931e456f2a8SStefano Zampini PetscScalar *vals; 5932e456f2a8SStefano Zampini PetscErrorCode ierr; 5933e456f2a8SStefano Zampini 5934e456f2a8SStefano Zampini PetscFunctionBegin; 5935a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 5936e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 5937854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 5938e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 5939e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5940a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 5941a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 59421035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 5943a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 59441035eff8SStefano Zampini } 5945a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 5946e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5947e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5948a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 5949a7dc3881SStefano Zampini /* now compute set in local ordering */ 5950a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5951a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5952a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5953a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 5954a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5955ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5956e456f2a8SStefano Zampini lsize++; 5957e456f2a8SStefano Zampini } 5958e456f2a8SStefano Zampini } 5959854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 5960a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5961ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5962e456f2a8SStefano Zampini idxs[lsize++] = i; 5963e456f2a8SStefano Zampini } 5964e456f2a8SStefano Zampini } 5965a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5966a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 5967e456f2a8SStefano Zampini *localis = localis_t; 5968e456f2a8SStefano Zampini PetscFunctionReturn(0); 5969e456f2a8SStefano Zampini } 5970906d46d4SStefano Zampini 5971906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 5972906d46d4SStefano Zampini #undef __FUNCT__ 5973906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 5974906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 5975906d46d4SStefano Zampini { 5976906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5977906d46d4SStefano Zampini PetscErrorCode ierr; 5978906d46d4SStefano Zampini 5979906d46d4SStefano Zampini PetscFunctionBegin; 5980906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5981906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5982906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5983906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5984906d46d4SStefano Zampini PetscFunctionReturn(0); 5985906d46d4SStefano Zampini } 5986906d46d4SStefano Zampini 5987906d46d4SStefano Zampini #undef __FUNCT__ 5988906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 5989906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 5990906d46d4SStefano Zampini { 5991906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5992906d46d4SStefano Zampini PetscErrorCode ierr; 5993906d46d4SStefano Zampini 5994906d46d4SStefano Zampini PetscFunctionBegin; 5995906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5996906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5997906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5998906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5999906d46d4SStefano Zampini PetscFunctionReturn(0); 6000906d46d4SStefano Zampini } 6001b96c3477SStefano Zampini 6002b96c3477SStefano Zampini #undef __FUNCT__ 6003b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 600408122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 6005b96c3477SStefano Zampini { 6006a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6007b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6008b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6009a64f4aa4SStefano Zampini Mat S_j; 6010b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 6011b96c3477SStefano Zampini PetscBool free_used_adj; 6012b96c3477SStefano Zampini PetscErrorCode ierr; 6013b96c3477SStefano Zampini 6014b96c3477SStefano Zampini PetscFunctionBegin; 6015b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 6016b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 601708122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 6018b96c3477SStefano Zampini used_xadj = NULL; 6019b96c3477SStefano Zampini used_adjncy = NULL; 6020b96c3477SStefano Zampini } else { 602108122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 602208122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 602308122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 602408122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 6025b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 6026b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 6027b96c3477SStefano Zampini } else { 60282fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 6029b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 6030b96c3477SStefano Zampini PetscInt nvtxs; 6031b96c3477SStefano Zampini 60322fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 60332fffb893SStefano Zampini if (flg_row) { 6034b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 6035b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 6036b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 6037b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 60382fffb893SStefano Zampini } else { 60392fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 60402fffb893SStefano Zampini used_xadj = NULL; 60412fffb893SStefano Zampini used_adjncy = NULL; 60422fffb893SStefano Zampini } 60432fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 6044b96c3477SStefano Zampini } 6045b96c3477SStefano Zampini } 6046d5574798SStefano Zampini 6047d5574798SStefano Zampini /* setup sub_schurs data */ 6048a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6049df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 6050df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 6051a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6052ca92afb2SStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,NULL,S_j,PETSC_FALSE,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,pcbddc->faster_deluxe,pcbddc->adaptive_selection,PETSC_FALSE,PETSC_FALSE,0,NULL,NULL);CHKERRQ(ierr); 6053a64f4aa4SStefano Zampini } else { 60546816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 605504708bb6SStefano Zampini PetscBool isseqaij; 6056a3df083aSStefano Zampini PetscInt benign_n; 6057a3df083aSStefano Zampini 60585feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 60595feab87aSStefano Zampini PetscInt n_vertices; 60605feab87aSStefano Zampini 60615feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 60622034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 60635feab87aSStefano Zampini } 606404708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 606504708bb6SStefano Zampini if (!isseqaij) { 606604708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 606704708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 606804708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 606904708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 607004708bb6SStefano Zampini } else { 607104708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 607204708bb6SStefano Zampini } 607304708bb6SStefano Zampini } 6074a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 6075a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 6076ca92afb2SStefano Zampini } else { 6077a3df083aSStefano Zampini benign_n = 0; 6078ca92afb2SStefano Zampini } 6079a3df083aSStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,pcbddc->local_mat,S_j,pcbddc->sub_schurs_exact_schur,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,pcbddc->faster_deluxe,pcbddc->adaptive_selection,reuse_solvers,pcbddc->benign_saddle_point,benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 6080ca92afb2SStefano Zampini } 6081d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6082b96c3477SStefano Zampini 6083b96c3477SStefano Zampini /* free adjacency */ 6084b96c3477SStefano Zampini if (free_used_adj) { 6085b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 6086b96c3477SStefano Zampini } 6087b96c3477SStefano Zampini PetscFunctionReturn(0); 6088b96c3477SStefano Zampini } 6089b96c3477SStefano Zampini 6090b96c3477SStefano Zampini #undef __FUNCT__ 6091b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 609208122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 6093b96c3477SStefano Zampini { 6094b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6095b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6096b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6097b96c3477SStefano Zampini PCBDDCGraph graph; 6098b96c3477SStefano Zampini PetscErrorCode ierr; 6099b96c3477SStefano Zampini 6100b96c3477SStefano Zampini PetscFunctionBegin; 6101b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 610208122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 61033301b35fSStefano Zampini IS verticesIS,verticescomm; 61043301b35fSStefano Zampini PetscInt vsize,*idxs; 6105b96c3477SStefano Zampini 6106b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 61073301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 61083301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 61093301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 61103301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 61113301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 6112b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 61137fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 61143301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 61153301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 6116b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 6117b96c3477SStefano Zampini /* 6118b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 6119b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6120b96c3477SStefano Zampini } 6121b96c3477SStefano Zampini */ 6122b96c3477SStefano Zampini } else { 6123b96c3477SStefano Zampini graph = pcbddc->mat_graph; 6124b96c3477SStefano Zampini } 6125b96c3477SStefano Zampini 6126b96c3477SStefano Zampini /* sub_schurs init */ 6127a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 6128a64f4aa4SStefano Zampini 6129b96c3477SStefano Zampini /* free graph struct */ 613008122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 6131b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6132b96c3477SStefano Zampini } 6133b96c3477SStefano Zampini PetscFunctionReturn(0); 6134b96c3477SStefano Zampini } 6135fa34dd3eSStefano Zampini 6136fa34dd3eSStefano Zampini #undef __FUNCT__ 6137fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 6138fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 6139fa34dd3eSStefano Zampini { 6140fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6141fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6142fa34dd3eSStefano Zampini PetscErrorCode ierr; 6143fa34dd3eSStefano Zampini 6144fa34dd3eSStefano Zampini PetscFunctionBegin; 6145fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 6146fa34dd3eSStefano Zampini IS zerodiag = NULL; 61474f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 6148fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 61494f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 615075c01103SStefano Zampini PetscReal norm; 6151fa34dd3eSStefano Zampini PetscInt i; 6152fa34dd3eSStefano Zampini 6153fa34dd3eSStefano Zampini /* B0 and B0_B */ 6154fa34dd3eSStefano Zampini if (zerodiag) { 6155fa34dd3eSStefano Zampini IS dummy; 6156fa34dd3eSStefano Zampini 61574f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 61584f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 6159fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 6160fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 6161fa34dd3eSStefano Zampini } 6162fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 6163fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 6164fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 6165fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6166fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6167fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6168fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6169fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 6170fa34dd3eSStefano Zampini /* S_j */ 6171fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6172fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6173fa34dd3eSStefano Zampini 6174fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 6175fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 6176fa34dd3eSStefano Zampini /* continuous in primal space */ 6177fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 6178fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6179fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6180fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 61814f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 61824f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 6183fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6184fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6185fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6186fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6187fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6188fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6189fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 6190fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 6191fa34dd3eSStefano Zampini 6192fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 6193fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 6194fa34dd3eSStefano Zampini /* local with Schur */ 6195fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 6196fa34dd3eSStefano Zampini if (zerodiag) { 6197fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 61984f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 6199fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6200fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 6201fa34dd3eSStefano Zampini } 6202fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 6203fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6204fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6205fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6206fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6207fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 6208fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6209fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6210fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 6211fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6212fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6213fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6214fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6215fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6216fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 6217fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 6218fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6219fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6220fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6221fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6222fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6223fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6224fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 6225fa34dd3eSStefano Zampini if (zerodiag) { 6226fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 6227fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 62284f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 6229fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6230fa34dd3eSStefano Zampini } 6231fa34dd3eSStefano Zampini /* BDDC */ 6232fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 6233fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 6234fa34dd3eSStefano Zampini 6235fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 6236fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 6237fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 6238fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 62394f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 62404f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 6241fa34dd3eSStefano Zampini } 62424f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 6243fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 6244fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 6245fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 6246fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6247fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 6248fa34dd3eSStefano Zampini } 6249fa34dd3eSStefano Zampini PetscFunctionReturn(0); 6250fa34dd3eSStefano Zampini } 6251