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; 2894f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 2904f1b2e48SStefano Zampini if (!isseqaij && filter) { 2911cf9b237SStefano Zampini PetscBool isseqdense; 2921cf9b237SStefano Zampini 2931cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 2941cf9b237SStefano Zampini if (!isseqdense) { 2954f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 2961cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 2971cf9b237SStefano Zampini PetscScalar *array; 2981cf9b237SStefano Zampini PetscReal chop=1.e-6; 2991cf9b237SStefano Zampini 3001cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 3011cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 3021cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 3031cf9b237SStefano Zampini for (i=0;i<n;i++) { 3041cf9b237SStefano Zampini PetscInt j; 3051cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 3061cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 3071cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 3081cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 3091cf9b237SStefano Zampini } 3101cf9b237SStefano Zampini } 3111cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 3121cf9b237SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_REUSE_MATRIX,&B);CHKERRQ(ierr); 3131cf9b237SStefano Zampini } 3144f1b2e48SStefano Zampini } else { 3154f1b2e48SStefano Zampini B = A; 3164f1b2e48SStefano Zampini } 3174f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3184f1b2e48SStefano Zampini 3194f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 3204f1b2e48SStefano Zampini if (filter) { 3214f1b2e48SStefano Zampini PetscScalar *data; 3224f1b2e48SStefano Zampini PetscInt j,cum; 3234f1b2e48SStefano Zampini 3244f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 3254f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 3264f1b2e48SStefano Zampini cum = 0; 3274f1b2e48SStefano Zampini for (i=0;i<n;i++) { 3284f1b2e48SStefano Zampini PetscInt t; 3294f1b2e48SStefano Zampini 3304f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 3314f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 3324f1b2e48SStefano Zampini continue; 3334f1b2e48SStefano Zampini } 3344f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 3354f1b2e48SStefano Zampini } 3364f1b2e48SStefano Zampini t = xadj_filtered[i]; 3374f1b2e48SStefano Zampini xadj_filtered[i] = cum; 3384f1b2e48SStefano Zampini cum += t; 3394f1b2e48SStefano Zampini } 3404f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 3414f1b2e48SStefano Zampini } else { 3424f1b2e48SStefano Zampini xadj_filtered = NULL; 3434f1b2e48SStefano Zampini adjncy_filtered = NULL; 3444f1b2e48SStefano Zampini } 3454f1b2e48SStefano Zampini 3464f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 3474f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 3484f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 3494f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 3504f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 3514f1b2e48SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n);CHKERRQ(ierr); 3524f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 3534f1b2e48SStefano Zampini if (xadj_filtered) { 3544f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 3554f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 3564f1b2e48SStefano Zampini } else { 3574f1b2e48SStefano Zampini graph->xadj = xadj; 3584f1b2e48SStefano Zampini graph->adjncy = adjncy; 3594f1b2e48SStefano Zampini } 3604f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 3614f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 3624f1b2e48SStefano Zampini /* partial clean up */ 3634f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 3644f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3651cf9b237SStefano Zampini if (A != B) { 3664f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 3674f1b2e48SStefano Zampini } 3684f1b2e48SStefano Zampini 3694f1b2e48SStefano Zampini /* get back data */ 3701cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 3711cf9b237SStefano Zampini if (cc) { 3724f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 3734f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 3744f1b2e48SStefano 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); 3754f1b2e48SStefano Zampini } 3764f1b2e48SStefano Zampini *cc = cc_n; 3771cf9b237SStefano Zampini } 3784f1b2e48SStefano Zampini /* clean up graph */ 3794f1b2e48SStefano Zampini graph->xadj = 0; 3804f1b2e48SStefano Zampini graph->adjncy = 0; 3814f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 3824f1b2e48SStefano Zampini PetscFunctionReturn(0); 3834f1b2e48SStefano Zampini } 3844f1b2e48SStefano Zampini 3854f1b2e48SStefano Zampini #undef __FUNCT__ 3865408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 3875408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 3885408967cSStefano Zampini { 3895408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3905408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 391dee84bffSStefano Zampini IS dirIS = NULL; 3924f1b2e48SStefano Zampini PetscInt i; 3935408967cSStefano Zampini PetscErrorCode ierr; 3945408967cSStefano Zampini 3955408967cSStefano Zampini PetscFunctionBegin; 396dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 3975408967cSStefano Zampini if (zerodiag) { 3985408967cSStefano Zampini Mat A; 3995408967cSStefano Zampini Vec vec3_N; 4005408967cSStefano Zampini PetscScalar *vals; 4015408967cSStefano Zampini const PetscInt *idxs; 402d12d3064SStefano Zampini PetscInt nz,*count; 4035408967cSStefano Zampini 4045408967cSStefano Zampini /* p0 */ 4055408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 4065408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 4075408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 4085408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 4094f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 4105408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4115408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 4125408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 4135408967cSStefano Zampini /* v_I */ 4145408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 4155408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 4165408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4175408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 4185408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 4195408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 4205408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4215408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 4225408967cSStefano Zampini if (dirIS) { 4235408967cSStefano Zampini PetscInt n; 4245408967cSStefano Zampini 4255408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 4265408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 4275408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 4285408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 4295408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 4305408967cSStefano Zampini } 4315408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 4325408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 4335408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 4345408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 4355408967cSStefano Zampini ierr = MatISGetLocalMat(pc->mat,&A);CHKERRQ(ierr); 4365408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 4375408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 4384f1b2e48SStefano Zampini if (PetscAbsScalar(vals[0]) > PETSC_SMALL) { 4395408967cSStefano 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])); 4405408967cSStefano Zampini } 4415408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4425408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 443d12d3064SStefano Zampini 444d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 445d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 446d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 447d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 448d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 449d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 450*d4d8cf7bSStefano Zampini for (i=0;i<nz;i++) { 451d12d3064SStefano Zampini if (count[idxs[i]]) { 452d12d3064SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! pressure dof %d is an interface dof",idxs[i]); 453d12d3064SStefano Zampini } 454*d4d8cf7bSStefano Zampini } 455d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 456d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 4575408967cSStefano Zampini } 458dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 4595408967cSStefano Zampini 4605408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 4615408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 4624f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 4635408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 4644f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 4655408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 4664f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 4674f1b2e48SStefano Zampini if ((PetscInt)PetscRealPart(pcbddc->benign_p0[i]) != -PetscGlobalRank-i) { 4684f1b2e48SStefano 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); 4694f1b2e48SStefano Zampini } 4705408967cSStefano Zampini } 4715408967cSStefano Zampini PetscFunctionReturn(0); 4725408967cSStefano Zampini } 4735408967cSStefano Zampini 4745408967cSStefano Zampini #undef __FUNCT__ 475339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 476339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 477339f8db1SStefano Zampini { 478339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4794f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 480b0f5fe93SStefano Zampini PetscInt nz,n; 4814f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 482339f8db1SStefano Zampini PetscErrorCode ierr; 483339f8db1SStefano Zampini 484339f8db1SStefano Zampini PetscFunctionBegin; 4859f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 4869f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 487339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 488a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 489a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 490a3df083aSStefano Zampini } 491a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 492a3df083aSStefano Zampini pcbddc->benign_n = 0; 4934f1b2e48SStefano Zampini /* if a local info on dofs is present, assumes the last field is represented by "pressures" 4944f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 4954f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 4964f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 4974f1b2e48SStefano Zampini since the local Schur complements are SPD 4984f1b2e48SStefano Zampini */ 4994f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 5004f1b2e48SStefano Zampini have_null = PETSC_TRUE; 50140fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 5024f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 5034f1b2e48SStefano Zampini 5044f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 5054f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 5064f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 5074f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 508ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 50940fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 51040fa8d13SStefano Zampini if (!sorted) { 51140fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 51240fa8d13SStefano Zampini } 51340fa8d13SStefano Zampini } else { 51440fa8d13SStefano Zampini pressures = NULL; 51540fa8d13SStefano Zampini } 51697d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 51797d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 51897d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 519339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 520339f8db1SStefano Zampini if (!sorted) { 521339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 522339f8db1SStefano Zampini } 523339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 5244f1b2e48SStefano Zampini if (!nz) { 5254f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 5264f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 52740fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 52840fa8d13SStefano Zampini } 5294f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 5304f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 5314f1b2e48SStefano Zampini zerodiag_subs = NULL; 5324f1b2e48SStefano Zampini pcbddc->benign_n = 0; 5334f1b2e48SStefano Zampini if (has_null_pressures) { 5344f1b2e48SStefano Zampini IS *subs; 5354f1b2e48SStefano Zampini PetscInt nsubs,i; 5364f1b2e48SStefano Zampini 5374f1b2e48SStefano Zampini subs = pcbddc->local_subs; 5384f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 5394f1b2e48SStefano Zampini if (nsubs > 1) { 5404f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 5414f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 5424f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 5434f1b2e48SStefano Zampini IS t_zerodiag_subs; 5444f1b2e48SStefano Zampini PetscInt nl; 5454f1b2e48SStefano Zampini 5464f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 5474f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 5484f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 5494f1b2e48SStefano Zampini if (nl) { 5504f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 5514f1b2e48SStefano Zampini 5524f1b2e48SStefano Zampini if (pressures) { 5534f1b2e48SStefano Zampini IS t_pressure_subs; 5544f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 5554f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 5564f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 5574f1b2e48SStefano Zampini } 5584f1b2e48SStefano Zampini if (valid) { 5594f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 5604f1b2e48SStefano Zampini pcbddc->benign_n++; 5614f1b2e48SStefano Zampini } else { 5624f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 5634f1b2e48SStefano Zampini } 5644f1b2e48SStefano Zampini } 5654f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 5664f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 5674f1b2e48SStefano Zampini } 5684f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 5694f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 5704f1b2e48SStefano Zampini if (pressures) { 5714f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 5724f1b2e48SStefano Zampini } 5734f1b2e48SStefano Zampini if (valid) { 5744f1b2e48SStefano Zampini pcbddc->benign_n = 1; 575ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 5764f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 5774f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 5784f1b2e48SStefano Zampini } 5794f1b2e48SStefano Zampini } 5804f1b2e48SStefano Zampini } 5814f1b2e48SStefano Zampini 5824f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 5834f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 5844f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 5854f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 5864f1b2e48SStefano Zampini have_null = PETSC_FALSE; 5874f1b2e48SStefano Zampini } 5884f1b2e48SStefano Zampini 5894f1b2e48SStefano Zampini /* final check for null pressures */ 5904f1b2e48SStefano Zampini if (zerodiag && pressures) { 5914f1b2e48SStefano Zampini PetscInt nz,np; 5924f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 5934f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 5944f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 5954f1b2e48SStefano Zampini } 5964f1b2e48SStefano Zampini 5974f1b2e48SStefano Zampini if (recompute_zerodiag) { 5984f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 5994f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 6004f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 6014f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 6024f1b2e48SStefano Zampini } else { 6034f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 6044f1b2e48SStefano Zampini 6054f1b2e48SStefano Zampini nzn = 0; 6064f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 6074f1b2e48SStefano Zampini PetscInt ns; 6084f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 6094f1b2e48SStefano Zampini nzn += ns; 6104f1b2e48SStefano Zampini } 6114f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 6124f1b2e48SStefano Zampini nzn = 0; 6134f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 6144f1b2e48SStefano Zampini PetscInt ns,*idxs; 6154f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 6164f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 6174f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 6184f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 6194f1b2e48SStefano Zampini nzn += ns; 6204f1b2e48SStefano Zampini } 6214f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 6224f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 6234f1b2e48SStefano Zampini } 6244f1b2e48SStefano Zampini have_null = PETSC_FALSE; 6254f1b2e48SStefano Zampini } 6264f1b2e48SStefano Zampini 6274f1b2e48SStefano Zampini if (has_null_pressures) { 6284f1b2e48SStefano Zampini IS zerodiagc; 6294f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 6304f1b2e48SStefano Zampini PetscInt i,s,*nnz; 6314f1b2e48SStefano Zampini 6324f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 633339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 634339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 635339f8db1SStefano Zampini /* local change of basis for pressures */ 636339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 63797d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 638339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 639339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 640339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 6414f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 6424f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 6434f1b2e48SStefano Zampini PetscInt nzs,j; 6444f1b2e48SStefano Zampini 6454f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 6464f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 6474f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 6484f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 6494f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 6504f1b2e48SStefano Zampini } 651339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 652339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 653339f8db1SStefano Zampini /* set identity on velocities */ 654339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 655339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 656339f8db1SStefano Zampini } 6574f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 6584f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 6599f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 6604f1b2e48SStefano 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); 661339f8db1SStefano Zampini /* set change on pressures */ 6624f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 6634f1b2e48SStefano Zampini PetscScalar *array; 6644f1b2e48SStefano Zampini PetscInt nzs; 6654f1b2e48SStefano Zampini 6664f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 6674f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 6684f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 669339f8db1SStefano Zampini PetscScalar vals[2]; 670339f8db1SStefano Zampini PetscInt cols[2]; 671339f8db1SStefano Zampini 672339f8db1SStefano Zampini cols[0] = idxs[i]; 6734f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 674339f8db1SStefano Zampini vals[0] = 1.; 675b0f5fe93SStefano Zampini vals[1] = 1.; 6764f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 677339f8db1SStefano Zampini } 6784f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 6794f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 6804f1b2e48SStefano Zampini array[nzs-1] = 1.; 6814f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 6824f1b2e48SStefano Zampini /* store local idxs for p0 */ 6834f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 6844f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 685339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 6864f1b2e48SStefano Zampini } 687339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 688339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 689a3df083aSStefano Zampini /* project if needed */ 690a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 69197d764eeSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&pcbddc->benign_original_mat);CHKERRQ(ierr); 692339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 69397d764eeSStefano Zampini ierr = MatSeqAIJCompress(pcbddc->benign_original_mat,&pcbddc->local_mat);CHKERRQ(ierr); 69497d764eeSStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 695a3df083aSStefano Zampini } 6964f1b2e48SStefano Zampini /* store global idxs for p0 */ 6974f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 698339f8db1SStefano Zampini } 699ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 7004f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 701b0f5fe93SStefano Zampini 702b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 703b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 704339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 705339f8db1SStefano Zampini PetscFunctionReturn(0); 706339f8db1SStefano Zampini } 707339f8db1SStefano Zampini 708339f8db1SStefano Zampini #undef __FUNCT__ 709015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 710015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 711efc2fbd9SStefano Zampini { 712efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 713efc2fbd9SStefano Zampini PetscErrorCode ierr; 714efc2fbd9SStefano Zampini 715efc2fbd9SStefano Zampini PetscFunctionBegin; 716efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 717efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 7184f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 719efc2fbd9SStefano Zampini } 720015636ebSStefano Zampini if (get) { /* use SF to get values */ 721efc2fbd9SStefano Zampini PetscScalar *array; 722efc2fbd9SStefano Zampini 723efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 7244f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 7254f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 726efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 7274f1b2e48SStefano Zampini } else { /* use VecSetValues (not scalable, I should try to find a better solution (defining a new MPI_OP for reduction) */ 7284f1b2e48SStefano Zampini ierr = VecSetValues(v,pcbddc->benign_n,pcbddc->benign_p0_gidx,pcbddc->benign_p0,INSERT_VALUES);CHKERRQ(ierr); 729efc2fbd9SStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 730efc2fbd9SStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 731efc2fbd9SStefano Zampini } 732efc2fbd9SStefano Zampini PetscFunctionReturn(0); 733efc2fbd9SStefano Zampini } 734efc2fbd9SStefano Zampini 735efc2fbd9SStefano Zampini #undef __FUNCT__ 736c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 737c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 738c263805aSStefano Zampini { 739c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 740c263805aSStefano Zampini PetscErrorCode ierr; 741c263805aSStefano Zampini 742c263805aSStefano Zampini PetscFunctionBegin; 743c263805aSStefano Zampini /* TODO: add error checking 744c263805aSStefano Zampini - avoid nested pop (or push) calls. 745c263805aSStefano Zampini - cannot push before pop. 7461c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 747c263805aSStefano Zampini */ 7484f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 749efc2fbd9SStefano Zampini PetscFunctionReturn(0); 750efc2fbd9SStefano Zampini } 751c263805aSStefano Zampini if (pop) { 752a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 7534f1b2e48SStefano Zampini IS is_p0; 7544f1b2e48SStefano Zampini MatReuse reuse; 755c263805aSStefano Zampini 756c263805aSStefano Zampini /* extract B_0 */ 7574f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 7584f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 7594f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 7604f1b2e48SStefano Zampini } 7614f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 7624f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 763c263805aSStefano Zampini /* remove rows and cols from local problem */ 764c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 76597d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7664f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 7674f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 768a3df083aSStefano Zampini } else { 769a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 770a3df083aSStefano Zampini PetscScalar *vals; 771a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 772a3df083aSStefano Zampini 773a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 774a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 775a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 776a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 777a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 778a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 779a3df083aSStefano Zampini /* this matrix is very sparse: the nnz pattern is not known unless we do 2 sweeps of the next loop. 780a3df083aSStefano Zampini Setting nnz=100 should be more than enough */ 781a3df083aSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,100,NULL);CHKERRQ(ierr); 782a3df083aSStefano Zampini } 783a3df083aSStefano Zampini 784a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 785a3df083aSStefano Zampini PetscScalar *array; 786a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 787a3df083aSStefano Zampini 788a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 789a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 790a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 791a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 792a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 793a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 794a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 795a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 796a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 797a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 798a3df083aSStefano Zampini cum = 0; 799a3df083aSStefano Zampini for (j=0;j<n;j++) { 800a3df083aSStefano Zampini if (PetscUnlikely(PetscAbsReal(array[j]) > PETSC_SMALL)) { 801a3df083aSStefano Zampini vals[cum] = array[j]; 802a3df083aSStefano Zampini idxs_ins[cum] = j; 803a3df083aSStefano Zampini cum++; 804a3df083aSStefano Zampini } 805a3df083aSStefano Zampini } 806a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 807a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 808a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 809a3df083aSStefano Zampini } 810a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 811a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 812a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 813a3df083aSStefano Zampini } 814c263805aSStefano Zampini } else { /* push */ 815a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 8164f1b2e48SStefano Zampini PetscInt i; 8174f1b2e48SStefano Zampini 8184f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 8194f1b2e48SStefano Zampini PetscScalar *B0_vals; 8204f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 8214f1b2e48SStefano Zampini 8224f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 8234f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 8247b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 8254f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 8264f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 8274f1b2e48SStefano Zampini } 828c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 829c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 830a3df083aSStefano Zampini } else { 831a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 832a3df083aSStefano Zampini } 833c263805aSStefano Zampini } 834c263805aSStefano Zampini PetscFunctionReturn(0); 835c263805aSStefano Zampini } 836c263805aSStefano Zampini 837c263805aSStefano Zampini #undef __FUNCT__ 838b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 83908122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 840b1b3d7a2SStefano Zampini { 841b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 84208122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 84308122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 84408122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 84508122e43SStefano Zampini PetscScalar *work,lwork; 84608122e43SStefano Zampini PetscScalar *St,*S,*eigv; 84708122e43SStefano Zampini PetscScalar *Sarray,*Starray; 84808122e43SStefano Zampini PetscReal *eigs,thresh; 8491b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 850f6f667cfSStefano Zampini PetscBool allocated_S_St; 85108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 85208122e43SStefano Zampini PetscReal *rwork; 85308122e43SStefano Zampini #endif 854b1b3d7a2SStefano Zampini PetscErrorCode ierr; 855b1b3d7a2SStefano Zampini 856b1b3d7a2SStefano Zampini PetscFunctionBegin; 857df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 858df4d28bfSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 85908122e43SStefano Zampini } 86008122e43SStefano Zampini 86106a4e24aSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) { 86206a4e24aSStefano 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); 86306a4e24aSStefano Zampini } 86406a4e24aSStefano Zampini 865fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 866fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 867fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 868fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 8691575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 870fd14bc51SStefano Zampini } 871fd14bc51SStefano Zampini 872e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 873e496cd5dSStefano 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); 874e496cd5dSStefano Zampini } 875e496cd5dSStefano Zampini 87608122e43SStefano Zampini /* max size of subsets */ 87708122e43SStefano Zampini mss = 0; 87808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 87908122e43SStefano Zampini PetscInt subset_size; 880862806e4SStefano Zampini 88108122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 88208122e43SStefano Zampini mss = PetscMax(mss,subset_size); 88308122e43SStefano Zampini } 88408122e43SStefano Zampini 88508122e43SStefano Zampini /* min/max and threshold */ 88608122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 887f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 88808122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 889f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 890f6f667cfSStefano Zampini if (nmin) { 891f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 892f6f667cfSStefano Zampini } 89308122e43SStefano Zampini 89408122e43SStefano Zampini /* allocate lapack workspace */ 89508122e43SStefano Zampini cum = cum2 = 0; 89608122e43SStefano Zampini maxneigs = 0; 89708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 89808122e43SStefano Zampini PetscInt n,subset_size; 899f6f667cfSStefano Zampini 90008122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 90108122e43SStefano Zampini n = PetscMin(subset_size,nmax); 9029162d606SStefano Zampini cum += subset_size; 9039162d606SStefano Zampini cum2 += subset_size*n; 90408122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 90508122e43SStefano Zampini } 90608122e43SStefano Zampini if (mss) { 9079ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 90808122e43SStefano Zampini PetscBLASInt B_itype = 1; 90908122e43SStefano Zampini PetscBLASInt B_N = mss; 9104c6709b3SStefano Zampini PetscReal zero = 0.0; 9114c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 91208122e43SStefano Zampini 91308122e43SStefano Zampini B_lwork = -1; 91408122e43SStefano Zampini S = NULL; 91508122e43SStefano Zampini St = NULL; 916a58a30b4SStefano Zampini eigs = NULL; 917a58a30b4SStefano Zampini eigv = NULL; 918a58a30b4SStefano Zampini B_iwork = NULL; 919a58a30b4SStefano Zampini B_ifail = NULL; 920d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 921d1710679SStefano Zampini rwork = NULL; 922d1710679SStefano Zampini #endif 9238bec7fa6SStefano Zampini thresh = 1.0; 92408122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 92508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 92608122e43SStefano 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)); 92708122e43SStefano Zampini #else 92808122e43SStefano 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)); 92908122e43SStefano Zampini #endif 93008122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 93108122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 93208122e43SStefano Zampini } else { 93308122e43SStefano Zampini /* TODO */ 93408122e43SStefano Zampini } 93508122e43SStefano Zampini } else { 93608122e43SStefano Zampini lwork = 0; 93708122e43SStefano Zampini } 93808122e43SStefano Zampini 93908122e43SStefano Zampini nv = 0; 940d62866d3SStefano 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) */ 941d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 94208122e43SStefano Zampini } 9434c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 944f6f667cfSStefano Zampini if (allocated_S_St) { 945f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 946f6f667cfSStefano Zampini } 947f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 94808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 94908122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 95008122e43SStefano Zampini #endif 9519162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 9529162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 9539162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 95408122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 9559162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 95608122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 95708122e43SStefano Zampini 95808122e43SStefano Zampini maxneigs = 0; 95908122e43SStefano Zampini cum = cum2 = cumarray = 0; 9609162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 9619162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 962d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 96308122e43SStefano Zampini const PetscInt *idxs; 96408122e43SStefano Zampini 965d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 96608122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 96708122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 96808122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 96908122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 9709162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 9719162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 97208122e43SStefano Zampini } 97308122e43SStefano Zampini cum2 = cum; 974d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 97508122e43SStefano Zampini } 97608122e43SStefano Zampini 97708122e43SStefano Zampini if (mss) { /* multilevel */ 97808122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 97908122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 98008122e43SStefano Zampini } 98108122e43SStefano Zampini 982ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 98308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 98408122e43SStefano Zampini const PetscInt *idxs; 985f6f667cfSStefano Zampini PetscReal infty = PETSC_MAX_REAL; 986862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 98708122e43SStefano Zampini PetscBLASInt B_N; 988aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 98908122e43SStefano Zampini 990862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 991ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 992f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 993f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 9949ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 995aff50787SStefano Zampini PetscInt j,k; 996aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 997aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 998aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 99908122e43SStefano Zampini } 100008122e43SStefano Zampini for (j=0;j<subset_size;j++) { 1001aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 1002aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 1003aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 1004aff50787SStefano Zampini } 100508122e43SStefano Zampini } 100608122e43SStefano Zampini } else { 100708122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 100808122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 100908122e43SStefano Zampini } 10108bec7fa6SStefano Zampini } else { 1011f6f667cfSStefano Zampini S = Sarray + cumarray; 1012f6f667cfSStefano Zampini St = Starray + cumarray; 10138bec7fa6SStefano Zampini } 101408122e43SStefano Zampini 1015aff50787SStefano Zampini /* see if we can save some work */ 1016aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { 1017aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 1018aff50787SStefano Zampini } 1019aff50787SStefano Zampini 1020aff50787SStefano Zampini if (same_data) { /* there's no need of constraints here, deluxe scaling is enough */ 1021aff50787SStefano Zampini B_neigs = 0; 1022aff50787SStefano Zampini } else { 10239ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 102408122e43SStefano Zampini PetscBLASInt B_itype = 1; 1025f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 10264c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 10279552c7c7SStefano Zampini PetscInt nmin_s; 102808122e43SStefano Zampini 1029fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 10308bec7fa6SStefano 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]]); 1031fd14bc51SStefano Zampini } 1032d16cbb6bSStefano Zampini 103308122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1034d16cbb6bSStefano Zampini if (thresh > 1.+PETSC_SMALL) { 1035d16cbb6bSStefano Zampini 1036d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 103708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1038f6f667cfSStefano 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)); 103908122e43SStefano Zampini #else 1040f6f667cfSStefano 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)); 104108122e43SStefano Zampini #endif 1042d16cbb6bSStefano Zampini } else { 1043d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 1044d16cbb6bSStefano Zampini B_IL = 1; 1045d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1046d16cbb6bSStefano 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)); 1047d16cbb6bSStefano Zampini #else 1048d16cbb6bSStefano 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)); 1049d16cbb6bSStefano Zampini #endif 1050d16cbb6bSStefano Zampini } 105108122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 105208122e43SStefano Zampini if (B_ierr) { 105308122e43SStefano Zampini if (B_ierr < 0 ) { 105408122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 105508122e43SStefano Zampini } else if (B_ierr <= B_N) { 105608122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 105708122e43SStefano Zampini } else { 10589552c7c7SStefano 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); 105908122e43SStefano Zampini } 106008122e43SStefano Zampini } 106108122e43SStefano Zampini 106208122e43SStefano Zampini if (B_neigs > nmax) { 1063fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1064fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 1065fd14bc51SStefano Zampini } 1066f6f667cfSStefano Zampini eigs_start = B_neigs -nmax; 106708122e43SStefano Zampini B_neigs = nmax; 106808122e43SStefano Zampini } 106908122e43SStefano Zampini 10709552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 10719552c7c7SStefano Zampini if (B_neigs < nmin_s) { 107208122e43SStefano Zampini PetscBLASInt B_neigs2; 107308122e43SStefano Zampini 1074f6f667cfSStefano Zampini B_IU = B_N - B_neigs; 1075f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 1076fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1077fd14bc51SStefano 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); 1078fd14bc51SStefano Zampini } 10799ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 108008122e43SStefano Zampini PetscInt j; 108108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 108208122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 108308122e43SStefano Zampini } 108408122e43SStefano Zampini for (j=0;j<subset_size;j++) { 108508122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 108608122e43SStefano Zampini } 108708122e43SStefano Zampini } else { 108808122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 108908122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 109008122e43SStefano Zampini } 109108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 109208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1093f6f667cfSStefano 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)); 109408122e43SStefano Zampini #else 1095f6f667cfSStefano 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)); 109608122e43SStefano Zampini #endif 109708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 109808122e43SStefano Zampini B_neigs += B_neigs2; 109908122e43SStefano Zampini } 110008122e43SStefano Zampini if (B_ierr) { 110108122e43SStefano Zampini if (B_ierr < 0 ) { 110208122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 110308122e43SStefano Zampini } else if (B_ierr <= B_N) { 110408122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 110508122e43SStefano Zampini } else { 11069552c7c7SStefano 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); 110708122e43SStefano Zampini } 110808122e43SStefano Zampini } 1109fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1110ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 111108122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 111208122e43SStefano Zampini if (eigs[j] == 0.0) { 1113ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 111408122e43SStefano Zampini } else { 1115ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 1116fd14bc51SStefano Zampini } 111708122e43SStefano Zampini } 111808122e43SStefano Zampini } 111908122e43SStefano Zampini } else { 112008122e43SStefano Zampini /* TODO */ 112108122e43SStefano Zampini } 1122aff50787SStefano Zampini } 11238bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 11248bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 11259162d606SStefano Zampini if (B_neigs) { 11269162d606SStefano 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); 1127fd14bc51SStefano Zampini 1128fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 11299552c7c7SStefano Zampini PetscInt ii; 11309552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 1131ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 11329552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 1133ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1134ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1135ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1136ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 1137ac47001eSStefano Zampini #else 1138ac47001eSStefano 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); 1139ac47001eSStefano Zampini #endif 11409552c7c7SStefano Zampini } 11419552c7c7SStefano Zampini } 1142fd14bc51SStefano Zampini } 114308122e43SStefano Zampini #if 0 11449162d606SStefano Zampini for (j=0;j<B_neigs;j++) { 114508122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 114608122e43SStefano Zampini PetscScalar norm; 114708122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 11489162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size, 11499162d606SStefano Zampini &Blas_one,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 115008122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 115108122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 115208122e43SStefano Zampini } else { 115308122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 115408122e43SStefano Zampini } 11559162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 1156b1b3d7a2SStefano Zampini } 1157b1b3d7a2SStefano Zampini #endif 11589162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 11599162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 11609162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 11619162d606SStefano Zampini cum++; 116208122e43SStefano Zampini } 116308122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 116408122e43SStefano Zampini /* shift for next computation */ 116508122e43SStefano Zampini cumarray += subset_size*subset_size; 116608122e43SStefano Zampini } 1167fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1168fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1169fd14bc51SStefano Zampini } 117008122e43SStefano Zampini 117108122e43SStefano Zampini if (mss) { 117208122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 117308122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 1174f6f667cfSStefano Zampini /* destroy matrices (junk) */ 1175f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 1176f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 117708122e43SStefano Zampini } 1178f6f667cfSStefano Zampini if (allocated_S_St) { 1179f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 1180f6f667cfSStefano Zampini } 1181f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 118208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 118308122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 118408122e43SStefano Zampini #endif 118508122e43SStefano Zampini if (pcbddc->dbg_flag) { 11861b968477SStefano Zampini PetscInt maxneigs_r; 118708122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 11889b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 118908122e43SStefano Zampini } 119008122e43SStefano Zampini PetscFunctionReturn(0); 119108122e43SStefano Zampini } 1192b1b3d7a2SStefano Zampini 1193674ae819SStefano Zampini #undef __FUNCT__ 1194c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 1195c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 1196c8587f34SStefano Zampini { 1197c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 11988629588bSStefano Zampini PetscScalar *coarse_submat_vals; 1199c8587f34SStefano Zampini PetscErrorCode ierr; 1200c8587f34SStefano Zampini 1201c8587f34SStefano Zampini PetscFunctionBegin; 1202f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 12035e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 1204c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 1205c8587f34SStefano Zampini 1206684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 12070fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 1208684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 1209c8587f34SStefano Zampini 1210c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 1211b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 1212c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 1213c8587f34SStefano Zampini } 1214c8587f34SStefano Zampini 12158629588bSStefano Zampini /* 12168629588bSStefano Zampini Setup local correction and local part of coarse basis. 12178629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 12188629588bSStefano Zampini */ 121947f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 12208629588bSStefano Zampini 12218629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 12228629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 12238629588bSStefano Zampini 12248629588bSStefano Zampini /* free */ 12258629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 1226c8587f34SStefano Zampini PetscFunctionReturn(0); 1227c8587f34SStefano Zampini } 1228c8587f34SStefano Zampini 1229c8587f34SStefano Zampini #undef __FUNCT__ 1230674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 1231674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 1232674ae819SStefano Zampini { 1233674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1234674ae819SStefano Zampini PetscErrorCode ierr; 1235674ae819SStefano Zampini 1236674ae819SStefano Zampini PetscFunctionBegin; 1237674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1238674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 123930368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 1240674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 1241674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1242785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 1243674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1244f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1245f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1246785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 124763602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 124863602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 1249674ae819SStefano Zampini PetscFunctionReturn(0); 1250674ae819SStefano Zampini } 1251674ae819SStefano Zampini 1252674ae819SStefano Zampini #undef __FUNCT__ 1253674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 1254674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 1255674ae819SStefano Zampini { 1256674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12574f1b2e48SStefano Zampini PetscInt i; 1258674ae819SStefano Zampini PetscErrorCode ierr; 1259674ae819SStefano Zampini 1260674ae819SStefano Zampini PetscFunctionBegin; 1261b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 1262674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 1263674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1264674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 12654f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 12664f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 12674f1b2e48SStefano Zampini } 12684f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1269b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1270674ae819SStefano Zampini PetscFunctionReturn(0); 1271674ae819SStefano Zampini } 1272674ae819SStefano Zampini 1273674ae819SStefano Zampini #undef __FUNCT__ 1274674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1275674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1276674ae819SStefano Zampini { 1277674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1278674ae819SStefano Zampini PetscErrorCode ierr; 1279674ae819SStefano Zampini 1280674ae819SStefano Zampini PetscFunctionBegin; 1281674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 128258da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 1283ca92afb2SStefano Zampini PetscScalar *array; 128406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 128506656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 128658da7f69SStefano Zampini } 1287674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1288674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 128915aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 129015aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1291674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1292674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1293674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 129406656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1295674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1296674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 12978ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1298674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1299674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1300674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1301f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1302f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1303f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1304f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1305727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 13060e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1307f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 130870cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 13096e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 131081d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 13110369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 13128b9f24d4SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 13134f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 13148b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 1315ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 1316ca92afb2SStefano Zampini PetscInt i; 1317ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1318ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1319ca92afb2SStefano Zampini } 1320ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1321ca92afb2SStefano Zampini } 13224f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1323674ae819SStefano Zampini PetscFunctionReturn(0); 1324674ae819SStefano Zampini } 1325674ae819SStefano Zampini 1326674ae819SStefano Zampini #undef __FUNCT__ 1327f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1328f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 13296bfb1811SStefano Zampini { 13306bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 13316bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 13326bfb1811SStefano Zampini VecType impVecType; 13334f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 13346bfb1811SStefano Zampini PetscErrorCode ierr; 13356bfb1811SStefano Zampini 13366bfb1811SStefano Zampini PetscFunctionBegin; 1337f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 1338019a44ceSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1339f4ddd8eeSStefano Zampini } 1340e7b262bdSStefano Zampini /* get sizes */ 13414f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1342b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 13436bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1344e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1345e7b262bdSStefano Zampini /* R nodes */ 1346e7b262bdSStefano Zampini old_size = -1; 1347e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1348e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1349e7b262bdSStefano Zampini } 1350e7b262bdSStefano Zampini if (n_R != old_size) { 1351e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1352e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 13536bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 13546bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 13556bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 13566bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1357e7b262bdSStefano Zampini } 1358e7b262bdSStefano Zampini /* local primal dofs */ 1359e7b262bdSStefano Zampini old_size = -1; 1360e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1361e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1362e7b262bdSStefano Zampini } 1363e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1364e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 136583b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1366e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 13676bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1368e7b262bdSStefano Zampini } 1369e7b262bdSStefano Zampini /* local explicit constraints */ 1370e7b262bdSStefano Zampini old_size = -1; 1371e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1372e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1373e7b262bdSStefano Zampini } 1374e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1375e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 137683b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 137783b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 137883b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 137983b7ccabSStefano Zampini } 13806bfb1811SStefano Zampini PetscFunctionReturn(0); 13816bfb1811SStefano Zampini } 13826bfb1811SStefano Zampini 13836bfb1811SStefano Zampini #undef __FUNCT__ 138447f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 138547f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 138688ebb749SStefano Zampini { 138725084f0cSStefano Zampini PetscErrorCode ierr; 138825084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 138988ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 139088ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1391d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 139225084f0cSStefano Zampini /* submatrices of local problem */ 139380677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 1394019a44ceSStefano Zampini /* submatrices of benign trick */ 1395d16cbb6bSStefano Zampini Mat B0_V = NULL; 139606656605SStefano Zampini /* submatrices of local coarse problem */ 139706656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 139825084f0cSStefano Zampini /* working matrices */ 139906656605SStefano Zampini Mat C_CR; 140025084f0cSStefano Zampini /* additional working stuff */ 140106656605SStefano Zampini PC pc_R; 14024f1b2e48SStefano Zampini Mat F; 1403a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 140406656605SStefano Zampini 140525084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 140606656605SStefano Zampini PetscScalar *work; 140706656605SStefano Zampini PetscInt *idx_V_B; 1408ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 140906656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1410ffd830a3SStefano Zampini 141125084f0cSStefano Zampini /* some shortcuts to scalars */ 141206656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 141388ebb749SStefano Zampini 141488ebb749SStefano Zampini PetscFunctionBegin; 1415ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal && pcbddc->benign_n) { 1416ffd830a3SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-symmetric primal basis computation with benign trick not yet implemented"); 1417ffd830a3SStefano Zampini } 1418ffd830a3SStefano Zampini 1419ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 1420b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 14214f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 1422b371cd4fSStefano Zampini n_B = pcis->n_B; 1423b371cd4fSStefano Zampini n_D = pcis->n - n_B; 142488ebb749SStefano Zampini n_R = pcis->n - n_vertices; 142588ebb749SStefano Zampini 142688ebb749SStefano Zampini /* vertices in boundary numbering */ 1427785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 14280e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 142988ebb749SStefano Zampini if (i != n_vertices) { 143022d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 143188ebb749SStefano Zampini } 143288ebb749SStefano Zampini 143306656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1434019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 143506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 143606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 143706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 143806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 143906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 144006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 144106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 144206656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 144306656605SStefano Zampini 144406656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 144506656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 144606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 144706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 144806656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 1449ffd830a3SStefano Zampini lda_rhs = n_R; 1450a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 145106656605SStefano Zampini if (isLU || isILU || isCHOL) { 145206656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1453df4d28bfSStefano Zampini } else if (sub_schurs->reuse_solver) { 1454df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1455d62866d3SStefano Zampini MatFactorType type; 1456d62866d3SStefano Zampini 1457df4d28bfSStefano Zampini F = reuse_solver->F; 14586816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1459d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 1460ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 1461df4d28bfSStefano Zampini need_benign_correction = !!reuse_solver->benign_n; 146206656605SStefano Zampini } else { 146306656605SStefano Zampini F = NULL; 146406656605SStefano Zampini } 146506656605SStefano Zampini 1466ffd830a3SStefano Zampini /* allocate workspace */ 1467ffd830a3SStefano Zampini n = 0; 1468ffd830a3SStefano Zampini if (n_constraints) { 1469ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 1470ffd830a3SStefano Zampini } 1471ffd830a3SStefano Zampini if (n_vertices) { 1472ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 1473ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 1474ffd830a3SStefano Zampini } 1475ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1476ffd830a3SStefano Zampini 147788ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 147888ebb749SStefano Zampini if (n_constraints) { 147906656605SStefano Zampini Mat M1,M2,M3; 148080677318SStefano Zampini Mat auxmat; 148106656605SStefano Zampini IS is_aux; 148280677318SStefano Zampini PetscScalar *array,*array2; 148306656605SStefano Zampini 1484f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 148580677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 148688ebb749SStefano Zampini 148725084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 148825084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 14898ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 149080677318SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&auxmat);CHKERRQ(ierr); 149188ebb749SStefano Zampini 149280677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 149380677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 1494ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 149588ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 149606656605SStefano Zampini const PetscScalar *row_cmat_values; 149706656605SStefano Zampini const PetscInt *row_cmat_indices; 149806656605SStefano Zampini PetscInt size_of_constraint,j; 149988ebb749SStefano Zampini 150006656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 150106656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1502ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 150306656605SStefano Zampini } 150406656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 150506656605SStefano Zampini } 1506ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 150706656605SStefano Zampini if (F) { 150806656605SStefano Zampini Mat B; 150906656605SStefano Zampini 1510ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 1511a3df083aSStefano Zampini if (need_benign_correction) { 1512a3df083aSStefano Zampini PetscScalar *marr; 1513df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1514a3df083aSStefano Zampini 1515a3df083aSStefano Zampini ierr = MatDenseGetArray(B,&marr);CHKERRQ(ierr); 1516a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1517a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1518df4d28bfSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE);CHKERRQ(ierr); 1519a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1520a3df083aSStefano Zampini } 1521a3df083aSStefano Zampini ierr = MatDenseRestoreArray(B,&marr);CHKERRQ(ierr); 1522a3df083aSStefano Zampini } 152380677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 1524a3df083aSStefano Zampini if (need_benign_correction) { 1525a3df083aSStefano Zampini PetscScalar *marr; 1526df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1527a3df083aSStefano Zampini 1528a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1529a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1530a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1531df4d28bfSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE);CHKERRQ(ierr); 1532a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1533a3df083aSStefano Zampini } 1534a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1535a3df083aSStefano Zampini } 153606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 153706656605SStefano Zampini } else { 153880677318SStefano Zampini PetscScalar *marr; 153980677318SStefano Zampini 154080677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 154106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 1542ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1543ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 154406656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 154506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 154606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 154706656605SStefano Zampini } 154880677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 154906656605SStefano Zampini } 155080677318SStefano Zampini if (!pcbddc->switch_static) { 155180677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 155280677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 155380677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 155480677318SStefano Zampini for (i=0;i<n_constraints;i++) { 1555ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 155680677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 155780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155980677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 156080677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 156180677318SStefano Zampini } 156280677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 156380677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 156480677318SStefano Zampini ierr = MatMatMult(auxmat,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 156580677318SStefano Zampini } else { 1566ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1567ffd830a3SStefano Zampini IS dummy; 1568ffd830a3SStefano Zampini 1569ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 1570ffd830a3SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,dummy,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 1571ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1572ffd830a3SStefano Zampini } else { 157380677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 157480677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 1575ffd830a3SStefano Zampini } 157625084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 157780677318SStefano Zampini } 157880677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 157980677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 158080677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 158106656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 158206656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 158380677318SStefano Zampini if (isCHOL) { 158480677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 158580677318SStefano Zampini } else { 158625084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 158780677318SStefano Zampini } 158880677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 158906656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 159025084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 159125084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 159225084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 159380677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 159480677318SStefano Zampini ierr = MatMatMult(M1,auxmat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 159580677318SStefano Zampini ierr = MatDestroy(&auxmat);CHKERRQ(ierr); 159606656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 159706656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1598f4ddd8eeSStefano Zampini } 159988ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 16004f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1601d16cbb6bSStefano Zampini IS dummy; 1602d16cbb6bSStefano Zampini Mat B0_R; 1603d16cbb6bSStefano Zampini PetscReal norm; 1604d16cbb6bSStefano Zampini 16054f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 16064f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&B0_R);CHKERRQ(ierr); 1607d16cbb6bSStefano Zampini ierr = MatNorm(B0_R,NORM_INFINITY,&norm);CHKERRQ(ierr); 1608d16cbb6bSStefano Zampini if (norm > PETSC_SMALL) { 1609d16cbb6bSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! ||B0_R|| = %f (should be numerically 0.)",norm); 1610d16cbb6bSStefano Zampini } 1611d16cbb6bSStefano Zampini ierr = MatDestroy(&B0_R);CHKERRQ(ierr); 1612d16cbb6bSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1613d16cbb6bSStefano Zampini } 1614d16cbb6bSStefano Zampini 161588ebb749SStefano Zampini if (n_vertices) { 161606656605SStefano Zampini IS is_aux; 16173a50541eSStefano Zampini 1618df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 16196816873aSStefano Zampini IS tis; 16206816873aSStefano Zampini 16216816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 16226816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 16236816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 16246816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 16256816873aSStefano Zampini } else { 16263a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 16276816873aSStefano Zampini } 16289577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 16299577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 163004708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 16314f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1632019a44ceSStefano Zampini IS dummy; 1633019a44ceSStefano Zampini 16344f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 16354f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,is_aux,MAT_INITIAL_MATRIX,&B0_V);CHKERRQ(ierr); 1636019a44ceSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1637019a44ceSStefano Zampini } 163825084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 163988ebb749SStefano Zampini } 164088ebb749SStefano Zampini 164188ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1642f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 164306656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 164406656605SStefano Zampini if (pcbddc->coarse_phi_D) { 164506656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 164606656605SStefano Zampini } 1647f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 164806656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 164906656605SStefano Zampini PetscScalar *marray; 165006656605SStefano Zampini 165106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 165206656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1653f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1654f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1655f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1656f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1657f4ddd8eeSStefano Zampini } 1658f4ddd8eeSStefano Zampini } 165906656605SStefano Zampini 1660f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 166106656605SStefano Zampini PetscScalar *marray; 166288ebb749SStefano Zampini 166306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 16648eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 166506656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 166688ebb749SStefano Zampini } 16673301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 166806656605SStefano Zampini n *= 2; 166988ebb749SStefano Zampini } 167006656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 167106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 167206656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 16738eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 167406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 167506656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 167688ebb749SStefano Zampini } 16773301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 167806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 16798eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 168006656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 168106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 168288ebb749SStefano Zampini } 168388ebb749SStefano Zampini } else { 1684c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1685c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 16861b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1687c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1688c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1689c0553b1fSStefano Zampini } 169088ebb749SStefano Zampini } 169106656605SStefano Zampini } 1692019a44ceSStefano Zampini 169306656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 16944f1b2e48SStefano Zampini p0_lidx_I = NULL; 16954f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1696d12edf2fSStefano Zampini const PetscInt *idxs; 1697d12edf2fSStefano Zampini 1698d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 16994f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 17004f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 17014f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 17024f1b2e48SStefano Zampini } 1703d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1704d12edf2fSStefano Zampini } 1705d16cbb6bSStefano Zampini 170606656605SStefano Zampini /* vertices */ 170706656605SStefano Zampini if (n_vertices) { 170816f15bc4SStefano Zampini 1709ffd830a3SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 171004708bb6SStefano Zampini 171116f15bc4SStefano Zampini if (n_R) { 171214393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 171306656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 171416f15bc4SStefano Zampini PetscScalar *x,*y; 171504708bb6SStefano Zampini PetscBool isseqaij; 171606656605SStefano Zampini 171721eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 171814393ed6SStefano Zampini if (need_benign_correction) { 171914393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 172014393ed6SStefano Zampini IS is_p0; 172114393ed6SStefano Zampini PetscInt *idxs_p0,n; 172214393ed6SStefano Zampini 172314393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 172414393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 172514393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 172614393ed6SStefano Zampini if (n != pcbddc->benign_n) { 172714393ed6SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in R numbering for benign p0! %d != %d\n",n,pcbddc->benign_n); 172814393ed6SStefano Zampini } 172914393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 173014393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 173114393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 173214393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 173314393ed6SStefano Zampini } 173414393ed6SStefano Zampini 1735ffd830a3SStefano Zampini if (lda_rhs == n_R) { 1736ffd830a3SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 1737ffd830a3SStefano Zampini } else { 1738ca92afb2SStefano Zampini PetscScalar *av,*array; 1739ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 1740ca92afb2SStefano Zampini PetscInt n; 1741ca92afb2SStefano Zampini PetscBool flg_row; 1742ffd830a3SStefano Zampini 1743ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 1744ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 1745ca92afb2SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 1746ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1747ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 1748ca92afb2SStefano Zampini for (i=0;i<n;i++) { 1749ca92afb2SStefano Zampini PetscInt j; 1750ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 1751ffd830a3SStefano Zampini } 1752ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1753ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 1754ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 1755ffd830a3SStefano Zampini } 1756ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 175714393ed6SStefano Zampini if (F) { 1758a3df083aSStefano Zampini if (need_benign_correction) { 1759df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1760a3df083aSStefano Zampini PetscScalar *marr; 1761a3df083aSStefano Zampini 1762a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 176314393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 176414393ed6SStefano Zampini 176514393ed6SStefano Zampini | 0 0 0 | (V) 176614393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 176714393ed6SStefano Zampini | 0 0 -1 | (p0) 176814393ed6SStefano Zampini 176914393ed6SStefano Zampini */ 1770df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 177114393ed6SStefano Zampini const PetscScalar *vals; 177214393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 177314393ed6SStefano Zampini PetscInt n,j,nz; 177414393ed6SStefano Zampini 1775df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1776df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 177714393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 177814393ed6SStefano Zampini for (j=0;j<n;j++) { 177914393ed6SStefano Zampini PetscScalar val = vals[j]; 178014393ed6SStefano Zampini PetscInt k,col = idxs[j]; 178114393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 178214393ed6SStefano Zampini } 178314393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 1784df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 178514393ed6SStefano Zampini } 178614393ed6SStefano Zampini /* need to correct the rhs */ 1787a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 1788a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1789df4d28bfSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE);CHKERRQ(ierr); 1790a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1791a3df083aSStefano Zampini } 1792a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 1793a3df083aSStefano Zampini } 179406656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 179514393ed6SStefano Zampini /* need to correct the solution */ 1796a3df083aSStefano Zampini if (need_benign_correction) { 1797df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 1798a3df083aSStefano Zampini PetscScalar *marr; 1799a3df083aSStefano Zampini 1800a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 1801a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 1802a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1803df4d28bfSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE);CHKERRQ(ierr); 1804a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1805a3df083aSStefano Zampini } 1806a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 1807a3df083aSStefano Zampini } 180806656605SStefano Zampini } else { 180906656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 181006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 1811ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 1812ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 181306656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 181406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 181506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 181606656605SStefano Zampini } 181706656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 181806656605SStefano Zampini } 181980677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 1820ffd830a3SStefano Zampini /* S_VV and S_CV */ 182106656605SStefano Zampini if (n_constraints) { 182206656605SStefano Zampini Mat B; 182380677318SStefano Zampini 1824ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 182580677318SStefano Zampini for (i=0;i<n_vertices;i++) { 1826ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1827ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 182880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 182980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 183080677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 183180677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 183280677318SStefano Zampini } 1833ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 183480677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 183580677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1836ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 183780677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 183806656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 1839ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 1840ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 184106656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 184206656605SStefano Zampini } 184304708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 184404708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 184504708bb6SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 184604708bb6SStefano Zampini } 1847ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1848ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 1849ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 1850ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 1851ffd830a3SStefano Zampini } 185206656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 185314393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 185414393ed6SStefano Zampini if (need_benign_correction) { 1855df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 185614393ed6SStefano Zampini PetscScalar *marr,*sums; 185714393ed6SStefano Zampini 185814393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 185914393ed6SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr); 1860df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 186114393ed6SStefano Zampini const PetscScalar *vals; 186214393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 186314393ed6SStefano Zampini PetscInt n,j,nz; 186414393ed6SStefano Zampini 1865df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1866df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 186714393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 186814393ed6SStefano Zampini PetscInt k; 186914393ed6SStefano Zampini sums[j] = 0.; 187014393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 187114393ed6SStefano Zampini } 187214393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 187314393ed6SStefano Zampini for (j=0;j<n;j++) { 187414393ed6SStefano Zampini PetscScalar val = vals[j]; 187514393ed6SStefano Zampini PetscInt k; 187614393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 187714393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 187814393ed6SStefano Zampini } 187914393ed6SStefano Zampini } 188014393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 1881df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 188214393ed6SStefano Zampini } 188314393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 188414393ed6SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr); 188514393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 188614393ed6SStefano Zampini } 188780677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 188806656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 188906656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 189006656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 189106656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 189206656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 189306656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 189406656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1895d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 1896019a44ceSStefano Zampini } else { 1897d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1898d16cbb6bSStefano Zampini } 18994f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1900019a44ceSStefano Zampini const PetscScalar *vals; 1901019a44ceSStefano Zampini const PetscInt *idxs; 19024f1b2e48SStefano Zampini PetscInt n,j,primal_idx; 1903019a44ceSStefano Zampini 19044f1b2e48SStefano Zampini ierr = MatGetRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 19054f1b2e48SStefano Zampini primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + i; 1906d16cbb6bSStefano Zampini for (j=0;j<n;j++) { 19074f1b2e48SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+idxs[j]] = vals[j]; 19084f1b2e48SStefano Zampini coarse_submat_vals[idxs[j]*pcbddc->local_primal_size+primal_idx] = vals[j]; 1909019a44ceSStefano Zampini } 19104f1b2e48SStefano Zampini ierr = MatRestoreRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 191116f15bc4SStefano Zampini } 191221eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 1913d16cbb6bSStefano Zampini 191406656605SStefano Zampini /* coarse basis functions */ 191506656605SStefano Zampini for (i=0;i<n_vertices;i++) { 191616f15bc4SStefano Zampini PetscScalar *y; 191716f15bc4SStefano Zampini 1918ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 191906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 192006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 192106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 192206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 192306656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 192406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 192506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 192606656605SStefano Zampini 192706656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 19284f1b2e48SStefano Zampini PetscInt j; 19294f1b2e48SStefano Zampini 193006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 193106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 193206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 193306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 193406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 19354f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 193606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 193706656605SStefano Zampini } 193806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 193906656605SStefano Zampini } 194004708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 194104708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 194206656605SStefano Zampini } 194306656605SStefano Zampini 194406656605SStefano Zampini if (n_constraints) { 194506656605SStefano Zampini Mat B; 194606656605SStefano Zampini 1947ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 194806656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 194980677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 195006656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 195106656605SStefano Zampini if (n_vertices) { 195280677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 195380677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 195480677318SStefano Zampini } else { 195580677318SStefano Zampini Mat S_VCt; 195680677318SStefano Zampini 1957ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1958ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1959ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B);CHKERRQ(ierr); 1960ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 1961ffd830a3SStefano Zampini } 196280677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 196380677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 196480677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 196580677318SStefano Zampini } 196606656605SStefano Zampini } 196706656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 196806656605SStefano Zampini /* coarse basis functions */ 196906656605SStefano Zampini for (i=0;i<n_constraints;i++) { 197006656605SStefano Zampini PetscScalar *y; 197106656605SStefano Zampini 1972ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 197306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 197406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 197506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 197606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 197706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 197806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 197906656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 19804f1b2e48SStefano Zampini PetscInt j; 19814f1b2e48SStefano Zampini 198206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 198306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 198406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 198506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 198606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 19874f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 198806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 198906656605SStefano Zampini } 199006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 199106656605SStefano Zampini } 199206656605SStefano Zampini } 199380677318SStefano Zampini if (n_constraints) { 199480677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 199580677318SStefano Zampini } 19964f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 1997019a44ceSStefano Zampini ierr = MatDestroy(&B0_V);CHKERRQ(ierr); 1998019a44ceSStefano Zampini 199906656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 20003301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 2001ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 2002ffd830a3SStefano Zampini PetscScalar *marray; 200306656605SStefano Zampini 200406656605SStefano Zampini if (n_constraints) { 2005ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 200606656605SStefano Zampini 2007ffd830a3SStefano Zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 200806656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 2009ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 201016f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 201106656605SStefano Zampini if (n_vertices) { 2012ffd830a3SStefano Zampini Mat S_VCT; 201306656605SStefano Zampini 201406656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 2015ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 201616f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 201706656605SStefano Zampini } 2018ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 201906656605SStefano Zampini } 202016f15bc4SStefano Zampini if (n_vertices && n_R) { 2021ffd830a3SStefano Zampini PetscScalar *av,*marray; 2022ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 2023ffd830a3SStefano Zampini PetscInt n; 2024ffd830a3SStefano Zampini PetscBool flg_row; 202506656605SStefano Zampini 2026ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 2027ffd830a3SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 2028ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2029ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 2030ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2031ffd830a3SStefano Zampini for (i=0;i<n;i++) { 2032ffd830a3SStefano Zampini PetscInt j; 2033ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 2034ffd830a3SStefano Zampini } 2035ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2036ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 2037ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 203806656605SStefano Zampini } 203906656605SStefano Zampini 2040ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 2041ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 2042ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 2043ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 2044ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 204506656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 204606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 204706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 204806656605SStefano Zampini } 2049ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 2050ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 2051ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 2052ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 2053ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 2054ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 2055ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 2056ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 205706656605SStefano Zampini } 2058ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 205906656605SStefano Zampini /* coarse basis functions */ 206006656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 206106656605SStefano Zampini PetscScalar *y; 206206656605SStefano Zampini 2063ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 206406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 206506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 206606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 206706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 206806656605SStefano Zampini if (i<n_vertices) { 206906656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 207006656605SStefano Zampini } 207106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 207206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 207306656605SStefano Zampini 207406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 207506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 207606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 207706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 207806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 207906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 208006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 208106656605SStefano Zampini } 208206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 208306656605SStefano Zampini } 2084ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 2085ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 208606656605SStefano Zampini } 2087d62866d3SStefano Zampini /* free memory */ 208888ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 208906656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 209006656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 209106656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 209206656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 2093d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2094d62866d3SStefano Zampini if (n_vertices) { 2095d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 2096d62866d3SStefano Zampini } 2097d62866d3SStefano Zampini if (n_constraints) { 2098d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 2099d62866d3SStefano Zampini } 210088ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 210188ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 210288ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 2103d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 210488ebb749SStefano Zampini Mat coarse_sub_mat; 210525084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 210688ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 210788ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 210888ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 21098bec7fa6SStefano Zampini Mat C_B,CPHI; 21108bec7fa6SStefano Zampini IS is_dummy; 21118bec7fa6SStefano Zampini Vec mones; 211288ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 211388ebb749SStefano Zampini PetscReal real_value; 211488ebb749SStefano Zampini 2115a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 2116a3df083aSStefano Zampini Mat A; 2117a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 2118a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 2119a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 2120a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 2121a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2122a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 2123a3df083aSStefano Zampini } else { 212488ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 212588ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 212688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 212788ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2128a3df083aSStefano Zampini } 212988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 213088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 2131ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 213288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 213388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 213488ebb749SStefano Zampini } 213588ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 213688ebb749SStefano Zampini 213725084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 21383301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 213925084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2140ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 214188ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 214288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 214388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 214488ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 214588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 214688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 214788ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 214888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 214988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 215088ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 215188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 215288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 215388ebb749SStefano Zampini } else { 215488ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 215588ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 215688ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 215788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 215888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 215988ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 216088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 216188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 216288ebb749SStefano Zampini } 216388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 216488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 216588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 216688ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 21674f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2168d12edf2fSStefano Zampini Mat B0_I,B0_B,B0_BPHI,B0_IPHI; 2169d12edf2fSStefano Zampini PetscScalar *data,*data2; 21704f1b2e48SStefano Zampini PetscInt j; 2171d12edf2fSStefano Zampini 21724f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 21734f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B); 21744f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_I_local,MAT_INITIAL_MATRIX,&B0_I); 2175d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 2176d12edf2fSStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_REUSE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 2177d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 2178d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 21794f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 21804f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 2181d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 21824f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 21834f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 21844f1b2e48SStefano Zampini } 2185d12edf2fSStefano Zampini } 2186d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 2187d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 2188d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 2189d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2190d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 2191d12edf2fSStefano Zampini ierr = MatMatMult(B0_I,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&B0_IPHI);CHKERRQ(ierr); 2192d12edf2fSStefano Zampini ierr = MatDestroy(&B0_I);CHKERRQ(ierr); 2193d12edf2fSStefano Zampini ierr = MatNorm(B0_IPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2194d12edf2fSStefano Zampini ierr = MatDestroy(&B0_IPHI);CHKERRQ(ierr); 2195d12edf2fSStefano Zampini } 2196d12edf2fSStefano Zampini #if 0 2197d12edf2fSStefano Zampini { 2198d12edf2fSStefano Zampini PetscViewer viewer; 2199d12edf2fSStefano Zampini char filename[256]; 2200ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 2201d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 2202d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2203ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 2204ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 2205ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 2206d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 2207ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 2208ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 2209ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 2210ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 2211ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 2212ffd830a3SStefano Zampini } 2213ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 2214ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 2215ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 2216ffd830a3SStefano Zampini } 2217ffd830a3SStefano Zampini if (pcbddc->coarse_phi_B) { 2218ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 2219ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 2220ffd830a3SStefano Zampini } 2221d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2222d12edf2fSStefano Zampini } 2223d12edf2fSStefano Zampini #endif 222481d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 22258bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 22261575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 222706656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 22288bec7fa6SStefano Zampini 22298bec7fa6SStefano Zampini /* check constraints */ 22304f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 22318bec7fa6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&is_dummy);CHKERRQ(ierr); 22328bec7fa6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B); 22338bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 22348bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 22358bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 22368bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 22378bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2238bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 2239ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 2240bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2241bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 2242bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 2243bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2244bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 224588ebb749SStefano Zampini } 22468bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 22478bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 22488bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 22498bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 2250d12edf2fSStefano Zampini } 225125084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 225288ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 225388ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 225488ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 225588ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 225688ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 225788ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 225888ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 225988ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 226088ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 226188ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 2262ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 226388ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 226488ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 226588ebb749SStefano Zampini } 226688ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 226788ebb749SStefano Zampini } 22688629588bSStefano Zampini /* get back data */ 22698629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 227088ebb749SStefano Zampini PetscFunctionReturn(0); 227188ebb749SStefano Zampini } 227288ebb749SStefano Zampini 227388ebb749SStefano Zampini #undef __FUNCT__ 2274d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 2275d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 2276aa0d41d4SStefano Zampini { 2277d65f70fdSStefano Zampini Mat *work_mat; 2278d65f70fdSStefano Zampini IS isrow_s,iscol_s; 2279d65f70fdSStefano Zampini PetscBool rsorted,csorted; 2280d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 2281aa0d41d4SStefano Zampini PetscErrorCode ierr; 2282aa0d41d4SStefano Zampini 2283aa0d41d4SStefano Zampini PetscFunctionBegin; 2284d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 2285d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 2286d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 2287d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 2288aa0d41d4SStefano Zampini 2289d65f70fdSStefano Zampini if (!rsorted) { 2290906d46d4SStefano Zampini const PetscInt *idxs; 2291906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 2292aa0d41d4SStefano Zampini 2293d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 2294d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 2295d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2296d65f70fdSStefano Zampini idxs_perm_r[i] = i; 2297aa0d41d4SStefano Zampini } 2298d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 2299d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 2300d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2301d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 2302aa0d41d4SStefano Zampini } 2303d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 2304d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 2305d65f70fdSStefano Zampini } else { 2306d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 2307d65f70fdSStefano Zampini isrow_s = isrow; 2308aa0d41d4SStefano Zampini } 2309906d46d4SStefano Zampini 2310d65f70fdSStefano Zampini if (!csorted) { 2311d65f70fdSStefano Zampini if (isrow == iscol) { 2312d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 2313d65f70fdSStefano Zampini iscol_s = isrow_s; 2314d65f70fdSStefano Zampini } else { 2315d65f70fdSStefano Zampini const PetscInt *idxs; 2316d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 2317906d46d4SStefano Zampini 2318d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 2319d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 2320d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2321d65f70fdSStefano Zampini idxs_perm_c[i] = i; 2322d65f70fdSStefano Zampini } 2323d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 2324d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 2325d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2326d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 2327d65f70fdSStefano Zampini } 2328d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 2329d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 2330d65f70fdSStefano Zampini } 2331d65f70fdSStefano Zampini } else { 2332d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 2333d65f70fdSStefano Zampini iscol_s = iscol; 2334d65f70fdSStefano Zampini } 2335d65f70fdSStefano Zampini 2336d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2337d65f70fdSStefano Zampini 2338d65f70fdSStefano Zampini if (!rsorted || !csorted) { 2339906d46d4SStefano Zampini Mat new_mat; 2340d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 2341906d46d4SStefano Zampini 2342d65f70fdSStefano Zampini if (!rsorted) { 2343d65f70fdSStefano Zampini PetscInt *idxs_r,i; 2344d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 2345d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2346d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 2347906d46d4SStefano Zampini } 2348d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 2349d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 2350d65f70fdSStefano Zampini } else { 2351d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 2352906d46d4SStefano Zampini } 2353d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 2354d65f70fdSStefano Zampini 2355d65f70fdSStefano Zampini if (!csorted) { 2356d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 2357d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 2358d65f70fdSStefano Zampini is_perm_c = is_perm_r; 2359d65f70fdSStefano Zampini } else { 2360d65f70fdSStefano Zampini PetscInt *idxs_c,i; 2361d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 2362d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2363d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 2364d65f70fdSStefano Zampini } 2365d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 2366d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 2367d65f70fdSStefano Zampini } 2368d65f70fdSStefano Zampini } else { 2369d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 2370d65f70fdSStefano Zampini } 2371d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 2372d65f70fdSStefano Zampini 2373d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 2374d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 2375d65f70fdSStefano Zampini work_mat[0] = new_mat; 2376d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 2377d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 2378d65f70fdSStefano Zampini } 2379d65f70fdSStefano Zampini 2380d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 2381d65f70fdSStefano Zampini *B = work_mat[0]; 2382d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 2383d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 2384d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 2385d65f70fdSStefano Zampini PetscFunctionReturn(0); 2386d65f70fdSStefano Zampini } 2387d65f70fdSStefano Zampini 2388d65f70fdSStefano Zampini #undef __FUNCT__ 23895e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 23905e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 2391aa0d41d4SStefano Zampini { 2392aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 23935e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2394d65f70fdSStefano Zampini Mat new_mat; 23955e8657edSStefano Zampini IS is_local,is_global; 2396d65f70fdSStefano Zampini PetscInt local_size; 2397d65f70fdSStefano Zampini PetscBool isseqaij; 2398aa0d41d4SStefano Zampini PetscErrorCode ierr; 2399aa0d41d4SStefano Zampini 2400aa0d41d4SStefano Zampini PetscFunctionBegin; 2401aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 24025e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 24035e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 2404b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 2405aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 2406d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 2407aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 2408906d46d4SStefano Zampini 2409906d46d4SStefano Zampini /* check */ 2410906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2411906d46d4SStefano Zampini Vec x,x_change; 2412906d46d4SStefano Zampini PetscReal error; 2413906d46d4SStefano Zampini 24145e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 2415906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 24165e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 2417e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2418e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2419d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 2420e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2421e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2422906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2423906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2424906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2425906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 2426906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2427906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2428906d46d4SStefano Zampini } 2429906d46d4SStefano Zampini 243022d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 24319b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 243222d5777bSStefano Zampini if (isseqaij) { 24331cf9b237SStefano Zampini Mat M; 24341cf9b237SStefano Zampini 24351cf9b237SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 24361cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 24371cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2438aa0d41d4SStefano Zampini } else { 24391cf9b237SStefano Zampini Mat work_mat,M; 24401cf9b237SStefano Zampini 2441aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 24421cf9b237SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 24431cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 24441cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2445aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 2446aa0d41d4SStefano Zampini } 24473301b35fSStefano Zampini if (matis->A->symmetric_set) { 24483301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 2449e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 24503301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 2451e496cd5dSStefano Zampini #endif 24523301b35fSStefano Zampini } 245345a1bb75SStefano Zampini /* 245445a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2455d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 245645a1bb75SStefano Zampini */ 2457d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 2458aa0d41d4SStefano Zampini PetscFunctionReturn(0); 2459aa0d41d4SStefano Zampini } 2460aa0d41d4SStefano Zampini 2461aa0d41d4SStefano Zampini #undef __FUNCT__ 2462a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 24638ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2464a64d13efSStefano Zampini { 2465a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2466a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2467d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 246853892102SStefano Zampini PetscInt *idx_R_local=NULL; 24693a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 24703a50541eSStefano Zampini PetscInt vbs,bs; 24716816873aSStefano Zampini PetscBT bitmask=NULL; 2472a64d13efSStefano Zampini PetscErrorCode ierr; 2473a64d13efSStefano Zampini 2474a64d13efSStefano Zampini PetscFunctionBegin; 2475b23d619eSStefano Zampini /* 2476b23d619eSStefano Zampini No need to setup local scatters if 2477b23d619eSStefano Zampini - primal space is unchanged 2478b23d619eSStefano Zampini AND 2479b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2480b23d619eSStefano Zampini AND 2481b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2482b23d619eSStefano Zampini */ 2483b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2484f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2485f4ddd8eeSStefano Zampini } 2486f4ddd8eeSStefano Zampini /* destroy old objects */ 2487f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2488f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2489f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2490a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2491b371cd4fSStefano Zampini n_B = pcis->n_B; 2492b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2493b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 24943a50541eSStefano Zampini 2495a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 24966816873aSStefano Zampini 249753892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 2498df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 2499854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2500a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2501a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 25020e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2503a64d13efSStefano Zampini } 2504a64d13efSStefano Zampini 2505a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 25064641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 25076816873aSStefano Zampini idx_R_local[n_R++] = i; 2508a64d13efSStefano Zampini } 2509a64d13efSStefano Zampini } 2510df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 2511df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 25126816873aSStefano Zampini 2513df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2514df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 25156816873aSStefano Zampini } 25163a50541eSStefano Zampini 25173a50541eSStefano Zampini /* Block code */ 25183a50541eSStefano Zampini vbs = 1; 25193a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 25203a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 25213a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 25223a50541eSStefano Zampini PetscInt *vary; 2523df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 2524785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 25253a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2526d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2527d3df7717SStefano 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 */ 25280e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2529d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 25303a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 25313a50541eSStefano Zampini is_blocked = PETSC_FALSE; 25323a50541eSStefano Zampini break; 25333a50541eSStefano Zampini } 25343a50541eSStefano Zampini } 2535d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2536d3df7717SStefano Zampini } else { 2537d3df7717SStefano Zampini /* Verify directly the R set */ 2538d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2539d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2540d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2541d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2542d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2543d3df7717SStefano Zampini break; 2544d3df7717SStefano Zampini } 2545d3df7717SStefano Zampini } 2546d3df7717SStefano Zampini } 2547d3df7717SStefano Zampini } 25483a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 25493a50541eSStefano Zampini vbs = bs; 25503a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 25513a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 25523a50541eSStefano Zampini } 25533a50541eSStefano Zampini } 25543a50541eSStefano Zampini } 25553a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 2556df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 2557df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 255853892102SStefano Zampini 2559df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2560df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 256153892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 2562df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 256353892102SStefano Zampini } else { 25643a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 256553892102SStefano Zampini } 2566a64d13efSStefano Zampini 2567a64d13efSStefano Zampini /* print some info if requested */ 2568a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 2569a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2570a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 25711575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2572a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 2573a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 25744f1b2e48SStefano 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); 2575a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2576a64d13efSStefano Zampini } 2577a64d13efSStefano Zampini 2578a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 2579df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 25806816873aSStefano Zampini IS is_aux1,is_aux2; 25816816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 25826816873aSStefano Zampini 25833a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2584854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 2585854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 2586a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 25874641a718SStefano Zampini for (i=0; i<n_D; i++) { 25884641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 25894641a718SStefano Zampini } 2590a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2591a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 25924641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 25934641a718SStefano Zampini aux_array1[j++] = i; 2594a64d13efSStefano Zampini } 2595a64d13efSStefano Zampini } 2596a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2597a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2598a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 25994641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 26004641a718SStefano Zampini aux_array2[j++] = i; 2601a64d13efSStefano Zampini } 2602a64d13efSStefano Zampini } 2603a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2604a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 2605a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 2606a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2607a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 2608a64d13efSStefano Zampini 26098eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2610785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 2611a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 26124641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 26134641a718SStefano Zampini aux_array1[j++] = i; 2614a64d13efSStefano Zampini } 2615a64d13efSStefano Zampini } 2616a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2617a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 2618a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2619a64d13efSStefano Zampini } 26204641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 26213a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2622d62866d3SStefano Zampini } else { 2623df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 26246816873aSStefano Zampini IS tis; 26256816873aSStefano Zampini PetscInt schur_size; 26266816873aSStefano Zampini 2627df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 26286816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 2629df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 26306816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 26316816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 26326816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 26336816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 26346816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2635d62866d3SStefano Zampini } 2636d62866d3SStefano Zampini } 2637a64d13efSStefano Zampini PetscFunctionReturn(0); 2638a64d13efSStefano Zampini } 2639a64d13efSStefano Zampini 2640304d26faSStefano Zampini 2641304d26faSStefano Zampini #undef __FUNCT__ 2642304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 2643684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 2644304d26faSStefano Zampini { 2645304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2646304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2647304d26faSStefano Zampini PC pc_temp; 2648304d26faSStefano Zampini Mat A_RR; 2649f4ddd8eeSStefano Zampini MatReuse reuse; 2650304d26faSStefano Zampini PetscScalar m_one = -1.0; 2651304d26faSStefano Zampini PetscReal value; 265204708bb6SStefano Zampini PetscInt n_D,n_R; 26539577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 2654304d26faSStefano Zampini PetscErrorCode ierr; 2655e604994aSStefano Zampini /* prefixes stuff */ 2656312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 2657e604994aSStefano Zampini size_t len; 2658304d26faSStefano Zampini 2659304d26faSStefano Zampini PetscFunctionBegin; 2660304d26faSStefano Zampini 2661e604994aSStefano Zampini /* compute prefixes */ 2662e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 2663e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 2664e604994aSStefano Zampini if (!pcbddc->current_level) { 2665e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2666e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2667e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2668e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2669e604994aSStefano Zampini } else { 2670e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 2671312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 2672e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 2673e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 2674312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 2675312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 267634d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 267734d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 2678e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2679e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2680e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 2681e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 2682e604994aSStefano Zampini } 2683e604994aSStefano Zampini 2684304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 2685684f6988SStefano Zampini if (dirichlet) { 2686d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2687a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit && pcbddc->dbg_flag) { 2688a3df083aSStefano Zampini Mat A_IIn; 2689a3df083aSStefano Zampini 2690a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 2691a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 2692a3df083aSStefano Zampini pcis->A_II = A_IIn; 2693a3df083aSStefano Zampini } 26943301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 26953301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 2696964fefecSStefano Zampini } 2697ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 2698964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 2699304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 2700304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 2701304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 2702304d26faSStefano Zampini /* default */ 2703304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 2704e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 27059577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 2706304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 27079577ea80SStefano Zampini if (issbaij) { 27089577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 27099577ea80SStefano Zampini } else { 2710304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 27119577ea80SStefano Zampini } 2712304d26faSStefano Zampini /* Allow user's customization */ 2713304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 2714304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2715304d26faSStefano Zampini } 2716d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 2717df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 2718df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2719d62866d3SStefano Zampini 2720df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 2721d5574798SStefano Zampini } 2722304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2723304d26faSStefano Zampini if (!n_D) { 2724304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 2725304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2726304d26faSStefano Zampini } 2727304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 2728304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 2729304d26faSStefano Zampini /* set ksp_D into pcis data */ 2730304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 2731304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 2732304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 2733684f6988SStefano Zampini } 2734304d26faSStefano Zampini 2735304d26faSStefano Zampini /* NEUMANN PROBLEM */ 2736684f6988SStefano Zampini A_RR = 0; 2737684f6988SStefano Zampini if (neumann) { 2738d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 273904708bb6SStefano Zampini PetscInt ibs,mbs; 274004708bb6SStefano Zampini PetscBool issbaij; 274104708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2742f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 27438ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 2744f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 2745f4ddd8eeSStefano Zampini PetscInt nn_R; 274681d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 2747f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2748f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 2749f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 2750f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 2751f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2752f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2753f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 2754727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 2755f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2756f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2757f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 2758f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 2759f4ddd8eeSStefano Zampini } 2760f4ddd8eeSStefano Zampini } 2761f4ddd8eeSStefano Zampini /* last check */ 2762d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 2763f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2764f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2765f4ddd8eeSStefano Zampini } 2766f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 2767f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2768f4ddd8eeSStefano Zampini } 2769f4ddd8eeSStefano Zampini /* extract A_RR */ 2770af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 2771af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 277204708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 277304708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 277404708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 277504708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 277604708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 2777af732b37SStefano Zampini } else { 277804708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 27796816873aSStefano Zampini } 278004708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 278104708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 278204708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 278304708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 278404708bb6SStefano Zampini } else { 278504708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 278604708bb6SStefano Zampini } 278704708bb6SStefano Zampini } 2788f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 27893301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 27903301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 27916816873aSStefano Zampini } 2792a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit && pcbddc->dbg_flag) { 2793a3df083aSStefano Zampini Mat A_RRn; 2794a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RRn);CHKERRQ(ierr); 2795a3df083aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2796a3df083aSStefano Zampini A_RR = A_RRn; 2797a3df083aSStefano Zampini } 2798f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 2799304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 2800304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 2801304d26faSStefano Zampini /* default */ 2802304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 2803e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 2804304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 28059577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 28069577ea80SStefano Zampini if (issbaij) { 28079577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 28089577ea80SStefano Zampini } else { 2809304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 28109577ea80SStefano Zampini } 2811304d26faSStefano Zampini /* Allow user's customization */ 2812304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 2813304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2814304d26faSStefano Zampini } 2815304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2816304d26faSStefano Zampini if (!n_R) { 2817304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 2818304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2819304d26faSStefano Zampini } 2820df4d28bfSStefano Zampini /* Reuse solver if it is present */ 2821df4d28bfSStefano Zampini if (sub_schurs->reuse_solver) { 2822df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2823d62866d3SStefano Zampini 2824df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 2825d62866d3SStefano Zampini } 2826ffd830a3SStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 2827304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 2828304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 2829684f6988SStefano Zampini } 28306816873aSStefano Zampini /* free Neumann problem's matrix */ 28316816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2832304d26faSStefano Zampini 2833304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 28340fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 2835684f6988SStefano Zampini if (pcbddc->dbg_flag) { 2836684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 28371575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2838684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2839684f6988SStefano Zampini } 2840684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 28410fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 28420fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 28430fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 28440fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 28450fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 2846304d26faSStefano Zampini /* need to be adapted? */ 2847b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2848b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2849b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 2850304d26faSStefano Zampini /* print info */ 2851304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2852e604994aSStefano 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); 2853304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2854304d26faSStefano Zampini } 2855b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 2856298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 2857304d26faSStefano Zampini } 2858684f6988SStefano Zampini } 2859684f6988SStefano Zampini if (neumann) { /* Neumann */ 28606816873aSStefano Zampini ierr = KSPGetOperators(pcbddc->ksp_R,&A_RR,NULL);CHKERRQ(ierr); 28610fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 28620fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 28630fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 28640fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 28650fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 2866304d26faSStefano Zampini /* need to be adapted? */ 2867b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2868b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2869304d26faSStefano Zampini /* print info */ 2870304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2871e604994aSStefano 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); 2872304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2873304d26faSStefano Zampini } 2874b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 2875298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 2876304d26faSStefano Zampini } 28770fccc4e9SStefano Zampini } 2878684f6988SStefano Zampini } 2879304d26faSStefano Zampini PetscFunctionReturn(0); 2880304d26faSStefano Zampini } 2881304d26faSStefano Zampini 2882304d26faSStefano Zampini #undef __FUNCT__ 2883ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 288480677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 2885674ae819SStefano Zampini { 2886674ae819SStefano Zampini PetscErrorCode ierr; 2887674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2888be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2889674ae819SStefano Zampini 2890674ae819SStefano Zampini PetscFunctionBegin; 2891df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 289280677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 289320c7b377SStefano Zampini } 289480677318SStefano Zampini if (!pcbddc->switch_static) { 289580677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 289680677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 289780677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 289820c7b377SStefano Zampini } 2899df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 290080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 290180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 290220c7b377SStefano Zampini } else { 2903df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2904be83ff47SStefano Zampini 2905df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2906df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 290720c7b377SStefano Zampini } 2908be83ff47SStefano Zampini } else { 290980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 291080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 291180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 291280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 291380677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 291480677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 291580677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 291680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 291780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2918674ae819SStefano Zampini } 2919674ae819SStefano Zampini } 2920df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 292180677318SStefano Zampini if (applytranspose) { 292280677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 292380677318SStefano Zampini } else { 292480677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 292580677318SStefano Zampini } 2926be83ff47SStefano Zampini } else { 2927df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2928be83ff47SStefano Zampini 2929be83ff47SStefano Zampini if (applytranspose) { 2930df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 2931be83ff47SStefano Zampini } else { 2932df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 2933be83ff47SStefano Zampini } 2934be83ff47SStefano Zampini } 293580677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 293680677318SStefano Zampini if (!pcbddc->switch_static) { 2937df4d28bfSStefano Zampini if (!sub_schurs->reuse_solver) { 293880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 293980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2940be83ff47SStefano Zampini } else { 2941df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 2942be83ff47SStefano Zampini 2943df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2944df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2945be83ff47SStefano Zampini } 294680677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 294780677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 294880677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 294980677318SStefano Zampini } 295080677318SStefano Zampini } else { 295180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 295280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 295380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 295480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 295580677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 295680677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 295780677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 295880677318SStefano Zampini } 295980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 296080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 296180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 296280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2963674ae819SStefano Zampini } 2964674ae819SStefano Zampini PetscFunctionReturn(0); 2965674ae819SStefano Zampini } 2966674ae819SStefano Zampini 2967dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 2968674ae819SStefano Zampini #undef __FUNCT__ 2969674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 2970dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 2971674ae819SStefano Zampini { 2972674ae819SStefano Zampini PetscErrorCode ierr; 2973674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2974674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 2975674ae819SStefano Zampini const PetscScalar zero = 0.0; 2976674ae819SStefano Zampini 2977674ae819SStefano Zampini PetscFunctionBegin; 2978dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 2979dc359a40SStefano Zampini if (applytranspose) { 2980674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 29818eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 2982dc359a40SStefano Zampini } else { 2983674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 2984674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 298515aaf578SStefano Zampini } 2986efc2fbd9SStefano Zampini 2987efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 29884f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2989efc2fbd9SStefano Zampini PetscScalar *array; 29904f1b2e48SStefano Zampini PetscInt j; 2991efc2fbd9SStefano Zampini 2992efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 29934f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 2994efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2995efc2fbd9SStefano Zampini } 2996efc2fbd9SStefano Zampini 299712edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 299812edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 299912edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 300012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 300112edc857SStefano Zampini 30029f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 300312edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 300412edc857SStefano Zampini if (pcbddc->coarse_ksp) { 300551694757SStefano Zampini Mat coarse_mat; 3006964fefecSStefano Zampini Vec rhs,sol; 300751694757SStefano Zampini MatNullSpace nullsp; 3008964fefecSStefano Zampini 3009964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 3010964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 301151694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 301251694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 301351694757SStefano Zampini if (nullsp) { 301451694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 301551694757SStefano Zampini } 301612edc857SStefano Zampini if (applytranspose) { 3017964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 301812edc857SStefano Zampini } else { 3019964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 302012edc857SStefano Zampini } 302151694757SStefano Zampini if (nullsp) { 302251694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 302351694757SStefano Zampini } 302412edc857SStefano Zampini } 3025674ae819SStefano Zampini 3026674ae819SStefano Zampini /* Local solution on R nodes */ 302780677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 302880677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 30299f00e9b4SStefano Zampini } 3030674ae819SStefano Zampini 30319f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 30329f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 303312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3034674ae819SStefano Zampini 3035674ae819SStefano Zampini /* Sum contributions from two levels */ 3036dc359a40SStefano Zampini if (applytranspose) { 3037dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 3038dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3039dc359a40SStefano Zampini } else { 3040674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 30418eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3042dc359a40SStefano Zampini } 3043efc2fbd9SStefano Zampini /* store p0 */ 30444f1b2e48SStefano Zampini if (pcbddc->benign_n) { 3045efc2fbd9SStefano Zampini PetscScalar *array; 30464f1b2e48SStefano Zampini PetscInt j; 3047efc2fbd9SStefano Zampini 3048efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 30494f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 3050efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 3051efc2fbd9SStefano Zampini } 3052674ae819SStefano Zampini PetscFunctionReturn(0); 3053674ae819SStefano Zampini } 3054674ae819SStefano Zampini 3055674ae819SStefano Zampini #undef __FUNCT__ 3056674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 305712edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 3058674ae819SStefano Zampini { 3059674ae819SStefano Zampini PetscErrorCode ierr; 3060674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 306158da7f69SStefano Zampini PetscScalar *array; 306212edc857SStefano Zampini Vec from,to; 3063674ae819SStefano Zampini 3064674ae819SStefano Zampini PetscFunctionBegin; 306512edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 306612edc857SStefano Zampini from = pcbddc->coarse_vec; 306712edc857SStefano Zampini to = pcbddc->vec1_P; 306812edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 306912edc857SStefano Zampini Vec tvec; 307058da7f69SStefano Zampini 307158da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 307258da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 307312edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 307458da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 307558da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 307658da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 307712edc857SStefano Zampini } 307812edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 307912edc857SStefano Zampini from = pcbddc->vec1_P; 308012edc857SStefano Zampini to = pcbddc->coarse_vec; 308112edc857SStefano Zampini } 308212edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 3083674ae819SStefano Zampini PetscFunctionReturn(0); 3084674ae819SStefano Zampini } 3085674ae819SStefano Zampini 3086674ae819SStefano Zampini #undef __FUNCT__ 3087674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 308812edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 3089674ae819SStefano Zampini { 3090674ae819SStefano Zampini PetscErrorCode ierr; 3091674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 309258da7f69SStefano Zampini PetscScalar *array; 309312edc857SStefano Zampini Vec from,to; 3094674ae819SStefano Zampini 3095674ae819SStefano Zampini PetscFunctionBegin; 309612edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 309712edc857SStefano Zampini from = pcbddc->coarse_vec; 309812edc857SStefano Zampini to = pcbddc->vec1_P; 309912edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 310012edc857SStefano Zampini from = pcbddc->vec1_P; 310112edc857SStefano Zampini to = pcbddc->coarse_vec; 310212edc857SStefano Zampini } 310312edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 310412edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 310512edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 310612edc857SStefano Zampini Vec tvec; 310758da7f69SStefano Zampini 310812edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 310958da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 311058da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 311158da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 311258da7f69SStefano Zampini } 311358da7f69SStefano Zampini } else { 311458da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 311558da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 311612edc857SStefano Zampini } 311712edc857SStefano Zampini } 3118674ae819SStefano Zampini PetscFunctionReturn(0); 3119674ae819SStefano Zampini } 3120674ae819SStefano Zampini 3121984c4197SStefano Zampini /* uncomment for testing purposes */ 3122984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 3123674ae819SStefano Zampini #undef __FUNCT__ 3124674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 3125674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 3126674ae819SStefano Zampini { 3127674ae819SStefano Zampini PetscErrorCode ierr; 3128674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3129674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3130674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3131984c4197SStefano Zampini /* one and zero */ 3132984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 3133984c4197SStefano Zampini /* space to store constraints and their local indices */ 31349162d606SStefano Zampini PetscScalar *constraints_data; 31359162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 31369162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 31379162d606SStefano Zampini PetscInt *constraints_n; 3138984c4197SStefano Zampini /* iterators */ 3139b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 3140984c4197SStefano Zampini /* BLAS integers */ 3141e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 3142e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 3143c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 3144727cdba6SStefano Zampini /* reuse */ 31450e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 31460e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 3147984c4197SStefano Zampini /* change of basis */ 3148b3d85658SStefano Zampini PetscBool qr_needed; 31499162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 3150984c4197SStefano Zampini /* auxiliary stuff */ 315164efe560SStefano Zampini PetscInt *nnz,*is_indices; 31528a0068c3SStefano Zampini PetscInt ncc; 3153984c4197SStefano Zampini /* some quantities */ 315445a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 3155a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 3156984c4197SStefano Zampini 3157674ae819SStefano Zampini PetscFunctionBegin; 31588e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 31598e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 31608e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3161088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 3162088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 31630e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 31640e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 31650e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 31660e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 31670e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3168088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3169cf5a6209SStefano Zampini 3170cf5a6209SStefano Zampini /* print some info */ 3171cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 3172cf5a6209SStefano Zampini IS vertices; 3173cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 3174cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 3175cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 3176cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 31771575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3178cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3179cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 3180fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 3181fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 3182cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 31831575c14dSBarry Smith ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3184cf5a6209SStefano Zampini } 3185cf5a6209SStefano Zampini 3186cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 31879162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 3188cf5a6209SStefano Zampini MatNullSpace nearnullsp; 3189cf5a6209SStefano Zampini const Vec *nearnullvecs; 3190cf5a6209SStefano Zampini Vec *localnearnullsp; 3191cf5a6209SStefano Zampini PetscScalar *array; 3192cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 3193cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 3194674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 3195b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 3196674ae819SStefano Zampini PetscScalar *work; 3197674ae819SStefano Zampini PetscReal *singular_vals; 3198674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3199674ae819SStefano Zampini PetscReal *rwork; 3200674ae819SStefano Zampini #endif 3201674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3202674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 3203674ae819SStefano Zampini #else 3204964fefecSStefano Zampini PetscBLASInt dummy_int=1; 3205964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 3206674ae819SStefano Zampini #endif 3207674ae819SStefano Zampini 3208674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 3209d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 3210d06fc5fdSStefano Zampini /* free unneeded index sets */ 3211d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 3212d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 3213674ae819SStefano Zampini } 3214d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 3215d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3216d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3217d06fc5fdSStefano Zampini } 3218d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3219d06fc5fdSStefano Zampini n_ISForEdges = 0; 3220d06fc5fdSStefano Zampini } 3221d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 3222d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3223d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3224d06fc5fdSStefano Zampini } 3225d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3226d06fc5fdSStefano Zampini n_ISForFaces = 0; 3227d06fc5fdSStefano Zampini } 322870022509SStefano Zampini 322970022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 323070022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 323170022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 323270022509SStefano Zampini if (pcbddc->NullSpace) { 323370022509SStefano Zampini PetscBool tbool[2],gbool[2]; 323470022509SStefano Zampini 323570022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 3236b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 3237d06fc5fdSStefano Zampini if (!ISForEdges) { 3238d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 3239d06fc5fdSStefano Zampini } 3240b8ffe317SStefano Zampini } 3241d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 3242d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 3243d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3244d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 3245d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 324698a51de6SStefano Zampini } 324770022509SStefano Zampini #endif 324808122e43SStefano Zampini 3249674ae819SStefano Zampini /* check if near null space is attached to global mat */ 3250674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 3251674ae819SStefano Zampini if (nearnullsp) { 3252674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 3253f4ddd8eeSStefano Zampini /* remove any stored info */ 3254f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3255f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3256f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 3257f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 3258f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 3259473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3260f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 3261f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 3262f4ddd8eeSStefano Zampini } 3263984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 3264984c4197SStefano Zampini nnsp_size = 0; 3265674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 3266674ae819SStefano Zampini } 3267984c4197SStefano Zampini /* get max number of constraints on a single cc */ 3268984c4197SStefano Zampini max_constraints = nnsp_size; 3269984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 3270984c4197SStefano Zampini 3271674ae819SStefano Zampini /* 3272674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 32739162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 32749162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 32759162d606SStefano Zampini There can be multiple constraints per connected component 3276674ae819SStefano Zampini */ 3277674ae819SStefano Zampini n_vertices = 0; 3278674ae819SStefano Zampini if (ISForVertices) { 3279674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 3280674ae819SStefano Zampini } 32819162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 32829162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 32839162d606SStefano Zampini 32849162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 32859162d606SStefano Zampini total_counts *= max_constraints; 3286674ae819SStefano Zampini total_counts += n_vertices; 32874641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 32889162d606SStefano Zampini 3289674ae819SStefano Zampini total_counts = 0; 3290674ae819SStefano Zampini max_size_of_constraint = 0; 3291674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 32929162d606SStefano Zampini IS used_is; 3293674ae819SStefano Zampini if (i<n_ISForEdges) { 32949162d606SStefano Zampini used_is = ISForEdges[i]; 3295674ae819SStefano Zampini } else { 32969162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 3297674ae819SStefano Zampini } 32989162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 3299674ae819SStefano Zampini total_counts += j; 3300674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 3301674ae819SStefano Zampini } 33029162d606SStefano 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); 33039162d606SStefano Zampini 3304984c4197SStefano Zampini /* get local part of global near null space vectors */ 3305785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 3306984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3307984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 3308e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3309e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3310984c4197SStefano Zampini } 3311674ae819SStefano Zampini 3312242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 3313242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 3314a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 3315242a89d7SStefano Zampini 3316984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 3317a773dcb8SStefano Zampini if (!skip_lapack) { 3318674ae819SStefano Zampini PetscScalar temp_work; 3319911cabfeSStefano Zampini 3320674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3321984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 3322785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 3323785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 3324785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 3325674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3326785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 3327674ae819SStefano Zampini #endif 3328674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3329c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 3330c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 3331674ae819SStefano Zampini lwork = -1; 3332674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3333674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3334c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 3335674ae819SStefano Zampini #else 3336c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 3337674ae819SStefano Zampini #endif 3338674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3339984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 3340674ae819SStefano Zampini #else /* on missing GESVD */ 3341674ae819SStefano Zampini /* SVD */ 3342674ae819SStefano Zampini PetscInt max_n,min_n; 3343674ae819SStefano Zampini max_n = max_size_of_constraint; 3344984c4197SStefano Zampini min_n = max_constraints; 3345984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 3346674ae819SStefano Zampini min_n = max_size_of_constraint; 3347984c4197SStefano Zampini max_n = max_constraints; 3348674ae819SStefano Zampini } 3349785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 3350674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3351785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 3352674ae819SStefano Zampini #endif 3353674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3354674ae819SStefano Zampini lwork = -1; 3355e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 3356e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 3357b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 3358674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3359674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 33609162d606SStefano 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)); 3361674ae819SStefano Zampini #else 33629162d606SStefano 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)); 3363674ae819SStefano Zampini #endif 3364674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3365984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 3366984c4197SStefano Zampini #endif /* on missing GESVD */ 3367674ae819SStefano Zampini /* Allocate optimal workspace */ 3368674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 3369854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 3370674ae819SStefano Zampini } 3371674ae819SStefano Zampini /* Now we can loop on constraining sets */ 3372674ae819SStefano Zampini total_counts = 0; 33739162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 33749162d606SStefano Zampini constraints_data_ptr[0] = 0; 3375674ae819SStefano Zampini /* vertices */ 33769162d606SStefano Zampini if (n_vertices) { 3377674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 33789162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 3379674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 33809162d606SStefano Zampini constraints_n[total_counts] = 1; 33819162d606SStefano Zampini constraints_data[total_counts] = 1.0; 33829162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 33839162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 3384674ae819SStefano Zampini total_counts++; 3385674ae819SStefano Zampini } 3386674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3387674ae819SStefano Zampini n_vertices = total_counts; 3388674ae819SStefano Zampini } 3389984c4197SStefano Zampini 3390674ae819SStefano Zampini /* edges and faces */ 33919162d606SStefano Zampini total_counts_cc = total_counts; 3392911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 33939162d606SStefano Zampini IS used_is; 33949162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 33959162d606SStefano Zampini 3396911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 33979162d606SStefano Zampini used_is = ISForEdges[ncc]; 3398984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 3399674ae819SStefano Zampini } else { 34009162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 3401984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 3402674ae819SStefano Zampini } 3403674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 34049162d606SStefano Zampini 34059162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 34069162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3407984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 3408984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 3409674ae819SStefano Zampini if (nnsp_has_cnst) { 34105b08dc53SStefano Zampini PetscScalar quad_value; 34119162d606SStefano Zampini 34129162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 34139162d606SStefano Zampini idxs_copied = PETSC_TRUE; 34149162d606SStefano Zampini 3415a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 3416674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 3417a773dcb8SStefano Zampini } else { 3418a773dcb8SStefano Zampini quad_value = 1.0; 3419a773dcb8SStefano Zampini } 3420674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 34219162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 3422674ae819SStefano Zampini } 34239162d606SStefano Zampini temp_constraints++; 3424674ae819SStefano Zampini total_counts++; 3425674ae819SStefano Zampini } 3426674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 3427984c4197SStefano Zampini PetscReal real_value; 34289162d606SStefano Zampini PetscScalar *ptr_to_data; 34299162d606SStefano Zampini 3430984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 34319162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 3432674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 34339162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 3434674ae819SStefano Zampini } 3435984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 3436984c4197SStefano Zampini /* check if array is null on the connected component */ 3437e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 34389162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 34395b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 3440674ae819SStefano Zampini temp_constraints++; 3441674ae819SStefano Zampini total_counts++; 34429162d606SStefano Zampini if (!idxs_copied) { 34439162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 34449162d606SStefano Zampini idxs_copied = PETSC_TRUE; 3445674ae819SStefano Zampini } 3446674ae819SStefano Zampini } 34479162d606SStefano Zampini } 34489162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 344945a1bb75SStefano Zampini valid_constraints = temp_constraints; 3450eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 3451a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 34529162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 34539162d606SStefano Zampini 34549162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3455a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 34569162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 3457a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 34589162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 3459a773dcb8SStefano Zampini } else { /* perform SVD */ 3460984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 34619162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3462674ae819SStefano Zampini 3463674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3464984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3465984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3466984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3467984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3468984c4197SStefano Zampini from that computed using LAPACKgesvd 3469984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3470984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3471984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3472674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3473e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3474984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3475674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3476674ae819SStefano Zampini for (k=0;k<j+1;k++) { 34779162d606SStefano 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)); 3478674ae819SStefano Zampini } 3479674ae819SStefano Zampini } 3480e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3481e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3482e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3483674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3484c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3485674ae819SStefano Zampini #else 3486c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3487674ae819SStefano Zampini #endif 3488674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3489984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3490984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3491674ae819SStefano Zampini j = 0; 3492984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3493674ae819SStefano Zampini total_counts = total_counts-j; 349445a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3495e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3496c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3497c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3498c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3499c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3500c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3501c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3502674ae819SStefano Zampini if (j<temp_constraints) { 3503984c4197SStefano Zampini PetscInt ii; 3504984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3505674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 35069162d606SStefano 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)); 3507674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3508984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3509674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 35109162d606SStefano 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]; 3511674ae819SStefano Zampini } 3512674ae819SStefano Zampini } 3513674ae819SStefano Zampini } 3514674ae819SStefano Zampini #else /* on missing GESVD */ 3515e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3516e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3517b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3518674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3519674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 35209162d606SStefano 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)); 3521674ae819SStefano Zampini #else 35229162d606SStefano 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)); 3523674ae819SStefano Zampini #endif 3524984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 3525674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3526984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 3527e310c8b4SStefano Zampini k = temp_constraints; 3528e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 3529674ae819SStefano Zampini j = 0; 3530e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 353145a1bb75SStefano Zampini valid_constraints = k-j; 3532911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 3533984c4197SStefano Zampini #endif /* on missing GESVD */ 3534674ae819SStefano Zampini } 3535a773dcb8SStefano Zampini } 35369162d606SStefano Zampini /* update pointers information */ 35379162d606SStefano Zampini if (valid_constraints) { 35389162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 35399162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 35409162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 35419162d606SStefano Zampini /* set change_of_basis flag */ 354245a1bb75SStefano Zampini if (boolforchange) { 3543b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 35449162d606SStefano Zampini } 3545b3d85658SStefano Zampini total_counts_cc++; 354645a1bb75SStefano Zampini } 354745a1bb75SStefano Zampini } 3548984c4197SStefano Zampini /* free workspace */ 35498f1c130eSStefano Zampini if (!skip_lapack) { 3550984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3551984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3552984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 3553984c4197SStefano Zampini #endif 3554984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 3555984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3556984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 3557984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 3558984c4197SStefano Zampini #endif 3559984c4197SStefano Zampini } 3560984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3561984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 3562984c4197SStefano Zampini } 3563984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 3564cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 3565cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3566cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3567cf5a6209SStefano Zampini } 3568cf5a6209SStefano Zampini if (n_ISForFaces) { 3569cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3570cf5a6209SStefano Zampini } 3571cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3572cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3573cf5a6209SStefano Zampini } 3574cf5a6209SStefano Zampini if (n_ISForEdges) { 3575cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3576cf5a6209SStefano Zampini } 3577cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 357808122e43SStefano Zampini } else { 357908122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3580984c4197SStefano Zampini 358108122e43SStefano Zampini total_counts = 0; 358208122e43SStefano Zampini n_vertices = 0; 3583d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 3584d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 358508122e43SStefano Zampini } 358608122e43SStefano Zampini max_constraints = 0; 35879162d606SStefano Zampini total_counts_cc = 0; 358808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 358908122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 35909162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 359108122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 359208122e43SStefano Zampini } 35939162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 35949162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 35959162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 35969162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 359774d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 35989162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 35999162d606SStefano Zampini total_counts_cc = 0; 36009162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 36019162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 36029162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 360308122e43SStefano Zampini } 360408122e43SStefano Zampini } 36059162d606SStefano Zampini #if 0 36069162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 36079162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 36089162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 36099162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 36109162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 36119162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 36129162d606SStefano Zampini } 36139162d606SStefano Zampini printf("\n"); 36149162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 36159162d606SStefano Zampini } 36161b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 36178bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 36181b968477SStefano Zampini } 36191b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 36208bec7fa6SStefano 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]); 36211b968477SStefano Zampini } 362208122e43SStefano Zampini #endif 362308122e43SStefano Zampini 36248bec7fa6SStefano Zampini max_size_of_constraint = 0; 36259162d606SStefano 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]); 36269162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 362708122e43SStefano Zampini /* Change of basis */ 3628b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 362908122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 363008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 363108122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 3632b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 363308122e43SStefano Zampini } 363408122e43SStefano Zampini } 363508122e43SStefano Zampini } 363608122e43SStefano Zampini } 3637984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 36384f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 363908122e43SStefano Zampini 36409162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 36419162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 36429162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 36439162d606SStefano 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); 364408122e43SStefano Zampini } 3645674ae819SStefano Zampini 3646674ae819SStefano Zampini /* Create constraint matrix */ 3647674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 364816f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 3649984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 3650984c4197SStefano Zampini 3651984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 3652a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 3653a717540cSStefano Zampini qr_needed = PETSC_FALSE; 365474d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 3655984c4197SStefano Zampini total_primal_vertices=0; 3656b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 36579162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 36589162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3659984c4197SStefano Zampini if (size_of_constraint == 1) { 36609162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 3661b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 366264efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 36639162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 36649162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 3665a717540cSStefano Zampini } 3666b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 366774d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 3668a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 3669a717540cSStefano Zampini qr_needed = PETSC_TRUE; 3670a717540cSStefano Zampini } 3671fa434743SStefano Zampini } else { 3672b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 3673fa434743SStefano Zampini } 3674a717540cSStefano Zampini } 3675b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 3676b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 3677674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 367870022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3679b3d85658SStefano Zampini 36804f1b2e48SStefano 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); 36810e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 36820e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 3683984c4197SStefano Zampini 3684984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 368574d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 3686785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 3687984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 368874d5cdf7SStefano Zampini 3689984c4197SStefano Zampini j = total_primal_vertices; 369074d5cdf7SStefano Zampini total_counts = total_primal_vertices; 3691b3d85658SStefano Zampini cum = total_primal_vertices; 36929162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 36934641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 3694b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 3695b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 3696b3d85658SStefano Zampini cum++; 36979162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 369874d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 369974d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 370074d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 370174d5cdf7SStefano Zampini } 37029162d606SStefano Zampini j += constraints_n[i]; 3703674ae819SStefano Zampini } 3704674ae819SStefano Zampini } 3705674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 3706674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3707088faed8SStefano Zampini 3708674ae819SStefano Zampini /* set values in constraint matrix */ 3709984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 37100e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 3711674ae819SStefano Zampini } 3712984c4197SStefano Zampini total_counts = total_primal_vertices; 37139162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 37144641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 37159162d606SStefano Zampini PetscInt *cols; 37169162d606SStefano Zampini 37179162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 37189162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 37199162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 37209162d606SStefano Zampini PetscInt row = total_counts+k; 37219162d606SStefano Zampini PetscScalar *vals; 37229162d606SStefano Zampini 37239162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 37249162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 37259162d606SStefano Zampini } 37269162d606SStefano Zampini total_counts += constraints_n[i]; 3727674ae819SStefano Zampini } 3728674ae819SStefano Zampini } 3729674ae819SStefano Zampini /* assembling */ 3730674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3731674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3732088faed8SStefano Zampini 3733984c4197SStefano Zampini /* 373445a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3735984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 3736984c4197SStefano Zampini */ 3737674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 3738674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 3739026de310SStefano Zampini /* dual and primal dofs on a single cc */ 3740984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 3741984c4197SStefano Zampini /* working stuff for GEQRF */ 374281d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 3743984c4197SStefano Zampini PetscBLASInt lqr_work; 3744984c4197SStefano Zampini /* working stuff for UNGQR */ 3745984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 3746984c4197SStefano Zampini PetscBLASInt lgqr_work; 3747984c4197SStefano Zampini /* working stuff for TRTRS */ 3748984c4197SStefano Zampini PetscScalar *trs_rhs; 37493f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 3750984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 3751984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 3752984c4197SStefano Zampini PetscScalar *start_vals; 3753984c4197SStefano Zampini /* working stuff for values insertion */ 37544641a718SStefano Zampini PetscBT is_primal; 375564efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 3756906d46d4SStefano Zampini /* matrix sizes */ 3757906d46d4SStefano Zampini PetscInt global_size,local_size; 3758906d46d4SStefano Zampini /* temporary change of basis */ 3759906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 3760cf5a6209SStefano Zampini /* extra space for debugging */ 3761cf5a6209SStefano Zampini PetscScalar *dbg_work; 3762984c4197SStefano Zampini 3763906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 3764906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 376516f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 3766bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 3767906d46d4SStefano Zampini /* nonzeros for local mat */ 3768bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 3769bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 37709162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 3771a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 37729162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3773a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 37749162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 3775a717540cSStefano Zampini } else { 37769162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 37779162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 3778a717540cSStefano Zampini } 3779a717540cSStefano Zampini } 3780a717540cSStefano Zampini } 3781906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 3782bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3783a717540cSStefano Zampini /* Set initial identity in the matrix */ 3784bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 3785906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 3786a717540cSStefano Zampini } 3787a717540cSStefano Zampini 3788a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3789a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3790a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3791a717540cSStefano Zampini } 3792a717540cSStefano Zampini 3793a717540cSStefano Zampini 3794a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 3795a717540cSStefano Zampini /* 3796a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 3797a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 3798a717540cSStefano Zampini 3799a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 3800a717540cSStefano Zampini 3801a6b551f4SStefano 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) 3802a6b551f4SStefano Zampini 3803a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 3804a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 3805a717540cSStefano Zampini | ... | 3806a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 3807a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 3808a717540cSStefano Zampini 3809a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 3810a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 3811a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 3812a6b551f4SStefano Zampini 3813a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 3814a717540cSStefano Zampini */ 3815a717540cSStefano Zampini if (qr_needed) { 3816984c4197SStefano Zampini /* space to store Q */ 3817854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 3818984c4197SStefano Zampini /* first we issue queries for optimal work */ 38193f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 38203f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 38213f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3822984c4197SStefano Zampini lqr_work = -1; 38233f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 3824984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 3825984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 3826785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 3827984c4197SStefano Zampini lgqr_work = -1; 38283f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 38293f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 38303f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 38313f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 38323f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 38333f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 3834984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 3835984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 3836785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 3837984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 3838785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 3839984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 3840785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 3841a717540cSStefano Zampini /* allocating workspace for check */ 3842a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3843cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 3844a717540cSStefano Zampini } 3845a717540cSStefano Zampini } 3846984c4197SStefano Zampini /* array to store whether a node is primal or not */ 38474641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 3848473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 38490e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 385039e2fb2aSStefano Zampini if (i != total_primal_vertices) { 385139e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 38524641a718SStefano Zampini } 385339e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 385439e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 385539e2fb2aSStefano Zampini } 385639e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 3857984c4197SStefano Zampini 3858a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 38599162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 38609162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 38614641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 3862984c4197SStefano Zampini /* get constraint info */ 38639162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 3864984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 3865984c4197SStefano Zampini 3866984c4197SStefano Zampini if (pcbddc->dbg_flag) { 38679162d606SStefano 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); 3868674ae819SStefano Zampini } 3869984c4197SStefano Zampini 3870fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 3871a717540cSStefano Zampini 3872a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 3873a717540cSStefano Zampini if (pcbddc->dbg_flag) { 38749162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3875a717540cSStefano Zampini } 3876984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 38779162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3878984c4197SStefano Zampini 3879984c4197SStefano Zampini /* compute QR decomposition of constraints */ 38803f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 38813f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 38823f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3883674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 38843f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 3885984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 3886674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3887984c4197SStefano Zampini 3888984c4197SStefano Zampini /* explictly compute R^-T */ 3889984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 3890984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 38913f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 38923f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 38933f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 38943f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 3895984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 38963f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 3897984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 3898984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3899984c4197SStefano Zampini 3900a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 39013f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 39023f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 39033f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 39043f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3905984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 39063f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 3907984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 3908984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3909984c4197SStefano Zampini 3910984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 3911984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 3912984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 39133f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 39143f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 39153f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 39163f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 39173f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 39183f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3919984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 39209162d606SStefano 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)); 3921984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 39229162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3923984c4197SStefano Zampini 3924984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 39259162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 3926984c4197SStefano Zampini /* insert cols for primal dofs */ 3927984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 3928984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 39299162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3930906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3931984c4197SStefano Zampini } 3932984c4197SStefano Zampini /* insert cols for dual dofs */ 3933984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 39349162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 3935984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 39369162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3937906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3938984c4197SStefano Zampini j++; 3939674ae819SStefano Zampini } 3940674ae819SStefano Zampini } 3941984c4197SStefano Zampini 3942984c4197SStefano Zampini /* check change of basis */ 3943984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3944984c4197SStefano Zampini PetscInt ii,jj; 3945984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 3946c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 3947c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3948c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 3949c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3950c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 3951c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 3952984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3953cf5a6209SStefano 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)); 3954984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3955984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3956984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3957cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 3958cf5a6209SStefano 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; 3959674ae819SStefano Zampini } 3960674ae819SStefano Zampini } 3961984c4197SStefano Zampini if (!valid_qr) { 396222d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 3963984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3964984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3965cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 3966cf5a6209SStefano 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])); 3967674ae819SStefano Zampini } 3968cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 3969cf5a6209SStefano 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])); 3970984c4197SStefano Zampini } 3971984c4197SStefano Zampini } 3972984c4197SStefano Zampini } 3973674ae819SStefano Zampini } else { 397422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 3975674ae819SStefano Zampini } 3976674ae819SStefano Zampini } 3977a717540cSStefano Zampini } else { /* simple transformation block */ 3978a717540cSStefano Zampini PetscInt row,col; 3979a6b551f4SStefano Zampini PetscScalar val,norm; 3980a6b551f4SStefano Zampini 3981a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 39829162d606SStefano 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)); 3983a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 39849162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 39859162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3986bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 39879162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 3988906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 39899162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 3990a717540cSStefano Zampini } else { 3991a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 39929162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3993a717540cSStefano Zampini if (row != col) { 39949162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 3995a717540cSStefano Zampini } else { 39969162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 3997a717540cSStefano Zampini } 3998906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 3999a717540cSStefano Zampini } 4000a717540cSStefano Zampini } 4001a717540cSStefano Zampini } 400298a51de6SStefano Zampini if (pcbddc->dbg_flag) { 400322d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 4004a717540cSStefano Zampini } 4005674ae819SStefano Zampini } 4006984c4197SStefano Zampini } else { 4007984c4197SStefano Zampini if (pcbddc->dbg_flag) { 40089162d606SStefano 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); 4009674ae819SStefano Zampini } 4010674ae819SStefano Zampini } 4011674ae819SStefano Zampini } 4012a717540cSStefano Zampini 4013a717540cSStefano Zampini /* free workspace */ 4014a717540cSStefano Zampini if (qr_needed) { 4015984c4197SStefano Zampini if (pcbddc->dbg_flag) { 4016cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 4017984c4197SStefano Zampini } 4018984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 4019984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 4020984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 4021984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 4022984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 4023674ae819SStefano Zampini } 4024a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 4025906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4026906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4027906d46d4SStefano Zampini 4028906d46d4SStefano Zampini /* assembling of global change of variable */ 4029bbb9e6c6SStefano Zampini { 4030bbb9e6c6SStefano Zampini Mat tmat; 403116f15bc4SStefano Zampini PetscInt bs; 403216f15bc4SStefano Zampini 4033906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 4034906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 4035bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 4036bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 4037bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4038bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 403916f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 404016f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 4041906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 4042bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 4043bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4044bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4045bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4046bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 4047e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4048e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4049bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 4050bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 4051906d46d4SStefano Zampini } 4052906d46d4SStefano Zampini /* check */ 4053906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4054906d46d4SStefano Zampini PetscReal error; 4055906d46d4SStefano Zampini Vec x,x_change; 4056906d46d4SStefano Zampini 4057906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 4058906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 4059906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 4060906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 4061e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4062e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4063bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 4064e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4065e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4066906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 4067906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4068906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4069906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4070bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 4071906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4072906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4073906d46d4SStefano Zampini } 4074b96c3477SStefano Zampini 4075b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 4076b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 4077b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4078b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 4079ac632422SStefano Zampini Mat S_new,tmat; 4080b087196eSStefano Zampini ISLocalToGlobalMapping NtoSall; 4081b087196eSStefano Zampini IS is_all_N,is_V,is_V_Sall; 4082b087196eSStefano Zampini const PetscScalar *array; 4083b087196eSStefano Zampini const PetscInt *idxs_V,*idxs_all; 4084b087196eSStefano Zampini PetscInt i,n_V; 4085bbb9e6c6SStefano Zampini 4086bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 40876816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 4088b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 4089b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 4090b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 4091b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 4092bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 4093b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 4094ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4095b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 4096ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4097b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4098b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 4099b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4100b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4101b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 4102b087196eSStefano Zampini for (i=0;i<n_V;i++) { 4103b087196eSStefano Zampini PetscScalar val; 4104b087196eSStefano Zampini PetscInt idx; 4105b087196eSStefano Zampini 4106b087196eSStefano Zampini idx = idxs_V[i]; 4107b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 4108b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 4109b087196eSStefano Zampini } 4110b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4111b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4112ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 4113ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4114ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 4115ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4116b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 4117ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4118b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4119ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 4120ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4121ac632422SStefano Zampini } 4122b087196eSStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 4123b087196eSStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4124b087196eSStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4125b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4126b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 4127b96c3477SStefano Zampini } 4128b96c3477SStefano Zampini } 4129906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 4130906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 4131b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4132b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 4133b9b85e73SStefano Zampini } 4134906d46d4SStefano Zampini 4135906d46d4SStefano Zampini /* set up change of basis context */ 4136906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 4137906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4138906d46d4SStefano Zampini 4139906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 4140906d46d4SStefano Zampini PetscInt global_size,local_size; 4141906d46d4SStefano Zampini 4142906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 4143906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 4144906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 4145906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 4146906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 4147906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 4148906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 4149906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 4150906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 4151906d46d4SStefano Zampini } else { 4152906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 4153906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 4154906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 4155906d46d4SStefano Zampini } 4156906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 4157906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4158906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 4159906d46d4SStefano Zampini } else { 4160906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4161906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 4162906d46d4SStefano Zampini } 4163906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 4164906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 4165906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4166906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4167a8661815SStefano Zampini } else { 4168a8661815SStefano Zampini ierr = MatDestroy(&pcbddc->new_global_mat);CHKERRQ(ierr); 4169b9b85e73SStefano Zampini } 4170a717540cSStefano Zampini 41714f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 41724f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 41734f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 41744f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 4175019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 4176019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 4177019a44ceSStefano Zampini pcbddc->local_primal_size++; 4178019a44ceSStefano Zampini } 4179019a44ceSStefano Zampini 4180019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 4181727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 4182727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 41839f47a83aSStefano 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); 4184c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 41850e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 41869f47a83aSStefano 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); 4187727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 4188727cdba6SStefano Zampini } 41890e6343abSStefano Zampini } 41900e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 4191727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 4192727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4193727cdba6SStefano Zampini 4194a717540cSStefano Zampini /* flush dbg viewer */ 4195b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 4196b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4197b8ffe317SStefano Zampini } 4198a717540cSStefano Zampini 4199e310c8b4SStefano Zampini /* free workspace */ 4200a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 42014641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 420208122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 42039162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 42049162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 420508122e43SStefano Zampini } else { 42069162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 42079162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 42089162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 420908122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 421008122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 42119162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 42129162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 421308122e43SStefano Zampini } 4214674ae819SStefano Zampini PetscFunctionReturn(0); 4215674ae819SStefano Zampini } 4216674ae819SStefano Zampini 4217674ae819SStefano Zampini #undef __FUNCT__ 4218674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 4219674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 4220674ae819SStefano Zampini { 4221674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4222674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4223674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 42247fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 4225674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 4226674ae819SStefano Zampini 4227674ae819SStefano Zampini PetscFunctionBegin; 42288e61c736SStefano Zampini /* Reset previously computed graph */ 42298e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 4230674ae819SStefano Zampini /* Init local Graph struct */ 42317fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 42323bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 4233674ae819SStefano Zampini 4234575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 42355099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 42365099eff2SStefano 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); 4237575ad6abSStefano Zampini } 42389577ea80SStefano Zampini 4239674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 4240*d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 42414d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 42424d379d7bSStefano Zampini PetscInt nvtxs; 4243e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 4244674ae819SStefano Zampini 42452fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 42462fffb893SStefano Zampini if (flg_row) { 42474d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 4248b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 42492fffb893SStefano Zampini } 42502fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4251674ae819SStefano Zampini } 42529b28b941SStefano Zampini if (pcbddc->dbg_flag) { 42539b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4254674ae819SStefano Zampini } 4255674ae819SStefano Zampini 425663602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 4257674ae819SStefano Zampini vertex_size = 1; 425863602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 425963602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 426095ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 426163602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 4262e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 426363602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 4264674ae819SStefano Zampini } 426563602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 426663602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 426763602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 4268674ae819SStefano Zampini } 426963602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 4270674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 427163602bcaSStefano Zampini } else { 427263602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 427363602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 4274854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 427563602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 427663602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 427763602bcaSStefano Zampini } 427863602bcaSStefano Zampini } 4279674ae819SStefano Zampini } 4280674ae819SStefano Zampini 4281674ae819SStefano Zampini /* Setup of Graph */ 4282785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 4283e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 4284785d1243SStefano Zampini } 4285785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 4286e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 4287785d1243SStefano Zampini } 428830368db7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { /* need to convert from global to local */ 428930368db7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 429030368db7SStefano Zampini } 429130368db7SStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 4292674ae819SStefano Zampini 42934f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 42944f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 42954f1b2e48SStefano Zampini PetscInt *local_subs; 42964f1b2e48SStefano Zampini 42974f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 42984f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 42994f1b2e48SStefano Zampini const PetscInt *idxs; 43004f1b2e48SStefano Zampini PetscInt nl,j; 43014f1b2e48SStefano Zampini 43024f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 43034f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 43044f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 43054f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 43064f1b2e48SStefano Zampini } 43074f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 43084f1b2e48SStefano Zampini } 43094f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 43104f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 43114f1b2e48SStefano Zampini } 43124f1b2e48SStefano Zampini 4313674ae819SStefano Zampini /* Graph's connected components analysis */ 4314674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 4315674ae819SStefano Zampini 4316674ae819SStefano Zampini /* print some info to stdout */ 4317674ae819SStefano Zampini if (pcbddc->dbg_flag) { 4318302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 4319674ae819SStefano Zampini } 4320fb180af4SStefano Zampini 4321fb180af4SStefano Zampini /* mark topography has done */ 4322fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 4323674ae819SStefano Zampini PetscFunctionReturn(0); 4324674ae819SStefano Zampini } 4325674ae819SStefano Zampini 4326dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 4327674ae819SStefano Zampini #undef __FUNCT__ 4328674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 4329dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 4330674ae819SStefano Zampini { 4331dc456d91SStefano Zampini PetscSF sf; 4332dc456d91SStefano Zampini PetscLayout map; 4333dc456d91SStefano Zampini const PetscInt *idxs; 4334dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 4335dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 4336dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 4337dc456d91SStefano Zampini PetscMPIInt commsize; 4338674ae819SStefano Zampini PetscBool first_found; 4339674ae819SStefano Zampini PetscErrorCode ierr; 4340674ae819SStefano Zampini 4341674ae819SStefano Zampini PetscFunctionBegin; 4342dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 4343dc456d91SStefano Zampini if (subset_mult) { 4344dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 4345dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 4346dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 4347674ae819SStefano Zampini } 4348dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 4349dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 4350dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 4351dc456d91SStefano Zampini for (i=0;i<n;i++) { 4352dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 4353dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 4354674ae819SStefano Zampini } 4355dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 4356dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4357dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 4358dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 4359dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 4360dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 4361dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 4362dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 4363dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 4364dc456d91SStefano Zampini 4365dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 4366dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 4367dc456d91SStefano Zampini if (subset_mult) { 4368dc456d91SStefano Zampini const PetscInt* idxs_mult; 4369dc456d91SStefano Zampini 4370dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4371dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 4372dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4373674ae819SStefano Zampini } else { 4374dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 4375674ae819SStefano Zampini } 4376dc456d91SStefano Zampini /* local size of new subset */ 4377dc456d91SStefano Zampini n_n = 0; 4378dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 4379dc456d91SStefano Zampini 4380dc456d91SStefano Zampini /* global indexes in layout */ 4381dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 4382dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 4383dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 4384dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4385dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4386dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4387dc456d91SStefano Zampini 4388dc456d91SStefano Zampini /* reduce from leaves to roots */ 4389dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 439064a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 439164a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4392dc456d91SStefano Zampini 4393dc456d91SStefano Zampini /* count indexes in local part of layout */ 4394674ae819SStefano Zampini nlocals = 0; 4395674ae819SStefano Zampini first_index = -1; 4396674ae819SStefano Zampini first_found = PETSC_FALSE; 4397dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4398dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4399674ae819SStefano Zampini first_found = PETSC_TRUE; 4400674ae819SStefano Zampini first_index = i; 4401674ae819SStefano Zampini } 4402dc456d91SStefano Zampini nlocals += root_data[i]; 4403674ae819SStefano Zampini } 4404dc456d91SStefano Zampini 4405dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 44065fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4407dc456d91SStefano Zampini start = 0; 440864a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 44095fa240b1SStefano Zampini #else 441064a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 44115fa240b1SStefano Zampini start = start-nlocals; 44125fa240b1SStefano Zampini #endif 44135fa240b1SStefano Zampini 4414dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4415dc456d91SStefano Zampini *N_n = start + nlocals; 4416dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4417dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4418674ae819SStefano Zampini } 44195fa240b1SStefano Zampini 44205fa240b1SStefano Zampini /* adapt root data with cumulative */ 4421674ae819SStefano Zampini if (first_found) { 4422dc456d91SStefano Zampini PetscInt old_index; 4423dc456d91SStefano Zampini 4424dc456d91SStefano Zampini root_data[first_index] += start; 4425674ae819SStefano Zampini old_index = first_index; 4426dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4427dc456d91SStefano Zampini if (root_data[i]) { 4428dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4429674ae819SStefano Zampini old_index = i; 4430674ae819SStefano Zampini } 4431674ae819SStefano Zampini } 4432674ae819SStefano Zampini } 4433dc456d91SStefano Zampini 4434dc456d91SStefano Zampini /* from roots to leaves */ 4435dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4436dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4437dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4438dc456d91SStefano Zampini 4439dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4440dc456d91SStefano Zampini if (subset_mult) { 4441dc456d91SStefano Zampini const PetscInt* idxs_mult; 4442dc456d91SStefano Zampini PetscInt cum; 4443dc456d91SStefano Zampini 4444dc456d91SStefano Zampini cum = 0; 4445dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4446dc456d91SStefano Zampini for (i=0;i<n;i++) { 4447dc456d91SStefano Zampini PetscInt j; 4448dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4449674ae819SStefano Zampini } 4450dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4451674ae819SStefano Zampini } else { 4452dc456d91SStefano Zampini for (i=0;i<n;i++) { 4453dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4454674ae819SStefano Zampini } 4455674ae819SStefano Zampini } 4456dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4457dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4458674ae819SStefano Zampini PetscFunctionReturn(0); 4459674ae819SStefano Zampini } 44609a7d3425SStefano Zampini 44619a7d3425SStefano Zampini #undef __FUNCT__ 44629a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 44639a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 44649a7d3425SStefano Zampini { 44659a7d3425SStefano Zampini PetscInt i,j; 44669a7d3425SStefano Zampini PetscScalar *alphas; 44679a7d3425SStefano Zampini PetscErrorCode ierr; 44689a7d3425SStefano Zampini 44699a7d3425SStefano Zampini PetscFunctionBegin; 44709a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 4471785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 44729a7d3425SStefano Zampini for (i=0;i<n;i++) { 44739a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 44749a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 44759a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 44769a7d3425SStefano Zampini } 44779a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 44789a7d3425SStefano Zampini PetscFunctionReturn(0); 44799a7d3425SStefano Zampini } 44809a7d3425SStefano Zampini 4481e7931f94SStefano Zampini #undef __FUNCT__ 448270cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 4483b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 4484e7931f94SStefano Zampini { 448552e5ac9dSStefano Zampini IS ranks_send_to; 4486e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 4487e7931f94SStefano Zampini PetscMPIInt size,rank,color; 448852e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 448952e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 44903837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 44912b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 4492e7931f94SStefano Zampini PetscSubcomm subcomm; 449352e5ac9dSStefano Zampini PetscErrorCode ierr; 4494a57a6d2fSStefano Zampini 4495e7931f94SStefano Zampini PetscFunctionBegin; 44962b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 44972b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 44982b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 4499e7931f94SStefano Zampini 4500e7931f94SStefano Zampini /* Get info on mapping */ 45013bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 45023bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4503e7931f94SStefano Zampini 4504e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 4505785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 4506e7931f94SStefano Zampini xadj[0] = 0; 4507e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 4508785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 4509785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 4510e7931f94SStefano Zampini 45112b510759SStefano Zampini if (threshold) { 4512d023bfaeSStefano Zampini PetscInt xadj_count = 0; 45132b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 4514d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 4515d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 4516d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 4517d023bfaeSStefano Zampini xadj_count++; 4518e7931f94SStefano Zampini } 4519e7931f94SStefano Zampini } 4520d023bfaeSStefano Zampini xadj[1] = xadj_count; 4521c8587f34SStefano Zampini } else { 4522e7931f94SStefano Zampini if (xadj[1]) { 4523e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 4524e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 4525c8587f34SStefano Zampini } 4526e7931f94SStefano Zampini } 45273bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4528e7931f94SStefano Zampini if (use_square) { 4529e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4530e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 4531e7931f94SStefano Zampini } 4532e7931f94SStefano Zampini } 4533e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4534e7931f94SStefano Zampini 45353837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 4536e7931f94SStefano Zampini 4537e7931f94SStefano Zampini /* 4538e7931f94SStefano Zampini Restrict work on active processes only. 4539e7931f94SStefano Zampini */ 4540e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 4541e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 4542e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 45432b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 4544d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4545e7931f94SStefano Zampini if (color) { 4546e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 4547e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 4548e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4549c8587f34SStefano Zampini } else { 455052e5ac9dSStefano Zampini Mat subdomain_adj; 455152e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 455252e5ac9dSStefano Zampini MatPartitioning partitioner; 455352e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 455452e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 4555b0c7d250SStefano Zampini PetscBool aggregate; 4556b0c7d250SStefano Zampini 4557306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 4558785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 4559e7931f94SStefano Zampini prank = rank; 4560306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 45618002ef2cSStefano Zampini /* 4562e7931f94SStefano Zampini for (i=0;i<size;i++) { 4563e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 4564c8587f34SStefano Zampini } 45658002ef2cSStefano Zampini */ 4566e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4567e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 4568c8587f34SStefano Zampini } 4569e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4570b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 4571b0c7d250SStefano Zampini if (aggregate) { 4572b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 4573b0c7d250SStefano Zampini PetscMPIInt nrank; 4574b0c7d250SStefano Zampini PetscScalar *vals; 4575b0c7d250SStefano Zampini 4576b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 4577b0c7d250SStefano Zampini lrows = 0; 4578b0c7d250SStefano Zampini if (nrank<redprocs) { 4579b0c7d250SStefano Zampini lrows = size/redprocs; 4580b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 4581b0c7d250SStefano Zampini } 45825fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 4583b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 4584b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4585b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4586b0c7d250SStefano Zampini row = nrank; 4587b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 4588b0c7d250SStefano Zampini cols = adjncy; 4589b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 4590b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 4591b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 4592b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4593b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 459452e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 459552e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 459652e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4597b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4598b0c7d250SStefano Zampini } else { 4599306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 4600b0c7d250SStefano Zampini } 460122b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 4602e7931f94SStefano Zampini 4603e7931f94SStefano Zampini /* Partition */ 4604306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 4605e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 4606e7931f94SStefano Zampini if (use_vwgt) { 46073837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 4608e7931f94SStefano Zampini v_wgt[0] = local_size; 4609e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 4610c8587f34SStefano Zampini } 461128143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 461228143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 4613e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 4614e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 461522b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 4616e7931f94SStefano Zampini 461752e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 461852e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 461952e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 462052e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4621b0c7d250SStefano Zampini if (!redprocs) { 4622b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 462328143c3dSStefano Zampini } else { 4624b0c7d250SStefano Zampini PetscInt idxs[1]; 4625b0c7d250SStefano Zampini PetscMPIInt tag; 4626b0c7d250SStefano Zampini MPI_Request *reqs; 4627b0c7d250SStefano Zampini 4628b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 4629b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 4630b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 4631b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 463228143c3dSStefano Zampini } 4633b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 4634b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4635b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 4636b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 4637e7931f94SStefano Zampini } 463852e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4639e7931f94SStefano Zampini /* clean up */ 4640e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 464152e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 4642e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 4643e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 4644e7931f94SStefano Zampini } 4645e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 4646e7931f94SStefano Zampini 4647e7931f94SStefano Zampini /* assemble parallel IS for sends */ 4648e7931f94SStefano Zampini i = 1; 4649e7931f94SStefano Zampini if (color) i=0; 4650e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 4651e7931f94SStefano Zampini /* get back IS */ 4652e7931f94SStefano Zampini *is_sends = ranks_send_to; 4653e7931f94SStefano Zampini PetscFunctionReturn(0); 4654e7931f94SStefano Zampini } 4655e7931f94SStefano Zampini 4656e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 4657e7931f94SStefano Zampini 4658e7931f94SStefano Zampini #undef __FUNCT__ 4659e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 466053a05cb3SStefano 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[]) 4661e7931f94SStefano Zampini { 466270cf5478SStefano Zampini Mat local_mat; 4663e7931f94SStefano Zampini IS is_sends_internal; 46649d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 466528143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 46669d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 4667e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 4668e7931f94SStefano Zampini PetscInt* l2gmap_indices; 4669e7931f94SStefano Zampini const PetscInt* is_indices; 4670e7931f94SStefano Zampini MatType new_local_type; 4671e7931f94SStefano Zampini /* buffers */ 4672e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 467328143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 46749d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 4675e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 4676e7931f94SStefano Zampini /* MPI */ 467728143c3dSStefano Zampini MPI_Comm comm,comm_n; 467828143c3dSStefano Zampini PetscSubcomm subcomm; 4679e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 468028143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 468128143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 468228143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 468328143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 468428143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 4685e7931f94SStefano Zampini PetscErrorCode ierr; 4686e7931f94SStefano Zampini 4687e7931f94SStefano Zampini PetscFunctionBegin; 468828143c3dSStefano Zampini /* TODO: add missing checks */ 468928143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 469028143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 469128143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 469228143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 4693e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 469428143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 4695e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4696e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 4697e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 4698e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 4699e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 470028143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 470170cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 470270cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 470328143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 470470cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 470570cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 470670cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 470770cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 470870cf5478SStefano Zampini } 4709e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 4710e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 4711e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 4712e7931f94SStefano Zampini if (!is_sends) { 471328143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 4714b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 4715c8587f34SStefano Zampini } else { 4716e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 4717e7931f94SStefano Zampini is_sends_internal = is_sends; 4718c8587f34SStefano Zampini } 4719e7931f94SStefano Zampini 4720e7931f94SStefano Zampini /* get comm */ 4721a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 4722e7931f94SStefano Zampini 4723e7931f94SStefano Zampini /* compute number of sends */ 4724e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 4725e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 4726e7931f94SStefano Zampini 4727e7931f94SStefano Zampini /* compute number of receives */ 4728e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 4729785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 4730e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 4731e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4732e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 4733e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 4734e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 4735e7931f94SStefano Zampini 473628143c3dSStefano Zampini /* restrict comm if requested */ 473728143c3dSStefano Zampini subcomm = 0; 473828143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 473928143c3dSStefano Zampini if (restrict_comm) { 4740779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 4741779c1cceSStefano Zampini 474228143c3dSStefano Zampini color = 0; 474353a05cb3SStefano Zampini if (restrict_full) { 474453a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 474553a05cb3SStefano Zampini } else { 474653a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 474753a05cb3SStefano Zampini } 474828143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 474928143c3dSStefano Zampini subcommsize = commsize - subcommsize; 475028143c3dSStefano Zampini /* check if reuse has been requested */ 475128143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 475228143c3dSStefano Zampini if (*mat_n) { 475328143c3dSStefano Zampini PetscMPIInt subcommsize2; 475428143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 475528143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 475628143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 475728143c3dSStefano Zampini } else { 475828143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 475928143c3dSStefano Zampini } 476028143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 4761779c1cceSStefano Zampini PetscMPIInt rank; 4762779c1cceSStefano Zampini 4763779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 476428143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 476528143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 476628143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4767306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 476828143c3dSStefano Zampini } 476928143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 477028143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 477128143c3dSStefano Zampini } else { 477228143c3dSStefano Zampini comm_n = comm; 477328143c3dSStefano Zampini } 477428143c3dSStefano Zampini 4775e7931f94SStefano Zampini /* prepare send/receive buffers */ 4776785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 4777e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 4778785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 4779e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 478028143c3dSStefano Zampini if (nis) { 4781854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 478228143c3dSStefano Zampini } 4783e7931f94SStefano Zampini 478428143c3dSStefano Zampini /* Get data from local matrices */ 4785e7931f94SStefano Zampini if (!isdense) { 4786a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 4787e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 4788e7931f94SStefano Zampini /* 4789e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 4790e7931f94SStefano Zampini send_buffer_idxs should contain: 4791e7931f94SStefano Zampini - MatType_PRIVATE type 4792e7931f94SStefano Zampini - PetscInt size_of_l2gmap 4793e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 4794e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 4795e7931f94SStefano Zampini */ 4796e7931f94SStefano Zampini } else { 4797e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 47983bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 4799854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 4800e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 4801e7931f94SStefano Zampini send_buffer_idxs[1] = i; 48023bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4803e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 48043bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4805e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 4806e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4807e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 4808e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 4809c8587f34SStefano Zampini } 4810c8587f34SStefano Zampini } 4811e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 481228143c3dSStefano Zampini /* additional is (if any) */ 481328143c3dSStefano Zampini if (nis) { 481428143c3dSStefano Zampini PetscMPIInt psum; 481528143c3dSStefano Zampini PetscInt j; 481628143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 481728143c3dSStefano Zampini PetscInt plen; 481828143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 481928143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 482028143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 482128143c3dSStefano Zampini } 4822854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 482328143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 482428143c3dSStefano Zampini PetscInt plen; 482528143c3dSStefano Zampini const PetscInt *is_array_idxs; 482628143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 482728143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 482828143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 482928143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 483028143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 483128143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 483228143c3dSStefano Zampini } 483328143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 483428143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 483528143c3dSStefano Zampini } 483628143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 483728143c3dSStefano Zampini } 483828143c3dSStefano Zampini 4839e7931f94SStefano Zampini buf_size_idxs = 0; 4840e7931f94SStefano Zampini buf_size_vals = 0; 484128143c3dSStefano Zampini buf_size_idxs_is = 0; 4842e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4843e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 4844e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 484528143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 4846e7931f94SStefano Zampini } 4847785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 4848785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 484995ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 4850e7931f94SStefano Zampini 4851e7931f94SStefano Zampini /* get new tags for clean communications */ 4852e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 4853e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 485428143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 4855e7931f94SStefano Zampini 4856e7931f94SStefano Zampini /* allocate for requests */ 4857785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 4858785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 485995ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 4860785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 4861785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 486295ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 4863e7931f94SStefano Zampini 4864e7931f94SStefano Zampini /* communications */ 4865e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4866e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 486728143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 4868e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4869e7931f94SStefano Zampini source_dest = onodes[i]; 4870e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 4871e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 4872e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4873e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 487428143c3dSStefano Zampini if (nis) { 487528143c3dSStefano 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); 487628143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 487728143c3dSStefano Zampini } 4878e7931f94SStefano Zampini } 4879e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4880e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 4881e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 4882e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 488328143c3dSStefano Zampini if (nis) { 488428143c3dSStefano 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); 488528143c3dSStefano Zampini } 4886e7931f94SStefano Zampini } 4887e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4888e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 4889e7931f94SStefano Zampini 4890e7931f94SStefano Zampini /* assemble new l2g map */ 4891e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4892e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 48939d30be91SStefano Zampini new_local_rows = 0; 4894e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 48959d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4896e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4897e7931f94SStefano Zampini } 48989d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 4899e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 49009d30be91SStefano Zampini new_local_rows = 0; 4901e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 49029d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 49039d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4904e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4905e7931f94SStefano Zampini } 49069d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 49079d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 4908e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 4909e7931f94SStefano Zampini 4910e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 4911e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 4912e7931f94SStefano 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) */ 4913e7931f94SStefano Zampini if (n_recvs) { 491428143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 4915e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4916e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4917e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 4918e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 4919e7931f94SStefano Zampini break; 4920e7931f94SStefano Zampini } 4921e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4922e7931f94SStefano Zampini } 4923e7931f94SStefano Zampini switch (new_local_type_private) { 492428143c3dSStefano Zampini case MATDENSE_PRIVATE: 492528143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 4926e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4927e7931f94SStefano Zampini bs = 1; 492828143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 492928143c3dSStefano Zampini new_local_type = MATSEQDENSE; 493028143c3dSStefano Zampini bs = 1; 493128143c3dSStefano Zampini } 4932e7931f94SStefano Zampini break; 4933e7931f94SStefano Zampini case MATAIJ_PRIVATE: 4934e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4935e7931f94SStefano Zampini bs = 1; 4936e7931f94SStefano Zampini break; 4937e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 4938e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 4939e7931f94SStefano Zampini break; 4940e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 4941e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 4942e7931f94SStefano Zampini break; 4943e7931f94SStefano Zampini default: 49449d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 4945e7931f94SStefano Zampini break; 4946e7931f94SStefano Zampini } 494728143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 494828143c3dSStefano Zampini new_local_type = MATSEQDENSE; 494928143c3dSStefano Zampini bs = 1; 4950e7931f94SStefano Zampini } 4951e7931f94SStefano Zampini 495270cf5478SStefano Zampini /* create MATIS object if needed */ 495370cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 4954e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 4955e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 495670cf5478SStefano Zampini } else { 495770cf5478SStefano Zampini /* it also destroys the local matrices */ 495870cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 495970cf5478SStefano Zampini } 496070cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 4961e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 49629d30be91SStefano Zampini 49639d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 49649d30be91SStefano Zampini 49659d30be91SStefano Zampini /* Global to local map of received indices */ 49669d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 49679d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 49689d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 49699d30be91SStefano Zampini 49709d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 49719d30be91SStefano Zampini buf_size_idxs = 0; 49729d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 49739d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 49749d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 49759d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 49769d30be91SStefano Zampini } 49779d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 49789d30be91SStefano Zampini 49799d30be91SStefano Zampini /* set preallocation */ 49809d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 49819d30be91SStefano Zampini if (!newisdense) { 49829d30be91SStefano Zampini PetscInt *new_local_nnz=0; 49839d30be91SStefano Zampini 49849d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 49859d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 49869d30be91SStefano Zampini if (n_recvs) { 49879d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 49889d30be91SStefano Zampini } 49899d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 49909d30be91SStefano Zampini PetscInt j; 49919d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 49929d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 49939d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 49949d30be91SStefano Zampini } 49959d30be91SStefano Zampini } else { 49969d30be91SStefano Zampini /* TODO */ 49979d30be91SStefano Zampini } 49989d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 49999d30be91SStefano Zampini } 50009d30be91SStefano Zampini if (new_local_nnz) { 50019d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 50029d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 50039d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 50049d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 50059d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 50069d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 50079d30be91SStefano Zampini } else { 50089d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 50099d30be91SStefano Zampini } 50109d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 50119d30be91SStefano Zampini } else { 50129d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 50139d30be91SStefano Zampini } 5014e7931f94SStefano Zampini 5015e7931f94SStefano Zampini /* set values */ 5016e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 50179d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 5018e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5019e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 5020e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 50219d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 5022e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5023e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5024e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 502528143c3dSStefano Zampini } else { 502628143c3dSStefano Zampini /* TODO */ 5027e7931f94SStefano Zampini } 5028e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5029e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 5030e7931f94SStefano Zampini } 5031e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5032e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 503370cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 503470cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 50359d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 50369d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 5037e7931f94SStefano Zampini 5038dfd14d43SStefano Zampini #if 0 503928143c3dSStefano Zampini if (!restrict_comm) { /* check */ 5040e7931f94SStefano Zampini Vec lvec,rvec; 5041e7931f94SStefano Zampini PetscReal infty_error; 5042e7931f94SStefano Zampini 50432a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 5044e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 5045e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 5046e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 504770cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 5048e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 5049e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 5050e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 5051e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 5052e7931f94SStefano Zampini } 505328143c3dSStefano Zampini #endif 5054e7931f94SStefano Zampini 505528143c3dSStefano Zampini /* assemble new additional is (if any) */ 505628143c3dSStefano Zampini if (nis) { 505728143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 505828143c3dSStefano Zampini 505928143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5060854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 506128143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 506228143c3dSStefano Zampini psum = 0; 506328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 506428143c3dSStefano Zampini for (j=0;j<nis;j++) { 506528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 506628143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 506728143c3dSStefano Zampini psum += plen; 506828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 506928143c3dSStefano Zampini } 507028143c3dSStefano Zampini } 5071854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 5072854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 507328143c3dSStefano Zampini for (i=1;i<nis;i++) { 507428143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 507528143c3dSStefano Zampini } 507628143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 507728143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 507828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 507928143c3dSStefano Zampini for (j=0;j<nis;j++) { 508028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 508128143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 508228143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 508328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 508428143c3dSStefano Zampini } 508528143c3dSStefano Zampini } 508628143c3dSStefano Zampini for (i=0;i<nis;i++) { 508728143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 508828143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 508928143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 509028143c3dSStefano Zampini } 509128143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 509228143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 509328143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 509428143c3dSStefano Zampini } 5095e7931f94SStefano Zampini /* free workspace */ 509628143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 5097e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5098e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 5099e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5100e7931f94SStefano Zampini if (isdense) { 5101e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5102e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 5103e7931f94SStefano Zampini } else { 5104e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 5105e7931f94SStefano Zampini } 510628143c3dSStefano Zampini if (nis) { 510728143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 510828143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 510928143c3dSStefano Zampini } 5110e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 5111e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 511228143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 5113e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 5114e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 511528143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 5116e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 5117e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 5118e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 5119e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 5120e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 512128143c3dSStefano Zampini if (nis) { 512228143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 512328143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 512428143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 512528143c3dSStefano Zampini } 512628143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 512728143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 512828143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 512928143c3dSStefano Zampini for (i=0;i<nis;i++) { 513028143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 513128143c3dSStefano Zampini } 513253a05cb3SStefano Zampini *mat_n = NULL; 513328143c3dSStefano Zampini } 5134e7931f94SStefano Zampini PetscFunctionReturn(0); 5135e7931f94SStefano Zampini } 5136a57a6d2fSStefano Zampini 513712edc857SStefano Zampini /* temporary hack into ksp private data structure */ 5138af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 513912edc857SStefano Zampini 5140c8587f34SStefano Zampini #undef __FUNCT__ 5141c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 5142c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 5143c8587f34SStefano Zampini { 5144c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5145c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 514620a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 51479881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 514820a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 51496e683305SStefano Zampini IS coarse_is,*isarray; 51506e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 515130368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 5152f9eb5b7dSStefano Zampini PC pc_temp; 5153c8587f34SStefano Zampini PCType coarse_pc_type; 5154c8587f34SStefano Zampini KSPType coarse_ksp_type; 5155f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 51564f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 51576e683305SStefano Zampini Mat t_coarse_mat_is; 51586e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 51596e683305SStefano Zampini PetscMPIInt all_procs; 516074e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 516168457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 516222bc73bbSStefano Zampini PetscScalar *array; 51639881197aSStefano Zampini PetscErrorCode ierr; 5164fdc09c96SStefano Zampini 5165c8587f34SStefano Zampini PetscFunctionBegin; 5166c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 516768457ee5SStefano 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 */ 5168fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 51695a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 5170fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 5171f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 5172f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 5173f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 5174fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 517551bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 517651bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 5177dc4bcba2SStefano Zampini PC pc; 5178dc4bcba2SStefano Zampini PetscBool isbddc; 5179dc4bcba2SStefano Zampini 5180dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 5181dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 5182dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 5183dc4bcba2SStefano Zampini if (isbddc) { 5184dc4bcba2SStefano Zampini ierr = PCDestroy(&pc);CHKERRQ(ierr); 5185dc4bcba2SStefano Zampini } 5186727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 5187fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5188fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 5189fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5190f4ddd8eeSStefano Zampini } 5191fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 5192fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5193f4ddd8eeSStefano Zampini } 519470cf5478SStefano Zampini /* reset any subassembling information */ 519570cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 51966e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 51976e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 5198fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5199f4ddd8eeSStefano Zampini } 5200c8587f34SStefano Zampini 52016e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 52022b510759SStefano Zampini im_active = !!(pcis->n); 52032b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 52046e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 52056e683305SStefano Zampini void_procs = all_procs-active_procs; 52066e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 520774e2c79eSStefano Zampini redist = PETSC_FALSE; 520822bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 52096e683305SStefano Zampini csin_ml = PETSC_TRUE; 52106e683305SStefano Zampini ncoarse_ml = void_procs; 5211779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 5212779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 52136e683305SStefano Zampini csin_ds = PETSC_TRUE; 521418a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 521518a45a71SStefano Zampini redist = PETSC_TRUE; 521618a45a71SStefano Zampini } else { 52176e683305SStefano Zampini csin_ds = PETSC_TRUE; 5218779c1cceSStefano Zampini ncoarse_ds = active_procs; 5219779c1cceSStefano Zampini redist = PETSC_TRUE; 522018a45a71SStefano Zampini } 52216e683305SStefano Zampini } else { 52226e683305SStefano Zampini csin_ml = PETSC_FALSE; 52236e683305SStefano Zampini ncoarse_ml = all_procs; 52246e683305SStefano Zampini if (void_procs) { 52256e683305SStefano Zampini csin_ds = PETSC_TRUE; 52266e683305SStefano Zampini ncoarse_ds = void_procs; 52276e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 52286e683305SStefano Zampini } else { 5229779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 523074e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 523174e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 523274e2c79eSStefano Zampini redist = PETSC_TRUE; 523374e2c79eSStefano Zampini } else { 52346e683305SStefano Zampini csin_ds = PETSC_FALSE; 52356e683305SStefano Zampini ncoarse_ds = all_procs; 52366e683305SStefano Zampini } 52376e683305SStefano Zampini } 523874e2c79eSStefano Zampini } 52396e683305SStefano Zampini 52406e683305SStefano Zampini /* 52416e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 52426e683305SStefano Zampini - we have not exceeded the number of levels requested 52436e683305SStefano Zampini - we can actually subassemble the active processes 52446e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 52456e683305SStefano Zampini */ 52466e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 52476e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 52486e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 52496e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 52506e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 5251f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 52522b510759SStefano Zampini } else { 5253f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 5254c8587f34SStefano Zampini } 5255c8587f34SStefano Zampini } 52566e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 52576e683305SStefano Zampini if (multilevel_allowed) { 52586e683305SStefano Zampini ncoarse = ncoarse_ml; 52596e683305SStefano Zampini csin = csin_ml; 526058da7f69SStefano Zampini redist = PETSC_FALSE; 52616e683305SStefano Zampini } else { 52626e683305SStefano Zampini ncoarse = ncoarse_ds; 52636e683305SStefano Zampini csin = csin_ds; 52646e683305SStefano Zampini } 5265e7931f94SStefano Zampini 5266abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 5267abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 5268abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 5269abbbba34SStefano Zampini 5270abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 527122bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 527222bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 527322bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 527422bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 5275e176bc59SStefano 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); 52766e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 52776e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 52786e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5279abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 5280abbbba34SStefano Zampini 52816e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 528230368db7SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local))) { /* protects from unneded computations */ 52836e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 52846e683305SStefano Zampini const PetscInt *idxs; 52856e683305SStefano Zampini ISLocalToGlobalMapping tmap; 52866e683305SStefano Zampini 52876e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 52880be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 52896e683305SStefano Zampini /* allocate space for temporary storage */ 5290854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 5291854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 52926e683305SStefano Zampini /* allocate for IS array */ 52936e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 52946e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 529530368db7SStefano Zampini nisvert = 0; 529630368db7SStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local) { 529730368db7SStefano Zampini nisvert = 1; 529830368db7SStefano Zampini } 529930368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 5300854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 53016e683305SStefano Zampini /* dofs splitting */ 53026e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 53036e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 53046e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 53056e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 53066e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 53076e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 53086e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 530930368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 53106e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 53116e683305SStefano Zampini } 53126e683305SStefano Zampini /* neumann boundaries */ 53136e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 53146e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 53156e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 53166e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 53176e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 53186e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 53196e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 532030368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 53216e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 53226e683305SStefano Zampini } 532330368db7SStefano Zampini /* primal vertices (benign) */ 532430368db7SStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local) { 532530368db7SStefano Zampini ierr = ISGetLocalSize(pcbddc->user_primal_vertices_local,&tsize);CHKERRQ(ierr); 532630368db7SStefano Zampini ierr = ISGetIndices(pcbddc->user_primal_vertices_local,&idxs);CHKERRQ(ierr); 532730368db7SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 532830368db7SStefano Zampini ierr = ISRestoreIndices(pcbddc->user_primal_vertices_local,&idxs);CHKERRQ(ierr); 532930368db7SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 533030368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nis-1]);CHKERRQ(ierr); 533130368db7SStefano Zampini } 53326e683305SStefano Zampini /* free memory */ 53336e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 53346e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 53356e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 53366e683305SStefano Zampini } else { 53376e683305SStefano Zampini nis = 0; 53386e683305SStefano Zampini nisdofs = 0; 53396e683305SStefano Zampini nisneu = 0; 534030368db7SStefano Zampini nisvert = 0; 53416e683305SStefano Zampini isarray = NULL; 53426e683305SStefano Zampini } 53436e683305SStefano Zampini /* destroy no longer needed map */ 53446e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 53456e683305SStefano Zampini 53466e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 53476e683305SStefano Zampini coarse_mat_is = NULL; 53486e683305SStefano Zampini if (csin) { 53496e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 535074e2c79eSStefano Zampini if (redist) { 535174e2c79eSStefano Zampini PetscMPIInt rank; 5352779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 535374e2c79eSStefano Zampini 535474e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 535558da7f69SStefano Zampini spc = active_procs/ncoarse; 535658da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 5357779c1cceSStefano Zampini if (im_active) { 5358779c1cceSStefano Zampini destsize = 1; 535974e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 536074e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 536174e2c79eSStefano Zampini } else { 536274e2c79eSStefano Zampini dest[0] = rank/(spc+1); 536374e2c79eSStefano Zampini } 536474e2c79eSStefano Zampini } else { 5365779c1cceSStefano Zampini destsize = 0; 53666e683305SStefano Zampini } 5367779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 5368779c1cceSStefano Zampini } else if (csin_type_simple) { 53696e683305SStefano Zampini PetscMPIInt rank; 53706e683305SStefano Zampini PetscInt issize,isidx; 5371779c1cceSStefano Zampini 53726e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 53736e683305SStefano Zampini if (im_active) { 53746e683305SStefano Zampini issize = 1; 53756e683305SStefano Zampini isidx = (PetscInt)rank; 53766e683305SStefano Zampini } else { 53776e683305SStefano Zampini issize = 0; 53786e683305SStefano Zampini isidx = -1; 53796e683305SStefano Zampini } 53806e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 5381779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 5382b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 53836e683305SStefano Zampini } 5384779c1cceSStefano Zampini 5385779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 5386779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 5387779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 5388779c1cceSStefano Zampini PetscInt *coarse_candidates; 5389779c1cceSStefano Zampini const PetscInt* tisindices; 5390779c1cceSStefano Zampini 5391779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 5392779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 5393779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5394779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 5395779c1cceSStefano Zampini if (!coarse_candidates[i]) { 5396779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 5397779c1cceSStefano Zampini } 5398779c1cceSStefano Zampini } 5399779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 5400779c1cceSStefano Zampini 5401779c1cceSStefano Zampini 54026e683305SStefano Zampini if (pcbddc->dbg_flag) { 54036e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54046e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 54056e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 54066e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 5407779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 54086e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 54096e683305SStefano Zampini } 54106e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 54116e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54126e683305SStefano Zampini } 54136e683305SStefano Zampini /* shift the pattern on coarse candidates */ 54146e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 54156e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 5416854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 54176e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 54186e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 54196e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 54206e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 54216e683305SStefano Zampini } 54226e683305SStefano Zampini if (pcbddc->dbg_flag) { 54236e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54246e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 54256e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 54266e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54276e683305SStefano Zampini } 5428779c1cceSStefano Zampini } 54296e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 543053a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 543153a05cb3SStefano 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); 543253a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 543353a05cb3SStefano 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); 543453a05cb3SStefano Zampini } 54356e683305SStefano Zampini } else { 54366e683305SStefano Zampini if (pcbddc->dbg_flag) { 54376e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54386e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 54396e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54406e683305SStefano Zampini } 54416e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 54426e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 54436e683305SStefano Zampini } 54446e683305SStefano Zampini 54456e683305SStefano Zampini /* create local to global scatters for coarse problem */ 544668457ee5SStefano Zampini if (compute_vecs) { 54476e683305SStefano Zampini PetscInt lrows; 54486e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 54496e683305SStefano Zampini if (coarse_mat_is) { 54506e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 54516e683305SStefano Zampini } else { 54526e683305SStefano Zampini lrows = 0; 54536e683305SStefano Zampini } 54546e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 54556e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 54566e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 54576e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 54586e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 54596e683305SStefano Zampini } 54606e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 54616e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 5462c8587f34SStefano Zampini 5463f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 5464f9eb5b7dSStefano Zampini if (multilevel_allowed) { 5465f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 5466f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 5467f9eb5b7dSStefano Zampini } else { 5468f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 5469f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 5470c8587f34SStefano Zampini } 5471c8587f34SStefano Zampini 54726e683305SStefano Zampini /* print some info if requested */ 54736e683305SStefano Zampini if (pcbddc->dbg_flag) { 54746e683305SStefano Zampini if (!multilevel_allowed) { 54756e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54766e683305SStefano Zampini if (multilevel_requested) { 54776e683305SStefano 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); 54786e683305SStefano Zampini } else if (pcbddc->max_levels) { 54796e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 54806e683305SStefano Zampini } 54816e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54826e683305SStefano Zampini } 54836e683305SStefano Zampini } 54846e683305SStefano Zampini 5485f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 54866e683305SStefano Zampini if (coarse_mat_is) { 54876e683305SStefano Zampini MatReuse coarse_mat_reuse; 54886a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 54896e683305SStefano Zampini if (pcbddc->dbg_flag) { 54906e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 54916e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 54926e683305SStefano Zampini } 5493f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 5494312be037SStefano Zampini char prefix[256],str_level[16]; 5495e604994aSStefano Zampini size_t len; 54966e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 5497422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 5498c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5499f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 55005f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 5501c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 55026e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 5503c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 5504c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5505e604994aSStefano Zampini /* prefix */ 5506e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 5507e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 5508e604994aSStefano Zampini if (!pcbddc->current_level) { 5509e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5510e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 5511c8587f34SStefano Zampini } else { 5512e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5513312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5514312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 551534d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5516312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 5517e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 5518e604994aSStefano Zampini } 5519e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 55203e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 55213e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 55223e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 55233e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 5524f9eb5b7dSStefano Zampini /* allow user customization */ 5525f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 55263e3c6dadSStefano Zampini } 55273e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 552851bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 55293e3c6dadSStefano Zampini if (nisdofs) { 55303e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 55313e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 55323e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 55333e3c6dadSStefano Zampini } 55343e3c6dadSStefano Zampini } 55353e3c6dadSStefano Zampini if (nisneu) { 55363e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 55373e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 5538312be037SStefano Zampini } 553930368db7SStefano Zampini if (nisvert) { 554030368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 554130368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 554230368db7SStefano Zampini } 5543f9eb5b7dSStefano Zampini 5544f9eb5b7dSStefano Zampini /* get some info after set from options */ 5545f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 5546f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 55474f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 55486e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 5549f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5550f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 5551f9eb5b7dSStefano Zampini } 555239f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 55534f3a063dSStefano Zampini if (isredundant) { 55544f3a063dSStefano Zampini KSP inner_ksp; 55554f3a063dSStefano Zampini PC inner_pc; 55564f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 55574f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 55584f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 55594f3a063dSStefano Zampini } 5560f9eb5b7dSStefano Zampini 5561f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 5562fa7f1dd8SStefano Zampini if (coarse_reuse) { 556381d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 5564fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 55656e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 5566fa7f1dd8SStefano Zampini } else { 55676e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 5568fa7f1dd8SStefano Zampini } 5569c8587f34SStefano Zampini if (isbddc || isnn) { 5570*d4d8cf7bSStefano Zampini if (isbddc) { /* currently there's no API for this */ 5571*d4d8cf7bSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc_temp->data; 5572*d4d8cf7bSStefano Zampini pcbddc->detect_disconnected = PETSC_TRUE; 5573*d4d8cf7bSStefano Zampini } 557422bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 557570cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 5576b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 557722b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 55786e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 55796e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 55806e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 55816e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 558222b6e8a2SStefano Zampini } 558370cf5478SStefano Zampini } 558453a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 558570cf5478SStefano Zampini } else { 558622bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 558722bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 558822bc73bbSStefano Zampini } 558922bc73bbSStefano Zampini } else { 55902e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 5591c8587f34SStefano Zampini } 5592c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 5593c8587f34SStefano Zampini 55943301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 55955a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 55963301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 55973301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 55983301b35fSStefano Zampini } 55993301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 56003301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 56013301b35fSStefano Zampini } 56023301b35fSStefano Zampini if (pc->pmat->spd_set) { 56033301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 56043301b35fSStefano Zampini } 56056e683305SStefano Zampini /* set operators */ 56065f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 56076e683305SStefano Zampini if (pcbddc->dbg_flag) { 56086e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 56096e683305SStefano Zampini } 56106e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 56116e683305SStefano Zampini coarse_mat = 0; 56126e683305SStefano Zampini } 56136e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 5614b1ecc7b1SStefano Zampini #if 0 5615b9b85e73SStefano Zampini { 5616b9b85e73SStefano Zampini PetscViewer viewer; 5617b9b85e73SStefano Zampini char filename[256]; 5618b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 5619b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 5620b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5621b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 5622b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5623b9b85e73SStefano Zampini } 5624b9b85e73SStefano Zampini #endif 5625c8587f34SStefano Zampini 5626c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 5627298c0119SStefano Zampini #if 0 5628c8587f34SStefano Zampini if (pcbddc->NullSpace) { 5629c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 563098a51de6SStefano Zampini } 5631298c0119SStefano Zampini #endif 5632b0f5fe93SStefano Zampini /* hack */ 563398a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 563498a51de6SStefano Zampini Vec crhs,csol; 563504708bb6SStefano Zampini 5636f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 5637f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 5638f347579bSStefano Zampini if (!csol) { 56392a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 5640f9eb5b7dSStefano Zampini } 5641f347579bSStefano Zampini if (!crhs) { 56422a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 5643f347579bSStefano Zampini } 5644b0f5fe93SStefano Zampini } 5645b0f5fe93SStefano Zampini 5646b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 5647b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 5648b0f5fe93SStefano Zampini 5649b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 56504f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 56514f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 56524f1b2e48SStefano Zampini } 5653b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 5654b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 5655b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5656b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5657b0f5fe93SStefano Zampini if (coarse_mat) { 5658b0f5fe93SStefano Zampini Vec nullv; 5659b0f5fe93SStefano Zampini PetscScalar *array,*array2; 5660b0f5fe93SStefano Zampini PetscInt nl; 5661b0f5fe93SStefano Zampini 5662b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 5663b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 5664b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5665b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 5666b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 5667b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 5668b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5669b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 5670b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 5671b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 5672b0f5fe93SStefano Zampini } 5673b0f5fe93SStefano Zampini } 5674b0f5fe93SStefano Zampini 5675b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 5676b0f5fe93SStefano Zampini PetscBool ispreonly; 5677b0f5fe93SStefano Zampini 5678b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5679b0f5fe93SStefano Zampini PetscBool isnull; 5680b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 5681*d4d8cf7bSStefano Zampini if (0) { 568230368db7SStefano Zampini if (isbddc && !pcbddc->benign_saddle_point) { 5683b0f5fe93SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 5684b0f5fe93SStefano Zampini } else { 5685b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 5686b0f5fe93SStefano Zampini } 5687b0f5fe93SStefano Zampini } else { 5688b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5689b0f5fe93SStefano Zampini } 5690b0f5fe93SStefano Zampini } 5691b0f5fe93SStefano Zampini /* setup coarse ksp */ 5692b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 5693cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 5694cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 56956e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 5696c8587f34SStefano Zampini KSP check_ksp; 56972b510759SStefano Zampini KSPType check_ksp_type; 5698c8587f34SStefano Zampini PC check_pc; 56996e683305SStefano Zampini Vec check_vec,coarse_vec; 57006a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 57012b510759SStefano Zampini PetscInt its; 57026e683305SStefano Zampini PetscBool compute_eigs; 57036e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 57046e683305SStefano Zampini PetscInt neigs; 57058e185a42SStefano Zampini const char *prefix; 5706c8587f34SStefano Zampini 57072b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 57086e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 5709422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 571023ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 5711f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 57122b510759SStefano Zampini if (ispreonly) { 57132b510759SStefano Zampini check_ksp_type = KSPPREONLY; 57146e683305SStefano Zampini compute_eigs = PETSC_FALSE; 57152b510759SStefano Zampini } else { 5716cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 57176e683305SStefano Zampini compute_eigs = PETSC_TRUE; 5718c8587f34SStefano Zampini } 5719c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 57206e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 57216e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 57226e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 5723a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 5724a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 5725a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 5726a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 5727c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 5728c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 5729c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 5730c8587f34SStefano Zampini /* create random vec */ 57316e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 57326e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 5733c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 5734c8587f34SStefano Zampini if (CoarseNullSpace) { 5735c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 5736c8587f34SStefano Zampini } 57376e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 5738c8587f34SStefano Zampini /* solve coarse problem */ 57396e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 5740c8587f34SStefano Zampini if (CoarseNullSpace) { 57416e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 5742c8587f34SStefano Zampini } 5743cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 57446e683305SStefano Zampini if (compute_eigs) { 5745854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 5746854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 57476e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 57486e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 57496e683305SStefano Zampini lambda_min = eigs_r[0]; 57506e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 57516e683305SStefano Zampini if (lambda_max>lambda_min) { 5752cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 5753cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 5754cbcc2c2aSStefano Zampini } 5755c8587f34SStefano Zampini } 5756c8587f34SStefano Zampini } 5757cbcc2c2aSStefano Zampini 5758c8587f34SStefano Zampini /* check coarse problem residual error */ 57596e683305SStefano Zampini if (pcbddc->dbg_flag) { 57606e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 57616e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 57626e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 5763c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 57646e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 57656e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 5766c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 5767779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 57686e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 57696e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 57706e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 57716e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 5772b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5773b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 5774b0f5fe93SStefano Zampini } 57756e683305SStefano Zampini if (compute_eigs) { 57766e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 5777deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 5778c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 57796e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 57806e683305SStefano 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); 57816e683305SStefano Zampini for (i=0;i<neigs;i++) { 57826e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 5783c8587f34SStefano Zampini } 57846e683305SStefano Zampini } 57856e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 57866e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 57876e683305SStefano Zampini } 5788c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 57896e683305SStefano Zampini if (compute_eigs) { 57906e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 57916e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 5792c8587f34SStefano Zampini } 57936e683305SStefano Zampini } 57946e683305SStefano Zampini } 5795cbcc2c2aSStefano Zampini /* print additional info */ 5796cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 57976e683305SStefano Zampini /* waits until all processes reaches this point */ 57986e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 5799cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 5800cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5801cbcc2c2aSStefano Zampini } 5802cbcc2c2aSStefano Zampini 58032b510759SStefano Zampini /* free memory */ 5804c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5805fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 5806c8587f34SStefano Zampini PetscFunctionReturn(0); 5807c8587f34SStefano Zampini } 5808674ae819SStefano Zampini 5809f34684f1SStefano Zampini #undef __FUNCT__ 5810f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 5811f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 5812f34684f1SStefano Zampini { 5813f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5814f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 5815f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5816dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 5817dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 581873be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 5819dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 5820f34684f1SStefano Zampini PetscErrorCode ierr; 5821f34684f1SStefano Zampini 5822f34684f1SStefano Zampini PetscFunctionBegin; 5823f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 58240e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 58250e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 5826727cdba6SStefano Zampini } 5827dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 58283bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 5829dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5830dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 5831dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 5832dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 5833dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 5834dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 58350e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 58360e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 58370e6343abSStefano Zampini } 5838dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 5839dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5840dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 5841dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5842dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5843f34684f1SStefano Zampini 5844f34684f1SStefano Zampini /* check numbering */ 5845f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 5846019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 5847dc456d91SStefano Zampini PetscInt i; 5848b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 5849f34684f1SStefano Zampini 5850f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5851f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5852f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 58531575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5854019a44ceSStefano Zampini /* counter */ 5855019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5856019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5857019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5858019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5859019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5860019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5861f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 5862f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 5863727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5864f34684f1SStefano Zampini } 5865f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5866f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5867f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5868e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5869e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5870e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5871e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5872f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5873019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5874f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5875019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 587675c01103SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]); 587775c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 5878b9b85e73SStefano Zampini set_error = PETSC_TRUE; 5879019a44ceSStefano 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); 5880f34684f1SStefano Zampini } 5881f34684f1SStefano Zampini } 5882019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5883b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5884f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5885f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5886f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 5887f34684f1SStefano Zampini } 5888f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5889f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5890e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5891e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5892f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 5893f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 5894b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 5895ca8b9ea9SStefano Zampini PetscInt *gidxs; 5896ca8b9ea9SStefano Zampini 5897ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 58983bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 5899f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 5900f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5901f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5902f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 59034bc2dc4bSStefano 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); 5904f34684f1SStefano Zampini } 5905f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5906ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 5907f34684f1SStefano Zampini } 5908f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 59091575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5910302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 5911f34684f1SStefano Zampini } 59128bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 5913f34684f1SStefano Zampini /* get back data */ 5914f34684f1SStefano Zampini *coarse_size_n = coarse_size; 5915f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 5916674ae819SStefano Zampini PetscFunctionReturn(0); 5917674ae819SStefano Zampini } 5918674ae819SStefano Zampini 5919e456f2a8SStefano Zampini #undef __FUNCT__ 5920e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 5921a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 5922e456f2a8SStefano Zampini { 5923e456f2a8SStefano Zampini IS localis_t; 5924a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 5925e456f2a8SStefano Zampini PetscScalar *vals; 5926e456f2a8SStefano Zampini PetscErrorCode ierr; 5927e456f2a8SStefano Zampini 5928e456f2a8SStefano Zampini PetscFunctionBegin; 5929a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 5930e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 5931854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 5932e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 5933e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5934a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 5935a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 59361035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 5937a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 59381035eff8SStefano Zampini } 5939a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 5940e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5941e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5942a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 5943a7dc3881SStefano Zampini /* now compute set in local ordering */ 5944a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5945a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5946a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5947a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 5948a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5949ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5950e456f2a8SStefano Zampini lsize++; 5951e456f2a8SStefano Zampini } 5952e456f2a8SStefano Zampini } 5953854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 5954a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5955ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5956e456f2a8SStefano Zampini idxs[lsize++] = i; 5957e456f2a8SStefano Zampini } 5958e456f2a8SStefano Zampini } 5959a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5960a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 5961e456f2a8SStefano Zampini *localis = localis_t; 5962e456f2a8SStefano Zampini PetscFunctionReturn(0); 5963e456f2a8SStefano Zampini } 5964906d46d4SStefano Zampini 5965906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 5966906d46d4SStefano Zampini #undef __FUNCT__ 5967906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 5968906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 5969906d46d4SStefano Zampini { 5970906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5971906d46d4SStefano Zampini PetscErrorCode ierr; 5972906d46d4SStefano Zampini 5973906d46d4SStefano Zampini PetscFunctionBegin; 5974906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5975906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5976906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5977906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5978906d46d4SStefano Zampini PetscFunctionReturn(0); 5979906d46d4SStefano Zampini } 5980906d46d4SStefano Zampini 5981906d46d4SStefano Zampini #undef __FUNCT__ 5982906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 5983906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 5984906d46d4SStefano Zampini { 5985906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5986906d46d4SStefano Zampini PetscErrorCode ierr; 5987906d46d4SStefano Zampini 5988906d46d4SStefano Zampini PetscFunctionBegin; 5989906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5990906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5991906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5992906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5993906d46d4SStefano Zampini PetscFunctionReturn(0); 5994906d46d4SStefano Zampini } 5995b96c3477SStefano Zampini 5996b96c3477SStefano Zampini #undef __FUNCT__ 5997b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 599808122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 5999b96c3477SStefano Zampini { 6000a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6001b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6002b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6003a64f4aa4SStefano Zampini Mat S_j; 6004b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 6005b96c3477SStefano Zampini PetscBool free_used_adj; 6006b96c3477SStefano Zampini PetscErrorCode ierr; 6007b96c3477SStefano Zampini 6008b96c3477SStefano Zampini PetscFunctionBegin; 6009b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 6010b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 601108122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 6012b96c3477SStefano Zampini used_xadj = NULL; 6013b96c3477SStefano Zampini used_adjncy = NULL; 6014b96c3477SStefano Zampini } else { 601508122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 601608122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 601708122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 601808122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 6019b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 6020b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 6021b96c3477SStefano Zampini } else { 60222fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 6023b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 6024b96c3477SStefano Zampini PetscInt nvtxs; 6025b96c3477SStefano Zampini 60262fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 60272fffb893SStefano Zampini if (flg_row) { 6028b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 6029b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 6030b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 6031b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 60322fffb893SStefano Zampini } else { 60332fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 60342fffb893SStefano Zampini used_xadj = NULL; 60352fffb893SStefano Zampini used_adjncy = NULL; 60362fffb893SStefano Zampini } 60372fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 6038b96c3477SStefano Zampini } 6039b96c3477SStefano Zampini } 6040d5574798SStefano Zampini 6041d5574798SStefano Zampini /* setup sub_schurs data */ 6042a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6043df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 6044df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 6045a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6046ca92afb2SStefano 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); 6047a64f4aa4SStefano Zampini } else { 60486816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 604904708bb6SStefano Zampini PetscBool isseqaij; 6050a3df083aSStefano Zampini PetscInt benign_n; 6051a3df083aSStefano Zampini 60525feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 60535feab87aSStefano Zampini PetscInt n_vertices; 60545feab87aSStefano Zampini 60555feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 60562034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 60575feab87aSStefano Zampini } 605804708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 605904708bb6SStefano Zampini if (!isseqaij) { 606004708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 606104708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 606204708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 606304708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 606404708bb6SStefano Zampini } else { 606504708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 606604708bb6SStefano Zampini } 606704708bb6SStefano Zampini } 6068a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 6069a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 6070ca92afb2SStefano Zampini } else { 6071a3df083aSStefano Zampini benign_n = 0; 6072ca92afb2SStefano Zampini } 6073a3df083aSStefano 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); 6074ca92afb2SStefano Zampini } 6075d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6076b96c3477SStefano Zampini 6077b96c3477SStefano Zampini /* free adjacency */ 6078b96c3477SStefano Zampini if (free_used_adj) { 6079b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 6080b96c3477SStefano Zampini } 6081b96c3477SStefano Zampini PetscFunctionReturn(0); 6082b96c3477SStefano Zampini } 6083b96c3477SStefano Zampini 6084b96c3477SStefano Zampini #undef __FUNCT__ 6085b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 608608122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 6087b96c3477SStefano Zampini { 6088b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6089b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6090b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6091b96c3477SStefano Zampini PCBDDCGraph graph; 6092b96c3477SStefano Zampini PetscErrorCode ierr; 6093b96c3477SStefano Zampini 6094b96c3477SStefano Zampini PetscFunctionBegin; 6095b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 609608122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 60973301b35fSStefano Zampini IS verticesIS,verticescomm; 60983301b35fSStefano Zampini PetscInt vsize,*idxs; 6099b96c3477SStefano Zampini 6100b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 61013301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 61023301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 61033301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 61043301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 61053301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 6106b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 61077fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 61083301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 61093301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 6110b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 6111b96c3477SStefano Zampini /* 6112b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 6113b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6114b96c3477SStefano Zampini } 6115b96c3477SStefano Zampini */ 6116b96c3477SStefano Zampini } else { 6117b96c3477SStefano Zampini graph = pcbddc->mat_graph; 6118b96c3477SStefano Zampini } 6119b96c3477SStefano Zampini 6120b96c3477SStefano Zampini /* sub_schurs init */ 6121a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 6122a64f4aa4SStefano Zampini 6123b96c3477SStefano Zampini /* free graph struct */ 612408122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 6125b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6126b96c3477SStefano Zampini } 6127b96c3477SStefano Zampini PetscFunctionReturn(0); 6128b96c3477SStefano Zampini } 6129fa34dd3eSStefano Zampini 6130fa34dd3eSStefano Zampini #undef __FUNCT__ 6131fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 6132fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 6133fa34dd3eSStefano Zampini { 6134fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6135fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6136fa34dd3eSStefano Zampini PetscErrorCode ierr; 6137fa34dd3eSStefano Zampini 6138fa34dd3eSStefano Zampini PetscFunctionBegin; 6139fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 6140fa34dd3eSStefano Zampini IS zerodiag = NULL; 61414f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 6142fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 61434f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 614475c01103SStefano Zampini PetscReal norm; 6145fa34dd3eSStefano Zampini PetscInt i; 6146fa34dd3eSStefano Zampini 6147fa34dd3eSStefano Zampini /* B0 and B0_B */ 6148fa34dd3eSStefano Zampini if (zerodiag) { 6149fa34dd3eSStefano Zampini IS dummy; 6150fa34dd3eSStefano Zampini 61514f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 61524f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 6153fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 6154fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 6155fa34dd3eSStefano Zampini } 6156fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 6157fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 6158fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 6159fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6160fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6161fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6162fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6163fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 6164fa34dd3eSStefano Zampini /* S_j */ 6165fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6166fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6167fa34dd3eSStefano Zampini 6168fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 6169fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 6170fa34dd3eSStefano Zampini /* continuous in primal space */ 6171fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 6172fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6173fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6174fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 61754f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 61764f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 6177fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6178fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6179fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6180fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6181fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6182fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6183fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 6184fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 6185fa34dd3eSStefano Zampini 6186fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 6187fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 6188fa34dd3eSStefano Zampini /* local with Schur */ 6189fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 6190fa34dd3eSStefano Zampini if (zerodiag) { 6191fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 61924f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 6193fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6194fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 6195fa34dd3eSStefano Zampini } 6196fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 6197fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6198fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6199fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6200fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6201fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 6202fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6203fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6204fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 6205fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6206fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6207fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6208fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6209fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6210fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 6211fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 6212fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6213fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6214fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6215fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6216fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6217fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6218fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 6219fa34dd3eSStefano Zampini if (zerodiag) { 6220fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 6221fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 62224f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 6223fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6224fa34dd3eSStefano Zampini } 6225fa34dd3eSStefano Zampini /* BDDC */ 6226fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 6227fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 6228fa34dd3eSStefano Zampini 6229fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 6230fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 6231fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 6232fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 62334f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 62344f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 6235fa34dd3eSStefano Zampini } 62364f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 6237fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 6238fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 6239fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 6240fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6241fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 6242fa34dd3eSStefano Zampini } 6243fa34dd3eSStefano Zampini PetscFunctionReturn(0); 6244fa34dd3eSStefano Zampini } 6245