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 9*a3df083aSStefano Zampini #undef __FUNCT__ 10*a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 11*a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 12*a3df083aSStefano Zampini { 13*a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 14*a3df083aSStefano Zampini PetscErrorCode ierr; 15*a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 16*a3df083aSStefano Zampini 17*a3df083aSStefano Zampini PetscFunctionBegin; 18*a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 19*a3df083aSStefano Zampini if (transpose) { 20*a3df083aSStefano Zampini apply_right = ctx->apply_left; 21*a3df083aSStefano Zampini apply_left = ctx->apply_right; 22*a3df083aSStefano Zampini } else { 23*a3df083aSStefano Zampini apply_right = ctx->apply_right; 24*a3df083aSStefano Zampini apply_left = ctx->apply_left; 25*a3df083aSStefano Zampini } 26*a3df083aSStefano Zampini reset_x = PETSC_FALSE; 27*a3df083aSStefano Zampini if (apply_right) { 28*a3df083aSStefano Zampini const PetscScalar *ax; 29*a3df083aSStefano Zampini PetscInt nl,i; 30*a3df083aSStefano Zampini 31*a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 32*a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 33*a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 34*a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 35*a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 36*a3df083aSStefano Zampini PetscScalar sum,val; 37*a3df083aSStefano Zampini const PetscInt *idxs; 38*a3df083aSStefano Zampini PetscInt nz,j; 39*a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 40*a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 41*a3df083aSStefano Zampini sum = 0.; 42*a3df083aSStefano Zampini if (ctx->apply_p0) { 43*a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 44*a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 45*a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 46*a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 47*a3df083aSStefano Zampini } 48*a3df083aSStefano Zampini } else { 49*a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 50*a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 51*a3df083aSStefano Zampini } 52*a3df083aSStefano Zampini } 53*a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 54*a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 55*a3df083aSStefano Zampini } 56*a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 57*a3df083aSStefano Zampini reset_x = PETSC_TRUE; 58*a3df083aSStefano Zampini } 59*a3df083aSStefano Zampini if (transpose) { 60*a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 61*a3df083aSStefano Zampini } else { 62*a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 63*a3df083aSStefano Zampini } 64*a3df083aSStefano Zampini if (reset_x) { 65*a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 66*a3df083aSStefano Zampini } 67*a3df083aSStefano Zampini if (apply_left) { 68*a3df083aSStefano Zampini PetscScalar *ay; 69*a3df083aSStefano Zampini PetscInt i; 70*a3df083aSStefano Zampini 71*a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 72*a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 73*a3df083aSStefano Zampini PetscScalar sum,val; 74*a3df083aSStefano Zampini const PetscInt *idxs; 75*a3df083aSStefano Zampini PetscInt nz,j; 76*a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 77*a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 78*a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 79*a3df083aSStefano Zampini if (ctx->apply_p0) { 80*a3df083aSStefano Zampini sum = 0.; 81*a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 82*a3df083aSStefano Zampini sum += ay[idxs[j]]; 83*a3df083aSStefano Zampini ay[idxs[j]] += val; 84*a3df083aSStefano Zampini } 85*a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 86*a3df083aSStefano Zampini } else { 87*a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 88*a3df083aSStefano Zampini ay[idxs[j]] += val; 89*a3df083aSStefano Zampini } 90*a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 91*a3df083aSStefano Zampini } 92*a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 93*a3df083aSStefano Zampini } 94*a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 95*a3df083aSStefano Zampini } 96*a3df083aSStefano Zampini PetscFunctionReturn(0); 97*a3df083aSStefano Zampini } 98*a3df083aSStefano Zampini 99*a3df083aSStefano Zampini #undef __FUNCT__ 100*a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 101*a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 102*a3df083aSStefano Zampini { 103*a3df083aSStefano Zampini PetscErrorCode ierr; 104*a3df083aSStefano Zampini 105*a3df083aSStefano Zampini PetscFunctionBegin; 106*a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 107*a3df083aSStefano Zampini PetscFunctionReturn(0); 108*a3df083aSStefano Zampini } 109*a3df083aSStefano Zampini 110*a3df083aSStefano Zampini #undef __FUNCT__ 111*a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 112*a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 113*a3df083aSStefano Zampini { 114*a3df083aSStefano Zampini PetscErrorCode ierr; 115*a3df083aSStefano Zampini 116*a3df083aSStefano Zampini PetscFunctionBegin; 117*a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 118*a3df083aSStefano Zampini PetscFunctionReturn(0); 119*a3df083aSStefano Zampini } 120*a3df083aSStefano Zampini 121*a3df083aSStefano Zampini #undef __FUNCT__ 122*a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 123*a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 124*a3df083aSStefano Zampini { 125*a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 126*a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 127*a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 128*a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 129*a3df083aSStefano Zampini PetscErrorCode ierr; 130*a3df083aSStefano Zampini 131*a3df083aSStefano Zampini PetscFunctionBegin; 132*a3df083aSStefano Zampini if (!restore) { 133*a3df083aSStefano Zampini Mat A,A_IB,A_BI; 134*a3df083aSStefano Zampini PetscScalar *work; 135*a3df083aSStefano Zampini PCBDDCReuseMumps reuse = pcbddc->sub_schurs->reuse_mumps; 136*a3df083aSStefano Zampini 137*a3df083aSStefano Zampini if (!reuse) { 138*a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot setup shell matrices!"); 139*a3df083aSStefano Zampini } 140*a3df083aSStefano Zampini 141*a3df083aSStefano Zampini /* local mat */ 142*a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A);CHKERRQ(ierr); 143*a3df083aSStefano Zampini ierr = MatSetSizes(A,pcis->n,pcis->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 144*a3df083aSStefano Zampini ierr = MatSetType(A,MATSHELL);CHKERRQ(ierr); 145*a3df083aSStefano Zampini ierr = MatShellSetOperation(A,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 146*a3df083aSStefano Zampini ierr = MatShellSetOperation(A,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 147*a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 148*a3df083aSStefano Zampini ierr = MatShellSetContext(A,ctx);CHKERRQ(ierr); 149*a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 150*a3df083aSStefano Zampini ctx->apply_right = PETSC_TRUE; 151*a3df083aSStefano Zampini ctx->apply_p0 = PETSC_TRUE; 152*a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 153*a3df083aSStefano Zampini ctx->benign_zerodiag_subs = pcbddc->benign_zerodiag_subs; 154*a3df083aSStefano Zampini ctx->A = matis->A; 155*a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 156*a3df083aSStefano Zampini ctx->work = work; 157*a3df083aSStefano Zampini ierr = MatSetUp(A);CHKERRQ(ierr); 158*a3df083aSStefano Zampini ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 159*a3df083aSStefano Zampini ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 160*a3df083aSStefano Zampini matis->A = A; 161*a3df083aSStefano Zampini 162*a3df083aSStefano Zampini /* A_IB */ 163*a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 164*a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 165*a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 166*a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 167*a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 168*a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 169*a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 170*a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 171*a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 172*a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 173*a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 174*a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 175*a3df083aSStefano Zampini ctx->A = pcis->A_IB; 176*a3df083aSStefano Zampini ctx->work = work; 177*a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 178*a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179*a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 180*a3df083aSStefano Zampini pcis->A_IB = A_IB; 181*a3df083aSStefano Zampini 182*a3df083aSStefano Zampini /* A_BI as A_IB^T */ 183*a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 184*a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 185*a3df083aSStefano Zampini pcis->A_BI = A_BI; 186*a3df083aSStefano Zampini } else { 187*a3df083aSStefano Zampini ierr = MatShellGetContext(matis->A,&ctx);CHKERRQ(ierr); 188*a3df083aSStefano Zampini ierr = MatDestroy(&matis->A);CHKERRQ(ierr); 189*a3df083aSStefano Zampini matis->A = ctx->A; 190*a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 191*a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 192*a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 193*a3df083aSStefano Zampini pcis->A_IB = ctx->A; 194*a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 195*a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 196*a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 197*a3df083aSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 198*a3df083aSStefano Zampini pcbddc->benign_original_mat = NULL; 199*a3df083aSStefano Zampini } 200*a3df083aSStefano Zampini PetscFunctionReturn(0); 201*a3df083aSStefano Zampini } 202*a3df083aSStefano Zampini 203*a3df083aSStefano Zampini /* used just in bddc debug mode */ 204*a3df083aSStefano Zampini #undef __FUNCT__ 205*a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 206*a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 207*a3df083aSStefano Zampini { 208*a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 209*a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 210*a3df083aSStefano Zampini Mat An; 211*a3df083aSStefano Zampini PetscErrorCode ierr; 212*a3df083aSStefano Zampini 213*a3df083aSStefano Zampini PetscFunctionBegin; 214*a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 215*a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 216*a3df083aSStefano Zampini if (is1) { 217*a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 218*a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 219*a3df083aSStefano Zampini } else { 220*a3df083aSStefano Zampini *B = An; 221*a3df083aSStefano Zampini } 222*a3df083aSStefano Zampini PetscFunctionReturn(0); 223*a3df083aSStefano Zampini } 224*a3df083aSStefano 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; 4024f1b2e48SStefano Zampini PetscInt nz; 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); 4435408967cSStefano Zampini } 444dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 4455408967cSStefano Zampini 4465408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 4475408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 4484f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 4495408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 4504f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 4515408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 4524f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 4534f1b2e48SStefano Zampini if ((PetscInt)PetscRealPart(pcbddc->benign_p0[i]) != -PetscGlobalRank-i) { 4544f1b2e48SStefano 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); 4554f1b2e48SStefano Zampini } 4565408967cSStefano Zampini } 4575408967cSStefano Zampini PetscFunctionReturn(0); 4585408967cSStefano Zampini } 4595408967cSStefano Zampini 4605408967cSStefano Zampini #undef __FUNCT__ 461339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 462339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 463339f8db1SStefano Zampini { 464339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4654f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 466b0f5fe93SStefano Zampini PetscInt nz,n; 4674f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 468339f8db1SStefano Zampini PetscErrorCode ierr; 469339f8db1SStefano Zampini 470339f8db1SStefano Zampini PetscFunctionBegin; 4719f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 4729f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 473339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 474*a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 475*a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 476*a3df083aSStefano Zampini } 477*a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 478*a3df083aSStefano Zampini pcbddc->benign_n = 0; 4794f1b2e48SStefano Zampini /* if a local info on dofs is present, assumes the last field is represented by "pressures" 4804f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 4814f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 4824f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 4834f1b2e48SStefano Zampini since the local Schur complements are SPD 4844f1b2e48SStefano Zampini */ 4854f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 4864f1b2e48SStefano Zampini have_null = PETSC_TRUE; 48740fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 4884f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 4894f1b2e48SStefano Zampini 4904f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 4914f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 4924f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 4934f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 494ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 49540fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 49640fa8d13SStefano Zampini if (!sorted) { 49740fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 49840fa8d13SStefano Zampini } 49940fa8d13SStefano Zampini } else { 50040fa8d13SStefano Zampini pressures = NULL; 50140fa8d13SStefano Zampini } 50297d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 50397d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 5044f1b2e48SStefano Zampini /* TODO: add check for shared dofs and raise error */ 50597d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 506339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 507339f8db1SStefano Zampini if (!sorted) { 508339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 509339f8db1SStefano Zampini } 510339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 5114f1b2e48SStefano Zampini if (!nz) { 5124f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 5134f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 51440fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 51540fa8d13SStefano Zampini } 5164f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 5174f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 5184f1b2e48SStefano Zampini zerodiag_subs = NULL; 5194f1b2e48SStefano Zampini pcbddc->benign_n = 0; 5204f1b2e48SStefano Zampini if (has_null_pressures) { 5214f1b2e48SStefano Zampini IS *subs; 5224f1b2e48SStefano Zampini PetscInt nsubs,i; 5234f1b2e48SStefano Zampini 5244f1b2e48SStefano Zampini subs = pcbddc->local_subs; 5254f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 5264f1b2e48SStefano Zampini if (nsubs > 1) { 5274f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 5284f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 5294f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 5304f1b2e48SStefano Zampini IS t_zerodiag_subs; 5314f1b2e48SStefano Zampini PetscInt nl; 5324f1b2e48SStefano Zampini 5334f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 5344f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 5354f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 5364f1b2e48SStefano Zampini if (nl) { 5374f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 5384f1b2e48SStefano Zampini 5394f1b2e48SStefano Zampini if (pressures) { 5404f1b2e48SStefano Zampini IS t_pressure_subs; 5414f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 5424f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 5434f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 5444f1b2e48SStefano Zampini } 5454f1b2e48SStefano Zampini if (valid) { 5464f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 5474f1b2e48SStefano Zampini pcbddc->benign_n++; 5484f1b2e48SStefano Zampini } else { 5494f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 5504f1b2e48SStefano Zampini } 5514f1b2e48SStefano Zampini } 5524f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 5534f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 5544f1b2e48SStefano Zampini } 5554f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 5564f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 5574f1b2e48SStefano Zampini if (pressures) { 5584f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 5594f1b2e48SStefano Zampini } 5604f1b2e48SStefano Zampini if (valid) { 5614f1b2e48SStefano Zampini pcbddc->benign_n = 1; 562ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 5634f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 5644f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 5654f1b2e48SStefano Zampini } 5664f1b2e48SStefano Zampini } 5674f1b2e48SStefano Zampini } 5684f1b2e48SStefano Zampini 5694f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 5704f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 5714f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 5724f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 5734f1b2e48SStefano Zampini have_null = PETSC_FALSE; 5744f1b2e48SStefano Zampini } 5754f1b2e48SStefano Zampini 5764f1b2e48SStefano Zampini /* final check for null pressures */ 5774f1b2e48SStefano Zampini if (zerodiag && pressures) { 5784f1b2e48SStefano Zampini PetscInt nz,np; 5794f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 5804f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 5814f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 5824f1b2e48SStefano Zampini } 5834f1b2e48SStefano Zampini 5844f1b2e48SStefano Zampini if (recompute_zerodiag) { 5854f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 5864f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 5874f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 5884f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 5894f1b2e48SStefano Zampini } else { 5904f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 5914f1b2e48SStefano Zampini 5924f1b2e48SStefano Zampini nzn = 0; 5934f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 5944f1b2e48SStefano Zampini PetscInt ns; 5954f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 5964f1b2e48SStefano Zampini nzn += ns; 5974f1b2e48SStefano Zampini } 5984f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 5994f1b2e48SStefano Zampini nzn = 0; 6004f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 6014f1b2e48SStefano Zampini PetscInt ns,*idxs; 6024f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 6034f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 6044f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 6054f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 6064f1b2e48SStefano Zampini nzn += ns; 6074f1b2e48SStefano Zampini } 6084f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 6094f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 6104f1b2e48SStefano Zampini } 6114f1b2e48SStefano Zampini have_null = PETSC_FALSE; 6124f1b2e48SStefano Zampini } 6134f1b2e48SStefano Zampini 6144f1b2e48SStefano Zampini if (has_null_pressures) { 6154f1b2e48SStefano Zampini IS zerodiagc; 6164f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 6174f1b2e48SStefano Zampini PetscInt i,s,*nnz; 6184f1b2e48SStefano Zampini 6194f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 620339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 621339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 622339f8db1SStefano Zampini /* local change of basis for pressures */ 623339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 62497d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 625339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 626339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 627339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 6284f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 6294f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 6304f1b2e48SStefano Zampini PetscInt nzs,j; 6314f1b2e48SStefano Zampini 6324f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 6334f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 6344f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 6354f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 6364f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 6374f1b2e48SStefano Zampini } 638339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 639339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 640339f8db1SStefano Zampini /* set identity on velocities */ 641339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 642339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 643339f8db1SStefano Zampini } 6444f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 6454f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 6469f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 6474f1b2e48SStefano 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); 648339f8db1SStefano Zampini /* set change on pressures */ 6494f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 6504f1b2e48SStefano Zampini PetscScalar *array; 6514f1b2e48SStefano Zampini PetscInt nzs; 6524f1b2e48SStefano Zampini 6534f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 6544f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 6554f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 656339f8db1SStefano Zampini PetscScalar vals[2]; 657339f8db1SStefano Zampini PetscInt cols[2]; 658339f8db1SStefano Zampini 659339f8db1SStefano Zampini cols[0] = idxs[i]; 6604f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 661339f8db1SStefano Zampini vals[0] = 1.; 662b0f5fe93SStefano Zampini vals[1] = 1.; 6634f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 664339f8db1SStefano Zampini } 6654f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 6664f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 6674f1b2e48SStefano Zampini array[nzs-1] = 1.; 6684f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 6694f1b2e48SStefano Zampini /* store local idxs for p0 */ 6704f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 6714f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 672339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 6734f1b2e48SStefano Zampini } 674339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 675339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 676*a3df083aSStefano Zampini /* project if needed */ 677*a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 67897d764eeSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&pcbddc->benign_original_mat);CHKERRQ(ierr); 679339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 68097d764eeSStefano Zampini ierr = MatSeqAIJCompress(pcbddc->benign_original_mat,&pcbddc->local_mat);CHKERRQ(ierr); 68197d764eeSStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 682*a3df083aSStefano Zampini } 6834f1b2e48SStefano Zampini /* store global idxs for p0 */ 6844f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 685339f8db1SStefano Zampini } 686ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 6874f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 688b0f5fe93SStefano Zampini 689b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 690b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 691339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 692339f8db1SStefano Zampini PetscFunctionReturn(0); 693339f8db1SStefano Zampini } 694339f8db1SStefano Zampini 695339f8db1SStefano Zampini #undef __FUNCT__ 696015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 697015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 698efc2fbd9SStefano Zampini { 699efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 700efc2fbd9SStefano Zampini PetscErrorCode ierr; 701efc2fbd9SStefano Zampini 702efc2fbd9SStefano Zampini PetscFunctionBegin; 703efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 704efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 7054f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 706efc2fbd9SStefano Zampini } 707015636ebSStefano Zampini if (get) { /* use SF to get values */ 708efc2fbd9SStefano Zampini PetscScalar *array; 709efc2fbd9SStefano Zampini 710efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 7114f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 7124f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 713efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 7144f1b2e48SStefano Zampini } else { /* use VecSetValues (not scalable, I should try to find a better solution (defining a new MPI_OP for reduction) */ 7154f1b2e48SStefano Zampini ierr = VecSetValues(v,pcbddc->benign_n,pcbddc->benign_p0_gidx,pcbddc->benign_p0,INSERT_VALUES);CHKERRQ(ierr); 716efc2fbd9SStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 717efc2fbd9SStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 718efc2fbd9SStefano Zampini } 719efc2fbd9SStefano Zampini PetscFunctionReturn(0); 720efc2fbd9SStefano Zampini } 721efc2fbd9SStefano Zampini 722efc2fbd9SStefano Zampini #undef __FUNCT__ 723c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 724c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 725c263805aSStefano Zampini { 726c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 727c263805aSStefano Zampini PetscErrorCode ierr; 728c263805aSStefano Zampini 729c263805aSStefano Zampini PetscFunctionBegin; 730c263805aSStefano Zampini /* TODO: add error checking 731c263805aSStefano Zampini - avoid nested pop (or push) calls. 732c263805aSStefano Zampini - cannot push before pop. 7331c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 734c263805aSStefano Zampini */ 7354f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 736efc2fbd9SStefano Zampini PetscFunctionReturn(0); 737efc2fbd9SStefano Zampini } 738c263805aSStefano Zampini if (pop) { 739*a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 7404f1b2e48SStefano Zampini IS is_p0; 7414f1b2e48SStefano Zampini MatReuse reuse; 742c263805aSStefano Zampini 743c263805aSStefano Zampini /* extract B_0 */ 7444f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 7454f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 7464f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 7474f1b2e48SStefano Zampini } 7484f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 7494f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 750c263805aSStefano Zampini /* remove rows and cols from local problem */ 751c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 75297d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7534f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 7544f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 755*a3df083aSStefano Zampini } else { 756*a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 757*a3df083aSStefano Zampini PetscScalar *vals; 758*a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 759*a3df083aSStefano Zampini 760*a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 761*a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 762*a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 763*a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 764*a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 765*a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 766*a3df083aSStefano Zampini /* this matrix is very sparse: the nnz pattern is not known unless we do 2 sweeps of the next loop. 767*a3df083aSStefano Zampini Setting nnz=100 should be more than enough */ 768*a3df083aSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,100,NULL);CHKERRQ(ierr); 769*a3df083aSStefano Zampini } 770*a3df083aSStefano Zampini 771*a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 772*a3df083aSStefano Zampini PetscScalar *array; 773*a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 774*a3df083aSStefano Zampini 775*a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 776*a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 777*a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 778*a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 779*a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 780*a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 781*a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 782*a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 783*a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 784*a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 785*a3df083aSStefano Zampini cum = 0; 786*a3df083aSStefano Zampini for (j=0;j<n;j++) { 787*a3df083aSStefano Zampini if (PetscUnlikely(PetscAbsReal(array[j]) > PETSC_SMALL)) { 788*a3df083aSStefano Zampini vals[cum] = array[j]; 789*a3df083aSStefano Zampini idxs_ins[cum] = j; 790*a3df083aSStefano Zampini cum++; 791*a3df083aSStefano Zampini } 792*a3df083aSStefano Zampini } 793*a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 794*a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 795*a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 796*a3df083aSStefano Zampini } 797*a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 798*a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 799*a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 800*a3df083aSStefano Zampini } 801c263805aSStefano Zampini } else { /* push */ 802*a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 8034f1b2e48SStefano Zampini PetscInt i; 8044f1b2e48SStefano Zampini 8054f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 8064f1b2e48SStefano Zampini PetscScalar *B0_vals; 8074f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 8084f1b2e48SStefano Zampini 8094f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 8104f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 8117b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 8124f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 8134f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 8144f1b2e48SStefano Zampini } 815c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 816c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 817*a3df083aSStefano Zampini } else { 818*a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 819*a3df083aSStefano Zampini } 820c263805aSStefano Zampini } 821c263805aSStefano Zampini PetscFunctionReturn(0); 822c263805aSStefano Zampini } 823c263805aSStefano Zampini 824c263805aSStefano Zampini #undef __FUNCT__ 825b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 82608122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 827b1b3d7a2SStefano Zampini { 828b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 82908122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 83008122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 83108122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 83208122e43SStefano Zampini PetscScalar *work,lwork; 83308122e43SStefano Zampini PetscScalar *St,*S,*eigv; 83408122e43SStefano Zampini PetscScalar *Sarray,*Starray; 83508122e43SStefano Zampini PetscReal *eigs,thresh; 8361b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 837f6f667cfSStefano Zampini PetscBool allocated_S_St; 83808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 83908122e43SStefano Zampini PetscReal *rwork; 84008122e43SStefano Zampini #endif 841b1b3d7a2SStefano Zampini PetscErrorCode ierr; 842b1b3d7a2SStefano Zampini 843b1b3d7a2SStefano Zampini PetscFunctionBegin; 84408122e43SStefano Zampini if (!sub_schurs->use_mumps) { 84508122e43SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS"); 84608122e43SStefano Zampini } 84708122e43SStefano Zampini 84806a4e24aSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) { 84906a4e24aSStefano 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); 85006a4e24aSStefano Zampini } 85106a4e24aSStefano Zampini 852fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 853fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 854fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 855fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 8561575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 857fd14bc51SStefano Zampini } 858fd14bc51SStefano Zampini 859e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 860e496cd5dSStefano 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); 861e496cd5dSStefano Zampini } 862e496cd5dSStefano Zampini 86308122e43SStefano Zampini /* max size of subsets */ 86408122e43SStefano Zampini mss = 0; 86508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 86608122e43SStefano Zampini PetscInt subset_size; 867862806e4SStefano Zampini 86808122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 86908122e43SStefano Zampini mss = PetscMax(mss,subset_size); 87008122e43SStefano Zampini } 87108122e43SStefano Zampini 87208122e43SStefano Zampini /* min/max and threshold */ 87308122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 874f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 87508122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 876f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 877f6f667cfSStefano Zampini if (nmin) { 878f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 879f6f667cfSStefano Zampini } 88008122e43SStefano Zampini 88108122e43SStefano Zampini /* allocate lapack workspace */ 88208122e43SStefano Zampini cum = cum2 = 0; 88308122e43SStefano Zampini maxneigs = 0; 88408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 88508122e43SStefano Zampini PetscInt n,subset_size; 886f6f667cfSStefano Zampini 88708122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 88808122e43SStefano Zampini n = PetscMin(subset_size,nmax); 8899162d606SStefano Zampini cum += subset_size; 8909162d606SStefano Zampini cum2 += subset_size*n; 89108122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 89208122e43SStefano Zampini } 89308122e43SStefano Zampini if (mss) { 8949ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 89508122e43SStefano Zampini PetscBLASInt B_itype = 1; 89608122e43SStefano Zampini PetscBLASInt B_N = mss; 8974c6709b3SStefano Zampini PetscReal zero = 0.0; 8984c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 89908122e43SStefano Zampini 90008122e43SStefano Zampini B_lwork = -1; 90108122e43SStefano Zampini S = NULL; 90208122e43SStefano Zampini St = NULL; 903a58a30b4SStefano Zampini eigs = NULL; 904a58a30b4SStefano Zampini eigv = NULL; 905a58a30b4SStefano Zampini B_iwork = NULL; 906a58a30b4SStefano Zampini B_ifail = NULL; 907d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 908d1710679SStefano Zampini rwork = NULL; 909d1710679SStefano Zampini #endif 9108bec7fa6SStefano Zampini thresh = 1.0; 91108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 91208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 91308122e43SStefano 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)); 91408122e43SStefano Zampini #else 91508122e43SStefano 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)); 91608122e43SStefano Zampini #endif 91708122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 91808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 91908122e43SStefano Zampini } else { 92008122e43SStefano Zampini /* TODO */ 92108122e43SStefano Zampini } 92208122e43SStefano Zampini } else { 92308122e43SStefano Zampini lwork = 0; 92408122e43SStefano Zampini } 92508122e43SStefano Zampini 92608122e43SStefano Zampini nv = 0; 927d62866d3SStefano 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) */ 928d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 92908122e43SStefano Zampini } 9304c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 931f6f667cfSStefano Zampini if (allocated_S_St) { 932f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 933f6f667cfSStefano Zampini } 934f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 93508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 93608122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 93708122e43SStefano Zampini #endif 9389162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 9399162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 9409162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 94108122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 9429162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 94308122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 94408122e43SStefano Zampini 94508122e43SStefano Zampini maxneigs = 0; 94608122e43SStefano Zampini cum = cum2 = cumarray = 0; 9479162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 9489162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 949d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 95008122e43SStefano Zampini const PetscInt *idxs; 95108122e43SStefano Zampini 952d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 95308122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 95408122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 95508122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 95608122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 9579162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 9589162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 95908122e43SStefano Zampini } 96008122e43SStefano Zampini cum2 = cum; 961d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 96208122e43SStefano Zampini } 96308122e43SStefano Zampini 96408122e43SStefano Zampini if (mss) { /* multilevel */ 96508122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 96608122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 96708122e43SStefano Zampini } 96808122e43SStefano Zampini 969ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 97008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 97108122e43SStefano Zampini const PetscInt *idxs; 972f6f667cfSStefano Zampini PetscReal infty = PETSC_MAX_REAL; 973862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 97408122e43SStefano Zampini PetscBLASInt B_N; 975aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 97608122e43SStefano Zampini 977862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 978ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 979f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 980f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 9819ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 982aff50787SStefano Zampini PetscInt j,k; 983aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 984aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 985aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 98608122e43SStefano Zampini } 98708122e43SStefano Zampini for (j=0;j<subset_size;j++) { 988aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 989aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 990aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 991aff50787SStefano Zampini } 99208122e43SStefano Zampini } 99308122e43SStefano Zampini } else { 99408122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 99508122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 99608122e43SStefano Zampini } 9978bec7fa6SStefano Zampini } else { 998f6f667cfSStefano Zampini S = Sarray + cumarray; 999f6f667cfSStefano Zampini St = Starray + cumarray; 10008bec7fa6SStefano Zampini } 100108122e43SStefano Zampini 1002aff50787SStefano Zampini /* see if we can save some work */ 1003aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { 1004aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 1005aff50787SStefano Zampini } 1006aff50787SStefano Zampini 1007aff50787SStefano Zampini if (same_data) { /* there's no need of constraints here, deluxe scaling is enough */ 1008aff50787SStefano Zampini B_neigs = 0; 1009aff50787SStefano Zampini } else { 10109ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 101108122e43SStefano Zampini PetscBLASInt B_itype = 1; 1012f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 10134c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 10149552c7c7SStefano Zampini PetscInt nmin_s; 101508122e43SStefano Zampini 1016fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 10178bec7fa6SStefano 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]]); 1018fd14bc51SStefano Zampini } 1019d16cbb6bSStefano Zampini 102008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1021d16cbb6bSStefano Zampini if (thresh > 1.+PETSC_SMALL) { 1022d16cbb6bSStefano Zampini 1023d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 102408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1025f6f667cfSStefano 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)); 102608122e43SStefano Zampini #else 1027f6f667cfSStefano 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)); 102808122e43SStefano Zampini #endif 1029d16cbb6bSStefano Zampini } else { 1030d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 1031d16cbb6bSStefano Zampini B_IL = 1; 1032d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1033d16cbb6bSStefano 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)); 1034d16cbb6bSStefano Zampini #else 1035d16cbb6bSStefano 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)); 1036d16cbb6bSStefano Zampini #endif 1037d16cbb6bSStefano Zampini } 103808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 103908122e43SStefano Zampini if (B_ierr) { 104008122e43SStefano Zampini if (B_ierr < 0 ) { 104108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 104208122e43SStefano Zampini } else if (B_ierr <= B_N) { 104308122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 104408122e43SStefano Zampini } else { 10459552c7c7SStefano 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); 104608122e43SStefano Zampini } 104708122e43SStefano Zampini } 104808122e43SStefano Zampini 104908122e43SStefano Zampini if (B_neigs > nmax) { 1050fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1051fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 1052fd14bc51SStefano Zampini } 1053f6f667cfSStefano Zampini eigs_start = B_neigs -nmax; 105408122e43SStefano Zampini B_neigs = nmax; 105508122e43SStefano Zampini } 105608122e43SStefano Zampini 10579552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 10589552c7c7SStefano Zampini if (B_neigs < nmin_s) { 105908122e43SStefano Zampini PetscBLASInt B_neigs2; 106008122e43SStefano Zampini 1061f6f667cfSStefano Zampini B_IU = B_N - B_neigs; 1062f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 1063fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1064fd14bc51SStefano 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); 1065fd14bc51SStefano Zampini } 10669ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 106708122e43SStefano Zampini PetscInt j; 106808122e43SStefano Zampini for (j=0;j<subset_size;j++) { 106908122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 107008122e43SStefano Zampini } 107108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 107208122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 107308122e43SStefano Zampini } 107408122e43SStefano Zampini } else { 107508122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 107608122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 107708122e43SStefano Zampini } 107808122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 107908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1080f6f667cfSStefano 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)); 108108122e43SStefano Zampini #else 1082f6f667cfSStefano 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)); 108308122e43SStefano Zampini #endif 108408122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 108508122e43SStefano Zampini B_neigs += B_neigs2; 108608122e43SStefano Zampini } 108708122e43SStefano Zampini if (B_ierr) { 108808122e43SStefano Zampini if (B_ierr < 0 ) { 108908122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 109008122e43SStefano Zampini } else if (B_ierr <= B_N) { 109108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 109208122e43SStefano Zampini } else { 10939552c7c7SStefano 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); 109408122e43SStefano Zampini } 109508122e43SStefano Zampini } 1096fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1097ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 109808122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 109908122e43SStefano Zampini if (eigs[j] == 0.0) { 1100ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 110108122e43SStefano Zampini } else { 1102ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 1103fd14bc51SStefano Zampini } 110408122e43SStefano Zampini } 110508122e43SStefano Zampini } 110608122e43SStefano Zampini } else { 110708122e43SStefano Zampini /* TODO */ 110808122e43SStefano Zampini } 1109aff50787SStefano Zampini } 11108bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 11118bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 11129162d606SStefano Zampini if (B_neigs) { 11139162d606SStefano 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); 1114fd14bc51SStefano Zampini 1115fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 11169552c7c7SStefano Zampini PetscInt ii; 11179552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 1118ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 11199552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 1120ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 1121ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1122ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 1123ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 1124ac47001eSStefano Zampini #else 1125ac47001eSStefano 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); 1126ac47001eSStefano Zampini #endif 11279552c7c7SStefano Zampini } 11289552c7c7SStefano Zampini } 1129fd14bc51SStefano Zampini } 113008122e43SStefano Zampini #if 0 11319162d606SStefano Zampini for (j=0;j<B_neigs;j++) { 113208122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 113308122e43SStefano Zampini PetscScalar norm; 113408122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 11359162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size, 11369162d606SStefano Zampini &Blas_one,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 113708122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 113808122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 113908122e43SStefano Zampini } else { 114008122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 114108122e43SStefano Zampini } 11429162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 1143b1b3d7a2SStefano Zampini } 1144b1b3d7a2SStefano Zampini #endif 11459162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 11469162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 11479162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 11489162d606SStefano Zampini cum++; 114908122e43SStefano Zampini } 115008122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 115108122e43SStefano Zampini /* shift for next computation */ 115208122e43SStefano Zampini cumarray += subset_size*subset_size; 115308122e43SStefano Zampini } 1154fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 1155fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1156fd14bc51SStefano Zampini } 115708122e43SStefano Zampini 115808122e43SStefano Zampini if (mss) { 115908122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 116008122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 1161f6f667cfSStefano Zampini /* destroy matrices (junk) */ 1162f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 1163f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 116408122e43SStefano Zampini } 1165f6f667cfSStefano Zampini if (allocated_S_St) { 1166f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 1167f6f667cfSStefano Zampini } 1168f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 116908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 117008122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 117108122e43SStefano Zampini #endif 117208122e43SStefano Zampini if (pcbddc->dbg_flag) { 11731b968477SStefano Zampini PetscInt maxneigs_r; 117408122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 11759b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 117608122e43SStefano Zampini } 117708122e43SStefano Zampini PetscFunctionReturn(0); 117808122e43SStefano Zampini } 1179b1b3d7a2SStefano Zampini 1180674ae819SStefano Zampini #undef __FUNCT__ 1181c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 1182c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 1183c8587f34SStefano Zampini { 1184c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 11858629588bSStefano Zampini PetscScalar *coarse_submat_vals; 1186c8587f34SStefano Zampini PetscErrorCode ierr; 1187c8587f34SStefano Zampini 1188c8587f34SStefano Zampini PetscFunctionBegin; 1189f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 11905e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 1191c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 1192c8587f34SStefano Zampini 1193684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 11940fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 1195684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 1196c8587f34SStefano Zampini 1197c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 1198b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 1199c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 1200c8587f34SStefano Zampini } 1201c8587f34SStefano Zampini 12028629588bSStefano Zampini /* 12038629588bSStefano Zampini Setup local correction and local part of coarse basis. 12048629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 12058629588bSStefano Zampini */ 120647f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 12078629588bSStefano Zampini 12088629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 12098629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 12108629588bSStefano Zampini 12118629588bSStefano Zampini /* free */ 12128629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 1213c8587f34SStefano Zampini PetscFunctionReturn(0); 1214c8587f34SStefano Zampini } 1215c8587f34SStefano Zampini 1216c8587f34SStefano Zampini #undef __FUNCT__ 1217674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 1218674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 1219674ae819SStefano Zampini { 1220674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1221674ae819SStefano Zampini PetscErrorCode ierr; 1222674ae819SStefano Zampini 1223674ae819SStefano Zampini PetscFunctionBegin; 1224674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1225674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 122630368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 1227674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 1228674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1229785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 1230674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 1231f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1232f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1233785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 123463602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 123563602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 1236674ae819SStefano Zampini PetscFunctionReturn(0); 1237674ae819SStefano Zampini } 1238674ae819SStefano Zampini 1239674ae819SStefano Zampini #undef __FUNCT__ 1240674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 1241674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 1242674ae819SStefano Zampini { 1243674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 12444f1b2e48SStefano Zampini PetscInt i; 1245674ae819SStefano Zampini PetscErrorCode ierr; 1246674ae819SStefano Zampini 1247674ae819SStefano Zampini PetscFunctionBegin; 1248b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 1249674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 1250674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 1251674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 12524f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 12534f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 12544f1b2e48SStefano Zampini } 12554f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 1256b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 1257674ae819SStefano Zampini PetscFunctionReturn(0); 1258674ae819SStefano Zampini } 1259674ae819SStefano Zampini 1260674ae819SStefano Zampini #undef __FUNCT__ 1261674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 1262674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 1263674ae819SStefano Zampini { 1264674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1265674ae819SStefano Zampini PetscErrorCode ierr; 1266674ae819SStefano Zampini 1267674ae819SStefano Zampini PetscFunctionBegin; 1268674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 126958da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 1270ca92afb2SStefano Zampini PetscScalar *array; 127106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 127206656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 127358da7f69SStefano Zampini } 1274674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1275674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 127615aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 127715aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1278674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 1279674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 1280674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 128106656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 1282674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1283674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 12848ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1285674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1286674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1287674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1288f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 1289f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 1290f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1291f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1292727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 12930e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 1294f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 129570cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 12966e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 129781d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 12980369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 12998b9f24d4SStefano Zampini ierr = MatDestroy(&pcbddc->benign_original_mat);CHKERRQ(ierr); 13004f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 13018b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 1302ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 1303ca92afb2SStefano Zampini PetscInt i; 1304ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1305ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1306ca92afb2SStefano Zampini } 1307ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 1308ca92afb2SStefano Zampini } 13094f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 1310674ae819SStefano Zampini PetscFunctionReturn(0); 1311674ae819SStefano Zampini } 1312674ae819SStefano Zampini 1313674ae819SStefano Zampini #undef __FUNCT__ 1314f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 1315f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 13166bfb1811SStefano Zampini { 13176bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 13186bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 13196bfb1811SStefano Zampini VecType impVecType; 13204f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 13216bfb1811SStefano Zampini PetscErrorCode ierr; 13226bfb1811SStefano Zampini 13236bfb1811SStefano Zampini PetscFunctionBegin; 1324f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 1325019a44ceSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 1326f4ddd8eeSStefano Zampini } 1327e7b262bdSStefano Zampini /* get sizes */ 13284f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 1329b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 13306bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 1331e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 1332e7b262bdSStefano Zampini /* R nodes */ 1333e7b262bdSStefano Zampini old_size = -1; 1334e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 1335e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 1336e7b262bdSStefano Zampini } 1337e7b262bdSStefano Zampini if (n_R != old_size) { 1338e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 1339e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 13406bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 13416bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 13426bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 13436bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 1344e7b262bdSStefano Zampini } 1345e7b262bdSStefano Zampini /* local primal dofs */ 1346e7b262bdSStefano Zampini old_size = -1; 1347e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 1348e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 1349e7b262bdSStefano Zampini } 1350e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 1351e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 135283b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 1353e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 13546bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 1355e7b262bdSStefano Zampini } 1356e7b262bdSStefano Zampini /* local explicit constraints */ 1357e7b262bdSStefano Zampini old_size = -1; 1358e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 1359e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 1360e7b262bdSStefano Zampini } 1361e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 1362e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 136383b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 136483b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 136583b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 136683b7ccabSStefano Zampini } 13676bfb1811SStefano Zampini PetscFunctionReturn(0); 13686bfb1811SStefano Zampini } 13696bfb1811SStefano Zampini 13706bfb1811SStefano Zampini #undef __FUNCT__ 137147f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 137247f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 137388ebb749SStefano Zampini { 137425084f0cSStefano Zampini PetscErrorCode ierr; 137525084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 137688ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 137788ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1378d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 137925084f0cSStefano Zampini /* submatrices of local problem */ 138080677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 1381019a44ceSStefano Zampini /* submatrices of benign trick */ 1382d16cbb6bSStefano Zampini Mat B0_V = NULL; 138306656605SStefano Zampini /* submatrices of local coarse problem */ 138406656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 138525084f0cSStefano Zampini /* working matrices */ 138606656605SStefano Zampini Mat C_CR; 138725084f0cSStefano Zampini /* additional working stuff */ 138806656605SStefano Zampini PC pc_R; 13894f1b2e48SStefano Zampini Mat F; 1390*a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 139106656605SStefano Zampini 139225084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 139306656605SStefano Zampini PetscScalar *work; 139406656605SStefano Zampini PetscInt *idx_V_B; 1395ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 139606656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 1397ffd830a3SStefano Zampini 139825084f0cSStefano Zampini /* some shortcuts to scalars */ 139906656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 140088ebb749SStefano Zampini 140188ebb749SStefano Zampini PetscFunctionBegin; 1402ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal && pcbddc->benign_n) { 1403ffd830a3SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-symmetric primal basis computation with benign trick not yet implemented"); 1404ffd830a3SStefano Zampini } 1405ffd830a3SStefano Zampini 1406ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 1407b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 14084f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 1409b371cd4fSStefano Zampini n_B = pcis->n_B; 1410b371cd4fSStefano Zampini n_D = pcis->n - n_B; 141188ebb749SStefano Zampini n_R = pcis->n - n_vertices; 141288ebb749SStefano Zampini 141388ebb749SStefano Zampini /* vertices in boundary numbering */ 1414785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 14150e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 141688ebb749SStefano Zampini if (i != n_vertices) { 141722d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 141888ebb749SStefano Zampini } 141988ebb749SStefano Zampini 142006656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1421019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 142206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 142306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 142406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 142506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 142606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 142706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 142806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 142906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 143006656605SStefano Zampini 143106656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 143206656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 143306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 143406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 143506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 1436ffd830a3SStefano Zampini lda_rhs = n_R; 1437*a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 143806656605SStefano Zampini if (isLU || isILU || isCHOL) { 143906656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 1440d62866d3SStefano Zampini } else if (sub_schurs->reuse_mumps) { 1441d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1442d62866d3SStefano Zampini MatFactorType type; 1443d62866d3SStefano Zampini 14446816873aSStefano Zampini F = reuse_mumps->F; 14456816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 1446d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 1447ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 1448*a3df083aSStefano Zampini need_benign_correction = !!reuse_mumps->benign_n; 144906656605SStefano Zampini } else { 145006656605SStefano Zampini F = NULL; 145106656605SStefano Zampini } 145206656605SStefano Zampini 1453ffd830a3SStefano Zampini /* allocate workspace */ 1454ffd830a3SStefano Zampini n = 0; 1455ffd830a3SStefano Zampini if (n_constraints) { 1456ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 1457ffd830a3SStefano Zampini } 1458ffd830a3SStefano Zampini if (n_vertices) { 1459ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 1460ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 1461ffd830a3SStefano Zampini } 1462ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 1463ffd830a3SStefano Zampini 146488ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 146588ebb749SStefano Zampini if (n_constraints) { 146606656605SStefano Zampini Mat M1,M2,M3; 146780677318SStefano Zampini Mat auxmat; 146806656605SStefano Zampini IS is_aux; 146980677318SStefano Zampini PetscScalar *array,*array2; 147006656605SStefano Zampini 1471f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 147280677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 147388ebb749SStefano Zampini 147425084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 147525084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 14768ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 147780677318SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&auxmat);CHKERRQ(ierr); 147888ebb749SStefano Zampini 147980677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 148080677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 1481ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 148288ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 148306656605SStefano Zampini const PetscScalar *row_cmat_values; 148406656605SStefano Zampini const PetscInt *row_cmat_indices; 148506656605SStefano Zampini PetscInt size_of_constraint,j; 148688ebb749SStefano Zampini 148706656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 148806656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1489ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 149006656605SStefano Zampini } 149106656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 149206656605SStefano Zampini } 1493ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 149406656605SStefano Zampini if (F) { 149506656605SStefano Zampini Mat B; 149606656605SStefano Zampini 1497ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 1498*a3df083aSStefano Zampini if (need_benign_correction) { 1499*a3df083aSStefano Zampini PetscScalar *marr; 1500*a3df083aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1501*a3df083aSStefano Zampini 1502*a3df083aSStefano Zampini ierr = MatDenseGetArray(B,&marr);CHKERRQ(ierr); 1503*a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1504*a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1505*a3df083aSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_mumps,pcbddc->vec1_R,NULL,PETSC_FALSE);CHKERRQ(ierr); 1506*a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1507*a3df083aSStefano Zampini } 1508*a3df083aSStefano Zampini ierr = MatDenseRestoreArray(B,&marr);CHKERRQ(ierr); 1509*a3df083aSStefano Zampini } 151080677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 1511*a3df083aSStefano Zampini if (need_benign_correction) { 1512*a3df083aSStefano Zampini PetscScalar *marr; 1513*a3df083aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1514*a3df083aSStefano Zampini 1515*a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1516*a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 1517*a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1518*a3df083aSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_mumps,pcbddc->vec1_R,NULL,PETSC_TRUE);CHKERRQ(ierr); 1519*a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1520*a3df083aSStefano Zampini } 1521*a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 1522*a3df083aSStefano Zampini } 152306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 152406656605SStefano Zampini } else { 152580677318SStefano Zampini PetscScalar *marr; 152680677318SStefano Zampini 152780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 152806656605SStefano Zampini for (i=0;i<n_constraints;i++) { 1529ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1530ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 153106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 153206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 153306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 153406656605SStefano Zampini } 153580677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 153606656605SStefano Zampini } 153780677318SStefano Zampini if (!pcbddc->switch_static) { 153880677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 153980677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 154080677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 154180677318SStefano Zampini for (i=0;i<n_constraints;i++) { 1542ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 154380677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 154480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 154580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 154680677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 154780677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 154880677318SStefano Zampini } 154980677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 155080677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 155180677318SStefano Zampini ierr = MatMatMult(auxmat,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 155280677318SStefano Zampini } else { 1553ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1554ffd830a3SStefano Zampini IS dummy; 1555ffd830a3SStefano Zampini 1556ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 1557ffd830a3SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,dummy,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 1558ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1559ffd830a3SStefano Zampini } else { 156080677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 156180677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 1562ffd830a3SStefano Zampini } 156325084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 156480677318SStefano Zampini } 156580677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 156680677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 156780677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 156806656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 156906656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 157080677318SStefano Zampini if (isCHOL) { 157180677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 157280677318SStefano Zampini } else { 157325084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 157480677318SStefano Zampini } 157580677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 157606656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 157725084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 157825084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 157925084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 158080677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 158180677318SStefano Zampini ierr = MatMatMult(M1,auxmat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 158280677318SStefano Zampini ierr = MatDestroy(&auxmat);CHKERRQ(ierr); 158306656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 158406656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 1585f4ddd8eeSStefano Zampini } 158688ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 15874f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1588d16cbb6bSStefano Zampini IS dummy; 1589d16cbb6bSStefano Zampini Mat B0_R; 1590d16cbb6bSStefano Zampini PetscReal norm; 1591d16cbb6bSStefano Zampini 15924f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 15934f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&B0_R);CHKERRQ(ierr); 1594d16cbb6bSStefano Zampini ierr = MatNorm(B0_R,NORM_INFINITY,&norm);CHKERRQ(ierr); 1595d16cbb6bSStefano Zampini if (norm > PETSC_SMALL) { 1596d16cbb6bSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! ||B0_R|| = %f (should be numerically 0.)",norm); 1597d16cbb6bSStefano Zampini } 1598d16cbb6bSStefano Zampini ierr = MatDestroy(&B0_R);CHKERRQ(ierr); 1599d16cbb6bSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1600d16cbb6bSStefano Zampini } 1601d16cbb6bSStefano Zampini 160288ebb749SStefano Zampini if (n_vertices) { 160306656605SStefano Zampini IS is_aux; 16043a50541eSStefano Zampini 16056816873aSStefano Zampini if (sub_schurs->reuse_mumps) { /* is_R_local is not sorted, ISComplement doesn't like it */ 16066816873aSStefano Zampini IS tis; 16076816873aSStefano Zampini 16086816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 16096816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 16106816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 16116816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 16126816873aSStefano Zampini } else { 16133a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 16146816873aSStefano Zampini } 1615*a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 1616*a3df083aSStefano Zampini ISLocalToGlobalMapping RtoN; 1617*a3df083aSStefano Zampini Mat B,A_RVt; 1618*a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1619*a3df083aSStefano Zampini PetscInt *idxs_p0,n; 1620*a3df083aSStefano Zampini 1621*a3df083aSStefano Zampini ierr = MatGetSubMatrix(matis->A,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RVt);CHKERRQ(ierr); 1622*a3df083aSStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_change,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 1623*a3df083aSStefano Zampini ierr = MatTranspose(B,MAT_REUSE_MATRIX,&B);CHKERRQ(ierr); 1624*a3df083aSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 1625*a3df083aSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 1626*a3df083aSStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 1627*a3df083aSStefano Zampini if (n != pcbddc->benign_n) { 1628*a3df083aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in R numbering for benign p0! %d != %d\n",n,pcbddc->benign_n); 1629*a3df083aSStefano Zampini } 1630*a3df083aSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 1631*a3df083aSStefano Zampini ierr = MatZeroRows(B,pcbddc->benign_n,idxs_p0,0.,NULL,NULL);CHKERRQ(ierr); 1632*a3df083aSStefano Zampini ierr = PetscFree(idxs_p0);CHKERRQ(ierr); 1633*a3df083aSStefano Zampini ierr = MatMatMult(B,A_RVt,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&A_RV);CHKERRQ(ierr); 1634*a3df083aSStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1635*a3df083aSStefano Zampini ierr = MatDestroy(&A_RVt);CHKERRQ(ierr); 1636*a3df083aSStefano Zampini ierr = MatTranspose(A_RV,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 1637*a3df083aSStefano Zampini ierr = MatGetSubMatrix(matis->A,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 1638*a3df083aSStefano Zampini } else { 16399577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 16409577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 164104708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 1642*a3df083aSStefano Zampini } 16434f1b2e48SStefano Zampini if (pcbddc->benign_n) { 1644019a44ceSStefano Zampini IS dummy; 1645019a44ceSStefano Zampini 16464f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 16474f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,is_aux,MAT_INITIAL_MATRIX,&B0_V);CHKERRQ(ierr); 1648019a44ceSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 1649019a44ceSStefano Zampini } 165025084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 165188ebb749SStefano Zampini } 165288ebb749SStefano Zampini 165388ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 1654f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 165506656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 165606656605SStefano Zampini if (pcbddc->coarse_phi_D) { 165706656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 165806656605SStefano Zampini } 1659f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 166006656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 166106656605SStefano Zampini PetscScalar *marray; 166206656605SStefano Zampini 166306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 166406656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 1665f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 1666f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 1667f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 1668f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 1669f4ddd8eeSStefano Zampini } 1670f4ddd8eeSStefano Zampini } 167106656605SStefano Zampini 1672f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 167306656605SStefano Zampini PetscScalar *marray; 167488ebb749SStefano Zampini 167506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 16768eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 167706656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 167888ebb749SStefano Zampini } 16793301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 168006656605SStefano Zampini n *= 2; 168188ebb749SStefano Zampini } 168206656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 168306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 168406656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 16858eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 168606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 168706656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 168888ebb749SStefano Zampini } 16893301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 169006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 16918eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 169206656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 169306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 169488ebb749SStefano Zampini } 169588ebb749SStefano Zampini } else { 1696c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 1697c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 16981b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1699c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 1700c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 1701c0553b1fSStefano Zampini } 170288ebb749SStefano Zampini } 170306656605SStefano Zampini } 1704019a44ceSStefano Zampini 170506656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 17064f1b2e48SStefano Zampini p0_lidx_I = NULL; 17074f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 1708d12edf2fSStefano Zampini const PetscInt *idxs; 1709d12edf2fSStefano Zampini 1710d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 17114f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 17124f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 17134f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 17144f1b2e48SStefano Zampini } 1715d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 1716d12edf2fSStefano Zampini } 1717d16cbb6bSStefano Zampini 171806656605SStefano Zampini /* vertices */ 171906656605SStefano Zampini if (n_vertices) { 172016f15bc4SStefano Zampini 1721ffd830a3SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 172204708bb6SStefano Zampini 172316f15bc4SStefano Zampini if (n_R) { 172406656605SStefano Zampini Mat A_RRmA_RV,S_VVt; /* S_VVt with LDA=N */ 172506656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 172616f15bc4SStefano Zampini PetscScalar *x,*y; 172704708bb6SStefano Zampini PetscBool isseqaij; 172806656605SStefano Zampini 172921eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 1730ffd830a3SStefano Zampini if (lda_rhs == n_R) { 1731ffd830a3SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 1732ffd830a3SStefano Zampini } else { 1733ca92afb2SStefano Zampini PetscScalar *av,*array; 1734ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 1735ca92afb2SStefano Zampini PetscInt n; 1736ca92afb2SStefano Zampini PetscBool flg_row; 1737ffd830a3SStefano Zampini 1738ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 1739ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 1740ca92afb2SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 1741ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1742ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 1743ca92afb2SStefano Zampini for (i=0;i<n;i++) { 1744ca92afb2SStefano Zampini PetscInt j; 1745ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 1746ffd830a3SStefano Zampini } 1747ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1748ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 1749ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 1750ffd830a3SStefano Zampini } 1751ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 17526816873aSStefano Zampini if (F) { /* TODO could be optimized for symmetric problems */ 1753*a3df083aSStefano Zampini if (need_benign_correction) { 1754*a3df083aSStefano Zampini PetscScalar *marr; 1755*a3df083aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1756*a3df083aSStefano Zampini 1757*a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 1758*a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 1759*a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1760*a3df083aSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_mumps,pcbddc->vec1_R,NULL,PETSC_FALSE);CHKERRQ(ierr); 1761*a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1762*a3df083aSStefano Zampini } 1763*a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 1764*a3df083aSStefano Zampini } 176506656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 1766*a3df083aSStefano Zampini if (need_benign_correction) { 1767*a3df083aSStefano Zampini PetscScalar *marr; 1768*a3df083aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1769*a3df083aSStefano Zampini 1770*a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 1771*a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 1772*a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 1773*a3df083aSStefano Zampini ierr = PCBDDCReuseSolversChangeInterior(reuse_mumps,pcbddc->vec1_R,NULL,PETSC_TRUE);CHKERRQ(ierr); 1774*a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1775*a3df083aSStefano Zampini } 1776*a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 1777*a3df083aSStefano Zampini } 177806656605SStefano Zampini } else { 177906656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 178006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 1781ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 1782ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 178306656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 178406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 178506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 178606656605SStefano Zampini } 178706656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 178806656605SStefano Zampini } 178980677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 1790ffd830a3SStefano Zampini /* S_VV and S_CV */ 179106656605SStefano Zampini if (n_constraints) { 179206656605SStefano Zampini Mat B; 179380677318SStefano Zampini 1794ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 179580677318SStefano Zampini for (i=0;i<n_vertices;i++) { 1796ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 1797ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 179880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 179980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 180080677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 180180677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 180280677318SStefano Zampini } 1803ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 180480677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 180580677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1806ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 180780677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 180806656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 1809ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 1810ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 181106656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 181206656605SStefano Zampini } 181304708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 181404708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 181504708bb6SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 181604708bb6SStefano Zampini } 1817ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1818ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 1819ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 1820ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 1821ffd830a3SStefano Zampini } 182206656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 182380677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 182406656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 182506656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 182606656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 182706656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 182806656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 182906656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 183006656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1831d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 1832019a44ceSStefano Zampini } else { 1833d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1834d16cbb6bSStefano Zampini } 18354f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1836019a44ceSStefano Zampini const PetscScalar *vals; 1837019a44ceSStefano Zampini const PetscInt *idxs; 18384f1b2e48SStefano Zampini PetscInt n,j,primal_idx; 1839019a44ceSStefano Zampini 18404f1b2e48SStefano Zampini ierr = MatGetRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 18414f1b2e48SStefano Zampini primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + i; 1842d16cbb6bSStefano Zampini for (j=0;j<n;j++) { 18434f1b2e48SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+idxs[j]] = vals[j]; 18444f1b2e48SStefano Zampini coarse_submat_vals[idxs[j]*pcbddc->local_primal_size+primal_idx] = vals[j]; 1845019a44ceSStefano Zampini } 18464f1b2e48SStefano Zampini ierr = MatRestoreRow(B0_V,i,&n,&idxs,&vals);CHKERRQ(ierr); 184716f15bc4SStefano Zampini } 184821eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 1849d16cbb6bSStefano Zampini 185006656605SStefano Zampini /* coarse basis functions */ 185106656605SStefano Zampini for (i=0;i<n_vertices;i++) { 185216f15bc4SStefano Zampini PetscScalar *y; 185316f15bc4SStefano Zampini 1854ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 185506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 185606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 185706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185906656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 186006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 186106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 186206656605SStefano Zampini 186306656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 18644f1b2e48SStefano Zampini PetscInt j; 18654f1b2e48SStefano Zampini 186606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 186706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 186806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 186906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 18714f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 187206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 187306656605SStefano Zampini } 187406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 187506656605SStefano Zampini } 187604708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 187704708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 187806656605SStefano Zampini } 187906656605SStefano Zampini 188006656605SStefano Zampini if (n_constraints) { 188106656605SStefano Zampini Mat B; 188206656605SStefano Zampini 1883ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 188406656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 188580677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 188606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 188706656605SStefano Zampini if (n_vertices) { 188880677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 188980677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 189080677318SStefano Zampini } else { 189180677318SStefano Zampini Mat S_VCt; 189280677318SStefano Zampini 1893ffd830a3SStefano Zampini if (lda_rhs != n_R) { 1894ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 1895ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B);CHKERRQ(ierr); 1896ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 1897ffd830a3SStefano Zampini } 189880677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 189980677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 190080677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 190180677318SStefano Zampini } 190206656605SStefano Zampini } 190306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 190406656605SStefano Zampini /* coarse basis functions */ 190506656605SStefano Zampini for (i=0;i<n_constraints;i++) { 190606656605SStefano Zampini PetscScalar *y; 190706656605SStefano Zampini 1908ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 190906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 191006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 191106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 191206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 191306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 191406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 191506656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 19164f1b2e48SStefano Zampini PetscInt j; 19174f1b2e48SStefano Zampini 191806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 191906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 192006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 192106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 192206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 19234f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 192406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 192506656605SStefano Zampini } 192606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 192706656605SStefano Zampini } 192806656605SStefano Zampini } 192980677318SStefano Zampini if (n_constraints) { 193080677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 193180677318SStefano Zampini } 19324f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 1933019a44ceSStefano Zampini ierr = MatDestroy(&B0_V);CHKERRQ(ierr); 1934019a44ceSStefano Zampini 193506656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 19363301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 1937ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 1938ffd830a3SStefano Zampini PetscScalar *marray; 193906656605SStefano Zampini 194006656605SStefano Zampini if (n_constraints) { 1941ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 194206656605SStefano Zampini 1943ffd830a3SStefano Zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 194406656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 1945ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 194616f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 194706656605SStefano Zampini if (n_vertices) { 1948ffd830a3SStefano Zampini Mat S_VCT; 194906656605SStefano Zampini 195006656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 1951ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 195216f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 195306656605SStefano Zampini } 1954ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 195506656605SStefano Zampini } 195616f15bc4SStefano Zampini if (n_vertices && n_R) { 1957ffd830a3SStefano Zampini PetscScalar *av,*marray; 1958ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 1959ffd830a3SStefano Zampini PetscInt n; 1960ffd830a3SStefano Zampini PetscBool flg_row; 196106656605SStefano Zampini 1962ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 1963ffd830a3SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 1964ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1965ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 1966ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 1967ffd830a3SStefano Zampini for (i=0;i<n;i++) { 1968ffd830a3SStefano Zampini PetscInt j; 1969ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 1970ffd830a3SStefano Zampini } 1971ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 1972ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 1973ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 197406656605SStefano Zampini } 197506656605SStefano Zampini 1976ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 1977ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 1978ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 1979ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 1980ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 198106656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 198206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 198306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 198406656605SStefano Zampini } 1985ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 1986ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 1987ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 1988ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 1989ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 1990ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1991ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 1992ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 199306656605SStefano Zampini } 1994ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 199506656605SStefano Zampini /* coarse basis functions */ 199606656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 199706656605SStefano Zampini PetscScalar *y; 199806656605SStefano Zampini 1999ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 200006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 200106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 200206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 200306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 200406656605SStefano Zampini if (i<n_vertices) { 200506656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 200606656605SStefano Zampini } 200706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 200806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 200906656605SStefano Zampini 201006656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 201106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 201206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 201306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 201506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 201606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 201706656605SStefano Zampini } 201806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 201906656605SStefano Zampini } 2020ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 2021ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 202206656605SStefano Zampini } 2023d62866d3SStefano Zampini /* free memory */ 202488ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 202506656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 202606656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 202706656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 202806656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 2029d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2030d62866d3SStefano Zampini if (n_vertices) { 2031d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 2032d62866d3SStefano Zampini } 2033d62866d3SStefano Zampini if (n_constraints) { 2034d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 2035d62866d3SStefano Zampini } 203688ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 203788ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 203888ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 2039d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 204088ebb749SStefano Zampini Mat coarse_sub_mat; 204125084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 204288ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 204388ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 204488ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 20458bec7fa6SStefano Zampini Mat C_B,CPHI; 20468bec7fa6SStefano Zampini IS is_dummy; 20478bec7fa6SStefano Zampini Vec mones; 204888ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 204988ebb749SStefano Zampini PetscReal real_value; 205088ebb749SStefano Zampini 2051*a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 2052*a3df083aSStefano Zampini Mat A; 2053*a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 2054*a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 2055*a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 2056*a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 2057*a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2058*a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 2059*a3df083aSStefano Zampini } else { 206088ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 206188ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 206288ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 206388ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 2064*a3df083aSStefano Zampini } 206588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 206688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 2067ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 206888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 206988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 207088ebb749SStefano Zampini } 207188ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 207288ebb749SStefano Zampini 207325084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 20743301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 207525084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2076ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 207788ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 207888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 207988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 208088ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 208188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 208288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 208388ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 208488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 208588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 208688ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 208788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 208888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 208988ebb749SStefano Zampini } else { 209088ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 209188ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 209288ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 209388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 209488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 209588ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 209688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 209788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 209888ebb749SStefano Zampini } 209988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 210088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 210188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 210288ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 21034f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2104d12edf2fSStefano Zampini Mat B0_I,B0_B,B0_BPHI,B0_IPHI; 2105d12edf2fSStefano Zampini PetscScalar *data,*data2; 21064f1b2e48SStefano Zampini PetscInt j; 2107d12edf2fSStefano Zampini 21084f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 21094f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B); 21104f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_I_local,MAT_INITIAL_MATRIX,&B0_I); 2111d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 2112d12edf2fSStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_REUSE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 2113d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 2114d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 21154f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 21164f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 2117d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 21184f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 21194f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 21204f1b2e48SStefano Zampini } 2121d12edf2fSStefano Zampini } 2122d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 2123d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 2124d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 2125d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2126d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 2127d12edf2fSStefano Zampini ierr = MatMatMult(B0_I,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&B0_IPHI);CHKERRQ(ierr); 2128d12edf2fSStefano Zampini ierr = MatDestroy(&B0_I);CHKERRQ(ierr); 2129d12edf2fSStefano Zampini ierr = MatNorm(B0_IPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2130d12edf2fSStefano Zampini ierr = MatDestroy(&B0_IPHI);CHKERRQ(ierr); 2131d12edf2fSStefano Zampini } 2132d12edf2fSStefano Zampini #if 0 2133d12edf2fSStefano Zampini { 2134d12edf2fSStefano Zampini PetscViewer viewer; 2135d12edf2fSStefano Zampini char filename[256]; 2136ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 2137d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 2138d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2139ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 2140ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 2141ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 2142d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 2143ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 2144ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 2145ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 2146ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 2147ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 2148ffd830a3SStefano Zampini } 2149ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 2150ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 2151ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 2152ffd830a3SStefano Zampini } 2153ffd830a3SStefano Zampini if (pcbddc->coarse_phi_B) { 2154ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 2155ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 2156ffd830a3SStefano Zampini } 2157d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2158d12edf2fSStefano Zampini } 2159d12edf2fSStefano Zampini #endif 216081d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 21618bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 21621575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 216306656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 21648bec7fa6SStefano Zampini 21658bec7fa6SStefano Zampini /* check constraints */ 21664f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 21678bec7fa6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&is_dummy);CHKERRQ(ierr); 21688bec7fa6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B); 21698bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 21708bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 21718bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 21728bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 21738bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2174bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 2175ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 2176bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 2177bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 2178bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 2179bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 2180bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 218188ebb749SStefano Zampini } 21828bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 21838bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 21848bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 21858bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 2186d12edf2fSStefano Zampini } 218725084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 218888ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 218988ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 219088ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 219188ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 219288ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 219388ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 219488ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 219588ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 219688ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 219788ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 2198ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 219988ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 220088ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 220188ebb749SStefano Zampini } 220288ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 220388ebb749SStefano Zampini } 22048629588bSStefano Zampini /* get back data */ 22058629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 220688ebb749SStefano Zampini PetscFunctionReturn(0); 220788ebb749SStefano Zampini } 220888ebb749SStefano Zampini 220988ebb749SStefano Zampini #undef __FUNCT__ 2210d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 2211d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 2212aa0d41d4SStefano Zampini { 2213d65f70fdSStefano Zampini Mat *work_mat; 2214d65f70fdSStefano Zampini IS isrow_s,iscol_s; 2215d65f70fdSStefano Zampini PetscBool rsorted,csorted; 2216d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 2217aa0d41d4SStefano Zampini PetscErrorCode ierr; 2218aa0d41d4SStefano Zampini 2219aa0d41d4SStefano Zampini PetscFunctionBegin; 2220d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 2221d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 2222d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 2223d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 2224aa0d41d4SStefano Zampini 2225d65f70fdSStefano Zampini if (!rsorted) { 2226906d46d4SStefano Zampini const PetscInt *idxs; 2227906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 2228aa0d41d4SStefano Zampini 2229d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 2230d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 2231d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2232d65f70fdSStefano Zampini idxs_perm_r[i] = i; 2233aa0d41d4SStefano Zampini } 2234d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 2235d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 2236d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2237d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 2238aa0d41d4SStefano Zampini } 2239d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 2240d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 2241d65f70fdSStefano Zampini } else { 2242d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 2243d65f70fdSStefano Zampini isrow_s = isrow; 2244aa0d41d4SStefano Zampini } 2245906d46d4SStefano Zampini 2246d65f70fdSStefano Zampini if (!csorted) { 2247d65f70fdSStefano Zampini if (isrow == iscol) { 2248d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 2249d65f70fdSStefano Zampini iscol_s = isrow_s; 2250d65f70fdSStefano Zampini } else { 2251d65f70fdSStefano Zampini const PetscInt *idxs; 2252d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 2253906d46d4SStefano Zampini 2254d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 2255d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 2256d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2257d65f70fdSStefano Zampini idxs_perm_c[i] = i; 2258d65f70fdSStefano Zampini } 2259d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 2260d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 2261d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2262d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 2263d65f70fdSStefano Zampini } 2264d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 2265d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 2266d65f70fdSStefano Zampini } 2267d65f70fdSStefano Zampini } else { 2268d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 2269d65f70fdSStefano Zampini iscol_s = iscol; 2270d65f70fdSStefano Zampini } 2271d65f70fdSStefano Zampini 2272d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 2273d65f70fdSStefano Zampini 2274d65f70fdSStefano Zampini if (!rsorted || !csorted) { 2275906d46d4SStefano Zampini Mat new_mat; 2276d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 2277906d46d4SStefano Zampini 2278d65f70fdSStefano Zampini if (!rsorted) { 2279d65f70fdSStefano Zampini PetscInt *idxs_r,i; 2280d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 2281d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 2282d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 2283906d46d4SStefano Zampini } 2284d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 2285d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 2286d65f70fdSStefano Zampini } else { 2287d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 2288906d46d4SStefano Zampini } 2289d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 2290d65f70fdSStefano Zampini 2291d65f70fdSStefano Zampini if (!csorted) { 2292d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 2293d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 2294d65f70fdSStefano Zampini is_perm_c = is_perm_r; 2295d65f70fdSStefano Zampini } else { 2296d65f70fdSStefano Zampini PetscInt *idxs_c,i; 2297d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 2298d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 2299d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 2300d65f70fdSStefano Zampini } 2301d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 2302d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 2303d65f70fdSStefano Zampini } 2304d65f70fdSStefano Zampini } else { 2305d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 2306d65f70fdSStefano Zampini } 2307d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 2308d65f70fdSStefano Zampini 2309d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 2310d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 2311d65f70fdSStefano Zampini work_mat[0] = new_mat; 2312d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 2313d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 2314d65f70fdSStefano Zampini } 2315d65f70fdSStefano Zampini 2316d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 2317d65f70fdSStefano Zampini *B = work_mat[0]; 2318d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 2319d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 2320d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 2321d65f70fdSStefano Zampini PetscFunctionReturn(0); 2322d65f70fdSStefano Zampini } 2323d65f70fdSStefano Zampini 2324d65f70fdSStefano Zampini #undef __FUNCT__ 23255e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 23265e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 2327aa0d41d4SStefano Zampini { 2328aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 23295e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2330d65f70fdSStefano Zampini Mat new_mat; 23315e8657edSStefano Zampini IS is_local,is_global; 2332d65f70fdSStefano Zampini PetscInt local_size; 2333d65f70fdSStefano Zampini PetscBool isseqaij; 2334aa0d41d4SStefano Zampini PetscErrorCode ierr; 2335aa0d41d4SStefano Zampini 2336aa0d41d4SStefano Zampini PetscFunctionBegin; 2337aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 23385e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 23395e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 2340b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 2341aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 2342d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 2343aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 2344906d46d4SStefano Zampini 2345906d46d4SStefano Zampini /* check */ 2346906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2347906d46d4SStefano Zampini Vec x,x_change; 2348906d46d4SStefano Zampini PetscReal error; 2349906d46d4SStefano Zampini 23505e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 2351906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 23525e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 2353e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2354e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2355d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 2356e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2357e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2358906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2359906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2360906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2361906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 2362906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2363906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2364906d46d4SStefano Zampini } 2365906d46d4SStefano Zampini 236622d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 23679b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 236822d5777bSStefano Zampini if (isseqaij) { 23691cf9b237SStefano Zampini Mat M; 23701cf9b237SStefano Zampini 23711cf9b237SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 23721cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 23731cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2374aa0d41d4SStefano Zampini } else { 23751cf9b237SStefano Zampini Mat work_mat,M; 23761cf9b237SStefano Zampini 2377aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 23781cf9b237SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 23791cf9b237SStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 23801cf9b237SStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2381aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 2382aa0d41d4SStefano Zampini } 23833301b35fSStefano Zampini if (matis->A->symmetric_set) { 23843301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 2385e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 23863301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 2387e496cd5dSStefano Zampini #endif 23883301b35fSStefano Zampini } 238945a1bb75SStefano Zampini /* 239045a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2391d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 239245a1bb75SStefano Zampini */ 2393d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 2394aa0d41d4SStefano Zampini PetscFunctionReturn(0); 2395aa0d41d4SStefano Zampini } 2396aa0d41d4SStefano Zampini 2397aa0d41d4SStefano Zampini #undef __FUNCT__ 2398a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 23998ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 2400a64d13efSStefano Zampini { 2401a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2402a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2403d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 240453892102SStefano Zampini PetscInt *idx_R_local=NULL; 24053a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 24063a50541eSStefano Zampini PetscInt vbs,bs; 24076816873aSStefano Zampini PetscBT bitmask=NULL; 2408a64d13efSStefano Zampini PetscErrorCode ierr; 2409a64d13efSStefano Zampini 2410a64d13efSStefano Zampini PetscFunctionBegin; 2411b23d619eSStefano Zampini /* 2412b23d619eSStefano Zampini No need to setup local scatters if 2413b23d619eSStefano Zampini - primal space is unchanged 2414b23d619eSStefano Zampini AND 2415b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 2416b23d619eSStefano Zampini AND 2417b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 2418b23d619eSStefano Zampini */ 2419b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 2420f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 2421f4ddd8eeSStefano Zampini } 2422f4ddd8eeSStefano Zampini /* destroy old objects */ 2423f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 2424f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 2425f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 2426a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 2427b371cd4fSStefano Zampini n_B = pcis->n_B; 2428b371cd4fSStefano Zampini n_D = pcis->n - n_B; 2429b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 24303a50541eSStefano Zampini 2431a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 24326816873aSStefano Zampini 243353892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 24346816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 2435854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 2436a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 2437a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 24380e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 2439a64d13efSStefano Zampini } 2440a64d13efSStefano Zampini 2441a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 24424641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 24436816873aSStefano Zampini idx_R_local[n_R++] = i; 2444a64d13efSStefano Zampini } 2445a64d13efSStefano Zampini } 244653892102SStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing MUMPS Schur solver */ 24476816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 24486816873aSStefano Zampini 244953892102SStefano Zampini ierr = ISGetIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 245053892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_R,&n_R);CHKERRQ(ierr); 24516816873aSStefano Zampini } 24523a50541eSStefano Zampini 24533a50541eSStefano Zampini /* Block code */ 24543a50541eSStefano Zampini vbs = 1; 24553a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 24563a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 24573a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 24583a50541eSStefano Zampini PetscInt *vary; 2459d3df7717SStefano Zampini if (!sub_schurs->reuse_mumps) { 2460785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 24613a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 2462d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 2463d3df7717SStefano 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 */ 24640e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 2465d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 24663a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 24673a50541eSStefano Zampini is_blocked = PETSC_FALSE; 24683a50541eSStefano Zampini break; 24693a50541eSStefano Zampini } 24703a50541eSStefano Zampini } 2471d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 2472d3df7717SStefano Zampini } else { 2473d3df7717SStefano Zampini /* Verify directly the R set */ 2474d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 2475d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 2476d3df7717SStefano Zampini for (j=1; j<bs; j++) { 2477d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 2478d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 2479d3df7717SStefano Zampini break; 2480d3df7717SStefano Zampini } 2481d3df7717SStefano Zampini } 2482d3df7717SStefano Zampini } 2483d3df7717SStefano Zampini } 24843a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 24853a50541eSStefano Zampini vbs = bs; 24863a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 24873a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 24883a50541eSStefano Zampini } 24893a50541eSStefano Zampini } 24903a50541eSStefano Zampini } 24913a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 249253892102SStefano Zampini if (sub_schurs->reuse_mumps) { 249353892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 249453892102SStefano Zampini 249553892102SStefano Zampini ierr = ISRestoreIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 249653892102SStefano Zampini ierr = ISDestroy(&reuse_mumps->is_R);CHKERRQ(ierr); 249753892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 249853892102SStefano Zampini reuse_mumps->is_R = pcbddc->is_R_local; 249953892102SStefano Zampini } else { 25003a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 250153892102SStefano Zampini } 2502a64d13efSStefano Zampini 2503a64d13efSStefano Zampini /* print some info if requested */ 2504a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 2505a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2506a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 25071575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2508a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 2509a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 25104f1b2e48SStefano 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); 2511a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2512a64d13efSStefano Zampini } 2513a64d13efSStefano Zampini 2514a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 25156816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 25166816873aSStefano Zampini IS is_aux1,is_aux2; 25176816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 25186816873aSStefano Zampini 25193a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2520854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 2521854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 2522a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 25234641a718SStefano Zampini for (i=0; i<n_D; i++) { 25244641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 25254641a718SStefano Zampini } 2526a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2527a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 25284641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 25294641a718SStefano Zampini aux_array1[j++] = i; 2530a64d13efSStefano Zampini } 2531a64d13efSStefano Zampini } 2532a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2533a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2534a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 25354641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 25364641a718SStefano Zampini aux_array2[j++] = i; 2537a64d13efSStefano Zampini } 2538a64d13efSStefano Zampini } 2539a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2540a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 2541a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 2542a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2543a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 2544a64d13efSStefano Zampini 25458eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 2546785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 2547a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 25484641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 25494641a718SStefano Zampini aux_array1[j++] = i; 2550a64d13efSStefano Zampini } 2551a64d13efSStefano Zampini } 2552a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 2553a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 2554a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 2555a64d13efSStefano Zampini } 25564641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 25573a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 2558d62866d3SStefano Zampini } else { 255953892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 25606816873aSStefano Zampini IS tis; 25616816873aSStefano Zampini PetscInt schur_size; 25626816873aSStefano Zampini 256353892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_B,&schur_size);CHKERRQ(ierr); 25646816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 256553892102SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_mumps->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 25666816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 25676816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 25686816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 25696816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 25706816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 2571d62866d3SStefano Zampini } 2572d62866d3SStefano Zampini } 2573a64d13efSStefano Zampini PetscFunctionReturn(0); 2574a64d13efSStefano Zampini } 2575a64d13efSStefano Zampini 2576304d26faSStefano Zampini 2577304d26faSStefano Zampini #undef __FUNCT__ 2578304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 2579684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 2580304d26faSStefano Zampini { 2581304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2582304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2583304d26faSStefano Zampini PC pc_temp; 2584304d26faSStefano Zampini Mat A_RR; 2585f4ddd8eeSStefano Zampini MatReuse reuse; 2586304d26faSStefano Zampini PetscScalar m_one = -1.0; 2587304d26faSStefano Zampini PetscReal value; 258804708bb6SStefano Zampini PetscInt n_D,n_R; 25899577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 2590304d26faSStefano Zampini PetscErrorCode ierr; 2591e604994aSStefano Zampini /* prefixes stuff */ 2592312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 2593e604994aSStefano Zampini size_t len; 2594304d26faSStefano Zampini 2595304d26faSStefano Zampini PetscFunctionBegin; 2596304d26faSStefano Zampini 2597e604994aSStefano Zampini /* compute prefixes */ 2598e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 2599e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 2600e604994aSStefano Zampini if (!pcbddc->current_level) { 2601e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2602e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 2603e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2604e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2605e604994aSStefano Zampini } else { 2606e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 2607312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 2608e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 2609e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 2610312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 2611312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 261234d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 261334d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 2614e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 2615e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 2616e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 2617e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 2618e604994aSStefano Zampini } 2619e604994aSStefano Zampini 2620304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 2621684f6988SStefano Zampini if (dirichlet) { 2622d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2623*a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit && pcbddc->dbg_flag) { 2624*a3df083aSStefano Zampini Mat A_IIn; 2625*a3df083aSStefano Zampini 2626*a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 2627*a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 2628*a3df083aSStefano Zampini pcis->A_II = A_IIn; 2629*a3df083aSStefano Zampini } 26303301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 26313301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 2632964fefecSStefano Zampini } 2633ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 2634964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 2635304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 2636304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 2637304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 2638304d26faSStefano Zampini /* default */ 2639304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 2640e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 26419577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 2642304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 26439577ea80SStefano Zampini if (issbaij) { 26449577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 26459577ea80SStefano Zampini } else { 2646304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 26479577ea80SStefano Zampini } 2648304d26faSStefano Zampini /* Allow user's customization */ 2649304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 2650304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2651304d26faSStefano Zampini } 2652d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 2653d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2654d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2655d62866d3SStefano Zampini 2656d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_mumps->interior_solver);CHKERRQ(ierr); 2657d5574798SStefano Zampini } 2658304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2659304d26faSStefano Zampini if (!n_D) { 2660304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 2661304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2662304d26faSStefano Zampini } 2663304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 2664304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 2665304d26faSStefano Zampini /* set ksp_D into pcis data */ 2666304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 2667304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 2668304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 2669684f6988SStefano Zampini } 2670304d26faSStefano Zampini 2671304d26faSStefano Zampini /* NEUMANN PROBLEM */ 2672684f6988SStefano Zampini A_RR = 0; 2673684f6988SStefano Zampini if (neumann) { 2674d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 267504708bb6SStefano Zampini PetscInt ibs,mbs; 267604708bb6SStefano Zampini PetscBool issbaij; 267704708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 2678f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 26798ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 2680f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 2681f4ddd8eeSStefano Zampini PetscInt nn_R; 268281d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 2683f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 2684f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 2685f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 2686f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 2687f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2688f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2689f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 2690727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 2691f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2692f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2693f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 2694f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 2695f4ddd8eeSStefano Zampini } 2696f4ddd8eeSStefano Zampini } 2697f4ddd8eeSStefano Zampini /* last check */ 2698d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 2699f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2700f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2701f4ddd8eeSStefano Zampini } 2702f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 2703f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 2704f4ddd8eeSStefano Zampini } 2705f4ddd8eeSStefano Zampini /* extract A_RR */ 2706af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 2707af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 270804708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 270904708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 271004708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 271104708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 271204708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 2713af732b37SStefano Zampini } else { 271404708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 27156816873aSStefano Zampini } 271604708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 271704708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 271804708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 271904708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 272004708bb6SStefano Zampini } else { 272104708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 272204708bb6SStefano Zampini } 272304708bb6SStefano Zampini } 2724f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 27253301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 27263301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 27276816873aSStefano Zampini } 2728*a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit && pcbddc->dbg_flag) { 2729*a3df083aSStefano Zampini Mat A_RRn; 2730*a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RRn);CHKERRQ(ierr); 2731*a3df083aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2732*a3df083aSStefano Zampini A_RR = A_RRn; 2733*a3df083aSStefano Zampini } 2734f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 2735304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 2736304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 2737304d26faSStefano Zampini /* default */ 2738304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 2739e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 2740304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 27419577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 27429577ea80SStefano Zampini if (issbaij) { 27439577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 27449577ea80SStefano Zampini } else { 2745304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 27469577ea80SStefano Zampini } 2747304d26faSStefano Zampini /* Allow user's customization */ 2748304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 2749304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 2750304d26faSStefano Zampini } 2751304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 2752304d26faSStefano Zampini if (!n_R) { 2753304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 2754304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 2755304d26faSStefano Zampini } 2756d62866d3SStefano Zampini /* Reuse MUMPS solver if it is present */ 2757d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 2758d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2759d62866d3SStefano Zampini 2760d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_mumps->correction_solver);CHKERRQ(ierr); 2761d62866d3SStefano Zampini } 2762ffd830a3SStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 2763304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 2764304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 2765684f6988SStefano Zampini } 27666816873aSStefano Zampini /* free Neumann problem's matrix */ 27676816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 2768304d26faSStefano Zampini 2769304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 27700fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 2771684f6988SStefano Zampini if (pcbddc->dbg_flag) { 2772684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 27731575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2774684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2775684f6988SStefano Zampini } 2776684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 27770fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 27780fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 27790fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 27800fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 27810fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 2782304d26faSStefano Zampini /* need to be adapted? */ 2783b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2784b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2785b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 2786304d26faSStefano Zampini /* print info */ 2787304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2788e604994aSStefano 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); 2789304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2790304d26faSStefano Zampini } 2791b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 2792298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 2793304d26faSStefano Zampini } 2794684f6988SStefano Zampini } 2795684f6988SStefano Zampini if (neumann) { /* Neumann */ 27966816873aSStefano Zampini ierr = KSPGetOperators(pcbddc->ksp_R,&A_RR,NULL);CHKERRQ(ierr); 27970fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 27980fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 27990fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 28000fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 28010fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 2802304d26faSStefano Zampini /* need to be adapted? */ 2803b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 2804b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2805304d26faSStefano Zampini /* print info */ 2806304d26faSStefano Zampini if (pcbddc->dbg_flag) { 2807e604994aSStefano 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); 2808304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2809304d26faSStefano Zampini } 2810b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 2811298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 2812304d26faSStefano Zampini } 28130fccc4e9SStefano Zampini } 2814684f6988SStefano Zampini } 2815304d26faSStefano Zampini PetscFunctionReturn(0); 2816304d26faSStefano Zampini } 2817304d26faSStefano Zampini 2818304d26faSStefano Zampini #undef __FUNCT__ 2819ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 282080677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 2821674ae819SStefano Zampini { 2822674ae819SStefano Zampini PetscErrorCode ierr; 2823674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2824be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2825674ae819SStefano Zampini 2826674ae819SStefano Zampini PetscFunctionBegin; 2827be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 282880677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 282920c7b377SStefano Zampini } 283080677318SStefano Zampini if (!pcbddc->switch_static) { 283180677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 283280677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 283380677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 283420c7b377SStefano Zampini } 2835be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 283680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 283780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 283820c7b377SStefano Zampini } else { 2839be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2840be83ff47SStefano Zampini 284153892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 284253892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 284320c7b377SStefano Zampini } 2844be83ff47SStefano Zampini } else { 284580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 284680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 284780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 284880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 284980677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 285080677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 285180677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 285280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 285380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2854674ae819SStefano Zampini } 2855674ae819SStefano Zampini } 2856be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 285780677318SStefano Zampini if (applytranspose) { 285880677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 285980677318SStefano Zampini } else { 286080677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 286180677318SStefano Zampini } 2862be83ff47SStefano Zampini } else { 2863be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2864be83ff47SStefano Zampini 2865be83ff47SStefano Zampini if (applytranspose) { 28665a05ddb0SStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2867be83ff47SStefano Zampini } else { 28685a05ddb0SStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 2869be83ff47SStefano Zampini } 2870be83ff47SStefano Zampini } 287180677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 287280677318SStefano Zampini if (!pcbddc->switch_static) { 2873be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 287480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 287580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2876be83ff47SStefano Zampini } else { 2877be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 2878be83ff47SStefano Zampini 287953892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 288053892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2881be83ff47SStefano Zampini } 288280677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 288380677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 288480677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 288580677318SStefano Zampini } 288680677318SStefano Zampini } else { 288780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 288880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 288980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 289080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 289180677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 289280677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 289380677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 289480677318SStefano Zampini } 289580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 289680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 289780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 289880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2899674ae819SStefano Zampini } 2900674ae819SStefano Zampini PetscFunctionReturn(0); 2901674ae819SStefano Zampini } 2902674ae819SStefano Zampini 2903dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 2904674ae819SStefano Zampini #undef __FUNCT__ 2905674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 2906dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 2907674ae819SStefano Zampini { 2908674ae819SStefano Zampini PetscErrorCode ierr; 2909674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 2910674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 2911674ae819SStefano Zampini const PetscScalar zero = 0.0; 2912674ae819SStefano Zampini 2913674ae819SStefano Zampini PetscFunctionBegin; 2914dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 2915dc359a40SStefano Zampini if (applytranspose) { 2916674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 29178eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 2918dc359a40SStefano Zampini } else { 2919674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 2920674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 292115aaf578SStefano Zampini } 2922efc2fbd9SStefano Zampini 2923efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 29244f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2925efc2fbd9SStefano Zampini PetscScalar *array; 29264f1b2e48SStefano Zampini PetscInt j; 2927efc2fbd9SStefano Zampini 2928efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 29294f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 2930efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2931efc2fbd9SStefano Zampini } 2932efc2fbd9SStefano Zampini 293312edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 293412edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 293512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 293612edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 293712edc857SStefano Zampini 29389f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 293912edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 294012edc857SStefano Zampini if (pcbddc->coarse_ksp) { 294151694757SStefano Zampini Mat coarse_mat; 2942964fefecSStefano Zampini Vec rhs,sol; 294351694757SStefano Zampini MatNullSpace nullsp; 2944964fefecSStefano Zampini 2945964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 2946964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 294751694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 294851694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 294951694757SStefano Zampini if (nullsp) { 295051694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 295151694757SStefano Zampini } 295212edc857SStefano Zampini if (applytranspose) { 2953964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 295412edc857SStefano Zampini } else { 2955964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 295612edc857SStefano Zampini } 295751694757SStefano Zampini if (nullsp) { 295851694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 295951694757SStefano Zampini } 296012edc857SStefano Zampini } 2961674ae819SStefano Zampini 2962674ae819SStefano Zampini /* Local solution on R nodes */ 296380677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 296480677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 29659f00e9b4SStefano Zampini } 2966674ae819SStefano Zampini 29679f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 29689f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 296912edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2970674ae819SStefano Zampini 2971674ae819SStefano Zampini /* Sum contributions from two levels */ 2972dc359a40SStefano Zampini if (applytranspose) { 2973dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2974dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2975dc359a40SStefano Zampini } else { 2976674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 29778eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2978dc359a40SStefano Zampini } 2979efc2fbd9SStefano Zampini /* store p0 */ 29804f1b2e48SStefano Zampini if (pcbddc->benign_n) { 2981efc2fbd9SStefano Zampini PetscScalar *array; 29824f1b2e48SStefano Zampini PetscInt j; 2983efc2fbd9SStefano Zampini 2984efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 29854f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 2986efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 2987efc2fbd9SStefano Zampini } 2988674ae819SStefano Zampini PetscFunctionReturn(0); 2989674ae819SStefano Zampini } 2990674ae819SStefano Zampini 2991674ae819SStefano Zampini #undef __FUNCT__ 2992674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 299312edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 2994674ae819SStefano Zampini { 2995674ae819SStefano Zampini PetscErrorCode ierr; 2996674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 299758da7f69SStefano Zampini PetscScalar *array; 299812edc857SStefano Zampini Vec from,to; 2999674ae819SStefano Zampini 3000674ae819SStefano Zampini PetscFunctionBegin; 300112edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 300212edc857SStefano Zampini from = pcbddc->coarse_vec; 300312edc857SStefano Zampini to = pcbddc->vec1_P; 300412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 300512edc857SStefano Zampini Vec tvec; 300658da7f69SStefano Zampini 300758da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 300858da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 300912edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 301058da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 301158da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 301258da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 301312edc857SStefano Zampini } 301412edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 301512edc857SStefano Zampini from = pcbddc->vec1_P; 301612edc857SStefano Zampini to = pcbddc->coarse_vec; 301712edc857SStefano Zampini } 301812edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 3019674ae819SStefano Zampini PetscFunctionReturn(0); 3020674ae819SStefano Zampini } 3021674ae819SStefano Zampini 3022674ae819SStefano Zampini #undef __FUNCT__ 3023674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 302412edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 3025674ae819SStefano Zampini { 3026674ae819SStefano Zampini PetscErrorCode ierr; 3027674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 302858da7f69SStefano Zampini PetscScalar *array; 302912edc857SStefano Zampini Vec from,to; 3030674ae819SStefano Zampini 3031674ae819SStefano Zampini PetscFunctionBegin; 303212edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 303312edc857SStefano Zampini from = pcbddc->coarse_vec; 303412edc857SStefano Zampini to = pcbddc->vec1_P; 303512edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 303612edc857SStefano Zampini from = pcbddc->vec1_P; 303712edc857SStefano Zampini to = pcbddc->coarse_vec; 303812edc857SStefano Zampini } 303912edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 304012edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 304112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 304212edc857SStefano Zampini Vec tvec; 304358da7f69SStefano Zampini 304412edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 304558da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 304658da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 304758da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 304858da7f69SStefano Zampini } 304958da7f69SStefano Zampini } else { 305058da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 305158da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 305212edc857SStefano Zampini } 305312edc857SStefano Zampini } 3054674ae819SStefano Zampini PetscFunctionReturn(0); 3055674ae819SStefano Zampini } 3056674ae819SStefano Zampini 3057984c4197SStefano Zampini /* uncomment for testing purposes */ 3058984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 3059674ae819SStefano Zampini #undef __FUNCT__ 3060674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 3061674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 3062674ae819SStefano Zampini { 3063674ae819SStefano Zampini PetscErrorCode ierr; 3064674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 3065674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3066674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 3067984c4197SStefano Zampini /* one and zero */ 3068984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 3069984c4197SStefano Zampini /* space to store constraints and their local indices */ 30709162d606SStefano Zampini PetscScalar *constraints_data; 30719162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 30729162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 30739162d606SStefano Zampini PetscInt *constraints_n; 3074984c4197SStefano Zampini /* iterators */ 3075b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 3076984c4197SStefano Zampini /* BLAS integers */ 3077e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 3078e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 3079c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 3080727cdba6SStefano Zampini /* reuse */ 30810e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 30820e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 3083984c4197SStefano Zampini /* change of basis */ 3084b3d85658SStefano Zampini PetscBool qr_needed; 30859162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 3086984c4197SStefano Zampini /* auxiliary stuff */ 308764efe560SStefano Zampini PetscInt *nnz,*is_indices; 30888a0068c3SStefano Zampini PetscInt ncc; 3089984c4197SStefano Zampini /* some quantities */ 309045a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 3091a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 3092984c4197SStefano Zampini 3093674ae819SStefano Zampini PetscFunctionBegin; 30948e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 30958e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 30968e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3097088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 3098088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 30990e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 31000e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 31010e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 31020e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 31030e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3104088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3105cf5a6209SStefano Zampini 3106cf5a6209SStefano Zampini /* print some info */ 3107cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 3108cf5a6209SStefano Zampini IS vertices; 3109cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 3110cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 3111cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 3112cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 31131575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3114cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3115cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 3116fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 3117fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 3118cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 31191575c14dSBarry Smith ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3120cf5a6209SStefano Zampini } 3121cf5a6209SStefano Zampini 3122cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 31239162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 3124cf5a6209SStefano Zampini MatNullSpace nearnullsp; 3125cf5a6209SStefano Zampini const Vec *nearnullvecs; 3126cf5a6209SStefano Zampini Vec *localnearnullsp; 3127cf5a6209SStefano Zampini PetscScalar *array; 3128cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 3129cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 3130674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 3131b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 3132674ae819SStefano Zampini PetscScalar *work; 3133674ae819SStefano Zampini PetscReal *singular_vals; 3134674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3135674ae819SStefano Zampini PetscReal *rwork; 3136674ae819SStefano Zampini #endif 3137674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3138674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 3139674ae819SStefano Zampini #else 3140964fefecSStefano Zampini PetscBLASInt dummy_int=1; 3141964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 3142674ae819SStefano Zampini #endif 3143674ae819SStefano Zampini 3144674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 3145d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 3146d06fc5fdSStefano Zampini /* free unneeded index sets */ 3147d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 3148d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 3149674ae819SStefano Zampini } 3150d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 3151d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3152d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3153d06fc5fdSStefano Zampini } 3154d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3155d06fc5fdSStefano Zampini n_ISForEdges = 0; 3156d06fc5fdSStefano Zampini } 3157d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 3158d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3159d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3160d06fc5fdSStefano Zampini } 3161d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3162d06fc5fdSStefano Zampini n_ISForFaces = 0; 3163d06fc5fdSStefano Zampini } 316470022509SStefano Zampini 316570022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 316670022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 316770022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 316870022509SStefano Zampini if (pcbddc->NullSpace) { 316970022509SStefano Zampini PetscBool tbool[2],gbool[2]; 317070022509SStefano Zampini 317170022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 3172b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 3173d06fc5fdSStefano Zampini if (!ISForEdges) { 3174d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 3175d06fc5fdSStefano Zampini } 3176b8ffe317SStefano Zampini } 3177d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 3178d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 3179d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3180d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 3181d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 318298a51de6SStefano Zampini } 318370022509SStefano Zampini #endif 318408122e43SStefano Zampini 3185674ae819SStefano Zampini /* check if near null space is attached to global mat */ 3186674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 3187674ae819SStefano Zampini if (nearnullsp) { 3188674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 3189f4ddd8eeSStefano Zampini /* remove any stored info */ 3190f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3191f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3192f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 3193f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 3194f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 3195473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3196f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 3197f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 3198f4ddd8eeSStefano Zampini } 3199984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 3200984c4197SStefano Zampini nnsp_size = 0; 3201674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 3202674ae819SStefano Zampini } 3203984c4197SStefano Zampini /* get max number of constraints on a single cc */ 3204984c4197SStefano Zampini max_constraints = nnsp_size; 3205984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 3206984c4197SStefano Zampini 3207674ae819SStefano Zampini /* 3208674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 32099162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 32109162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 32119162d606SStefano Zampini There can be multiple constraints per connected component 3212674ae819SStefano Zampini */ 3213674ae819SStefano Zampini n_vertices = 0; 3214674ae819SStefano Zampini if (ISForVertices) { 3215674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 3216674ae819SStefano Zampini } 32179162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 32189162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 32199162d606SStefano Zampini 32209162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 32219162d606SStefano Zampini total_counts *= max_constraints; 3222674ae819SStefano Zampini total_counts += n_vertices; 32234641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 32249162d606SStefano Zampini 3225674ae819SStefano Zampini total_counts = 0; 3226674ae819SStefano Zampini max_size_of_constraint = 0; 3227674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 32289162d606SStefano Zampini IS used_is; 3229674ae819SStefano Zampini if (i<n_ISForEdges) { 32309162d606SStefano Zampini used_is = ISForEdges[i]; 3231674ae819SStefano Zampini } else { 32329162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 3233674ae819SStefano Zampini } 32349162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 3235674ae819SStefano Zampini total_counts += j; 3236674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 3237674ae819SStefano Zampini } 32389162d606SStefano 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); 32399162d606SStefano Zampini 3240984c4197SStefano Zampini /* get local part of global near null space vectors */ 3241785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 3242984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3243984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 3244e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3245e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3246984c4197SStefano Zampini } 3247674ae819SStefano Zampini 3248242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 3249242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 3250a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 3251242a89d7SStefano Zampini 3252984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 3253a773dcb8SStefano Zampini if (!skip_lapack) { 3254674ae819SStefano Zampini PetscScalar temp_work; 3255911cabfeSStefano Zampini 3256674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3257984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 3258785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 3259785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 3260785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 3261674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3262785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 3263674ae819SStefano Zampini #endif 3264674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3265c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 3266c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 3267674ae819SStefano Zampini lwork = -1; 3268674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3269674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3270c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 3271674ae819SStefano Zampini #else 3272c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 3273674ae819SStefano Zampini #endif 3274674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3275984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 3276674ae819SStefano Zampini #else /* on missing GESVD */ 3277674ae819SStefano Zampini /* SVD */ 3278674ae819SStefano Zampini PetscInt max_n,min_n; 3279674ae819SStefano Zampini max_n = max_size_of_constraint; 3280984c4197SStefano Zampini min_n = max_constraints; 3281984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 3282674ae819SStefano Zampini min_n = max_size_of_constraint; 3283984c4197SStefano Zampini max_n = max_constraints; 3284674ae819SStefano Zampini } 3285785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 3286674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3287785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 3288674ae819SStefano Zampini #endif 3289674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 3290674ae819SStefano Zampini lwork = -1; 3291e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 3292e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 3293b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 3294674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3295674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 32969162d606SStefano 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)); 3297674ae819SStefano Zampini #else 32989162d606SStefano 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)); 3299674ae819SStefano Zampini #endif 3300674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3301984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 3302984c4197SStefano Zampini #endif /* on missing GESVD */ 3303674ae819SStefano Zampini /* Allocate optimal workspace */ 3304674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 3305854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 3306674ae819SStefano Zampini } 3307674ae819SStefano Zampini /* Now we can loop on constraining sets */ 3308674ae819SStefano Zampini total_counts = 0; 33099162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 33109162d606SStefano Zampini constraints_data_ptr[0] = 0; 3311674ae819SStefano Zampini /* vertices */ 33129162d606SStefano Zampini if (n_vertices) { 3313674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 33149162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 3315674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 33169162d606SStefano Zampini constraints_n[total_counts] = 1; 33179162d606SStefano Zampini constraints_data[total_counts] = 1.0; 33189162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 33199162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 3320674ae819SStefano Zampini total_counts++; 3321674ae819SStefano Zampini } 3322674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3323674ae819SStefano Zampini n_vertices = total_counts; 3324674ae819SStefano Zampini } 3325984c4197SStefano Zampini 3326674ae819SStefano Zampini /* edges and faces */ 33279162d606SStefano Zampini total_counts_cc = total_counts; 3328911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 33299162d606SStefano Zampini IS used_is; 33309162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 33319162d606SStefano Zampini 3332911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 33339162d606SStefano Zampini used_is = ISForEdges[ncc]; 3334984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 3335674ae819SStefano Zampini } else { 33369162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 3337984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 3338674ae819SStefano Zampini } 3339674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 33409162d606SStefano Zampini 33419162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 33429162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3343984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 3344984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 3345674ae819SStefano Zampini if (nnsp_has_cnst) { 33465b08dc53SStefano Zampini PetscScalar quad_value; 33479162d606SStefano Zampini 33489162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 33499162d606SStefano Zampini idxs_copied = PETSC_TRUE; 33509162d606SStefano Zampini 3351a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 3352674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 3353a773dcb8SStefano Zampini } else { 3354a773dcb8SStefano Zampini quad_value = 1.0; 3355a773dcb8SStefano Zampini } 3356674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 33579162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 3358674ae819SStefano Zampini } 33599162d606SStefano Zampini temp_constraints++; 3360674ae819SStefano Zampini total_counts++; 3361674ae819SStefano Zampini } 3362674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 3363984c4197SStefano Zampini PetscReal real_value; 33649162d606SStefano Zampini PetscScalar *ptr_to_data; 33659162d606SStefano Zampini 3366984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 33679162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 3368674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 33699162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 3370674ae819SStefano Zampini } 3371984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 3372984c4197SStefano Zampini /* check if array is null on the connected component */ 3373e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 33749162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 33755b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 3376674ae819SStefano Zampini temp_constraints++; 3377674ae819SStefano Zampini total_counts++; 33789162d606SStefano Zampini if (!idxs_copied) { 33799162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 33809162d606SStefano Zampini idxs_copied = PETSC_TRUE; 3381674ae819SStefano Zampini } 3382674ae819SStefano Zampini } 33839162d606SStefano Zampini } 33849162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 338545a1bb75SStefano Zampini valid_constraints = temp_constraints; 3386eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 3387a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 33889162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 33899162d606SStefano Zampini 33909162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3391a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 33929162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 3393a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 33949162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 3395a773dcb8SStefano Zampini } else { /* perform SVD */ 3396984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 33979162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 3398674ae819SStefano Zampini 3399674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3400984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 3401984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 3402984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 3403984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 3404984c4197SStefano Zampini from that computed using LAPACKgesvd 3405984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 3406984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 3407984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 3408674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 3409e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3410984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3411674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 3412674ae819SStefano Zampini for (k=0;k<j+1;k++) { 34139162d606SStefano 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)); 3414674ae819SStefano Zampini } 3415674ae819SStefano Zampini } 3416e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 3417e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3418e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 3419674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 3420c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 3421674ae819SStefano Zampini #else 3422c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 3423674ae819SStefano Zampini #endif 3424674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3425984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 3426984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 3427674ae819SStefano Zampini j = 0; 3428984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 3429674ae819SStefano Zampini total_counts = total_counts-j; 343045a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 3431e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 3432c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3433c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3434c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 3435c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3436c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 3437c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3438674ae819SStefano Zampini if (j<temp_constraints) { 3439984c4197SStefano Zampini PetscInt ii; 3440984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 3441674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 34429162d606SStefano 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)); 3443674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3444984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 3445674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 34469162d606SStefano 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]; 3447674ae819SStefano Zampini } 3448674ae819SStefano Zampini } 3449674ae819SStefano Zampini } 3450674ae819SStefano Zampini #else /* on missing GESVD */ 3451e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 3452e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 3453b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3454674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3455674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 34569162d606SStefano 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)); 3457674ae819SStefano Zampini #else 34589162d606SStefano 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)); 3459674ae819SStefano Zampini #endif 3460984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 3461674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3462984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 3463e310c8b4SStefano Zampini k = temp_constraints; 3464e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 3465674ae819SStefano Zampini j = 0; 3466e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 346745a1bb75SStefano Zampini valid_constraints = k-j; 3468911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 3469984c4197SStefano Zampini #endif /* on missing GESVD */ 3470674ae819SStefano Zampini } 3471a773dcb8SStefano Zampini } 34729162d606SStefano Zampini /* update pointers information */ 34739162d606SStefano Zampini if (valid_constraints) { 34749162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 34759162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 34769162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 34779162d606SStefano Zampini /* set change_of_basis flag */ 347845a1bb75SStefano Zampini if (boolforchange) { 3479b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 34809162d606SStefano Zampini } 3481b3d85658SStefano Zampini total_counts_cc++; 348245a1bb75SStefano Zampini } 348345a1bb75SStefano Zampini } 3484984c4197SStefano Zampini /* free workspace */ 34858f1c130eSStefano Zampini if (!skip_lapack) { 3486984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3487984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3488984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 3489984c4197SStefano Zampini #endif 3490984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 3491984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 3492984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 3493984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 3494984c4197SStefano Zampini #endif 3495984c4197SStefano Zampini } 3496984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 3497984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 3498984c4197SStefano Zampini } 3499984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 3500cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 3501cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 3502cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 3503cf5a6209SStefano Zampini } 3504cf5a6209SStefano Zampini if (n_ISForFaces) { 3505cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 3506cf5a6209SStefano Zampini } 3507cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 3508cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 3509cf5a6209SStefano Zampini } 3510cf5a6209SStefano Zampini if (n_ISForEdges) { 3511cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 3512cf5a6209SStefano Zampini } 3513cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 351408122e43SStefano Zampini } else { 351508122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 3516984c4197SStefano Zampini 351708122e43SStefano Zampini total_counts = 0; 351808122e43SStefano Zampini n_vertices = 0; 3519d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 3520d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 352108122e43SStefano Zampini } 352208122e43SStefano Zampini max_constraints = 0; 35239162d606SStefano Zampini total_counts_cc = 0; 352408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 352508122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 35269162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 352708122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 352808122e43SStefano Zampini } 35299162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 35309162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 35319162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 35329162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 353374d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 35349162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 35359162d606SStefano Zampini total_counts_cc = 0; 35369162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 35379162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 35389162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 353908122e43SStefano Zampini } 354008122e43SStefano Zampini } 35419162d606SStefano Zampini #if 0 35429162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 35439162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 35449162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 35459162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 35469162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 35479162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 35489162d606SStefano Zampini } 35499162d606SStefano Zampini printf("\n"); 35509162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 35519162d606SStefano Zampini } 35521b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 35538bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 35541b968477SStefano Zampini } 35551b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 35568bec7fa6SStefano 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]); 35571b968477SStefano Zampini } 355808122e43SStefano Zampini #endif 355908122e43SStefano Zampini 35608bec7fa6SStefano Zampini max_size_of_constraint = 0; 35619162d606SStefano 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]); 35629162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 356308122e43SStefano Zampini /* Change of basis */ 3564b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 356508122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 356608122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 356708122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 3568b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 356908122e43SStefano Zampini } 357008122e43SStefano Zampini } 357108122e43SStefano Zampini } 357208122e43SStefano Zampini } 3573984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 35744f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 357508122e43SStefano Zampini 35769162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 35779162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 35789162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 35799162d606SStefano 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); 358008122e43SStefano Zampini } 3581674ae819SStefano Zampini 3582674ae819SStefano Zampini /* Create constraint matrix */ 3583674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 358416f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 3585984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 3586984c4197SStefano Zampini 3587984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 3588a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 3589a717540cSStefano Zampini qr_needed = PETSC_FALSE; 359074d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 3591984c4197SStefano Zampini total_primal_vertices=0; 3592b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 35939162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 35949162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3595984c4197SStefano Zampini if (size_of_constraint == 1) { 35969162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 3597b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 359864efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 35999162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 36009162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 3601a717540cSStefano Zampini } 3602b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 360374d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 3604a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 3605a717540cSStefano Zampini qr_needed = PETSC_TRUE; 3606a717540cSStefano Zampini } 3607fa434743SStefano Zampini } else { 3608b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 3609fa434743SStefano Zampini } 3610a717540cSStefano Zampini } 3611b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 3612b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 3613674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 361470022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 3615b3d85658SStefano Zampini 36164f1b2e48SStefano 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); 36170e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 36180e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 3619984c4197SStefano Zampini 3620984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 362174d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 3622785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 3623984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 362474d5cdf7SStefano Zampini 3625984c4197SStefano Zampini j = total_primal_vertices; 362674d5cdf7SStefano Zampini total_counts = total_primal_vertices; 3627b3d85658SStefano Zampini cum = total_primal_vertices; 36289162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 36294641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 3630b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 3631b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 3632b3d85658SStefano Zampini cum++; 36339162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 363474d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 363574d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 363674d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 363774d5cdf7SStefano Zampini } 36389162d606SStefano Zampini j += constraints_n[i]; 3639674ae819SStefano Zampini } 3640674ae819SStefano Zampini } 3641674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 3642674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3643088faed8SStefano Zampini 3644674ae819SStefano Zampini /* set values in constraint matrix */ 3645984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 36460e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 3647674ae819SStefano Zampini } 3648984c4197SStefano Zampini total_counts = total_primal_vertices; 36499162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 36504641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 36519162d606SStefano Zampini PetscInt *cols; 36529162d606SStefano Zampini 36539162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 36549162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 36559162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 36569162d606SStefano Zampini PetscInt row = total_counts+k; 36579162d606SStefano Zampini PetscScalar *vals; 36589162d606SStefano Zampini 36599162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 36609162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 36619162d606SStefano Zampini } 36629162d606SStefano Zampini total_counts += constraints_n[i]; 3663674ae819SStefano Zampini } 3664674ae819SStefano Zampini } 3665674ae819SStefano Zampini /* assembling */ 3666674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3667674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3668088faed8SStefano Zampini 3669984c4197SStefano Zampini /* 367045a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3671984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 3672984c4197SStefano Zampini */ 3673674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 3674674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 3675026de310SStefano Zampini /* dual and primal dofs on a single cc */ 3676984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 3677984c4197SStefano Zampini /* working stuff for GEQRF */ 367881d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 3679984c4197SStefano Zampini PetscBLASInt lqr_work; 3680984c4197SStefano Zampini /* working stuff for UNGQR */ 3681984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 3682984c4197SStefano Zampini PetscBLASInt lgqr_work; 3683984c4197SStefano Zampini /* working stuff for TRTRS */ 3684984c4197SStefano Zampini PetscScalar *trs_rhs; 36853f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 3686984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 3687984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 3688984c4197SStefano Zampini PetscScalar *start_vals; 3689984c4197SStefano Zampini /* working stuff for values insertion */ 36904641a718SStefano Zampini PetscBT is_primal; 369164efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 3692906d46d4SStefano Zampini /* matrix sizes */ 3693906d46d4SStefano Zampini PetscInt global_size,local_size; 3694906d46d4SStefano Zampini /* temporary change of basis */ 3695906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 3696cf5a6209SStefano Zampini /* extra space for debugging */ 3697cf5a6209SStefano Zampini PetscScalar *dbg_work; 3698984c4197SStefano Zampini 3699906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 3700906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 370116f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 3702bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 3703906d46d4SStefano Zampini /* nonzeros for local mat */ 3704bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 3705bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 37069162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 3707a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 37089162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 3709a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 37109162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 3711a717540cSStefano Zampini } else { 37129162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 37139162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 3714a717540cSStefano Zampini } 3715a717540cSStefano Zampini } 3716a717540cSStefano Zampini } 3717906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 3718bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 3719a717540cSStefano Zampini /* Set initial identity in the matrix */ 3720bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 3721906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 3722a717540cSStefano Zampini } 3723a717540cSStefano Zampini 3724a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3725a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 3726a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 3727a717540cSStefano Zampini } 3728a717540cSStefano Zampini 3729a717540cSStefano Zampini 3730a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 3731a717540cSStefano Zampini /* 3732a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 3733a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 3734a717540cSStefano Zampini 3735a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 3736a717540cSStefano Zampini 3737a6b551f4SStefano 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) 3738a6b551f4SStefano Zampini 3739a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 3740a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 3741a717540cSStefano Zampini | ... | 3742a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 3743a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 3744a717540cSStefano Zampini 3745a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 3746a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 3747a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 3748a6b551f4SStefano Zampini 3749a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 3750a717540cSStefano Zampini */ 3751a717540cSStefano Zampini if (qr_needed) { 3752984c4197SStefano Zampini /* space to store Q */ 3753854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 3754984c4197SStefano Zampini /* first we issue queries for optimal work */ 37553f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 37563f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 37573f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3758984c4197SStefano Zampini lqr_work = -1; 37593f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 3760984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 3761984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 3762785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 3763984c4197SStefano Zampini lgqr_work = -1; 37643f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 37653f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 37663f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 37673f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 37683f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 37693f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 3770984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 3771984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 3772785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 3773984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 3774785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 3775984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 3776785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 3777a717540cSStefano Zampini /* allocating workspace for check */ 3778a717540cSStefano Zampini if (pcbddc->dbg_flag) { 3779cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 3780a717540cSStefano Zampini } 3781a717540cSStefano Zampini } 3782984c4197SStefano Zampini /* array to store whether a node is primal or not */ 37834641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 3784473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 37850e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 378639e2fb2aSStefano Zampini if (i != total_primal_vertices) { 378739e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 37884641a718SStefano Zampini } 378939e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 379039e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 379139e2fb2aSStefano Zampini } 379239e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 3793984c4197SStefano Zampini 3794a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 37959162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 37969162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 37974641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 3798984c4197SStefano Zampini /* get constraint info */ 37999162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 3800984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 3801984c4197SStefano Zampini 3802984c4197SStefano Zampini if (pcbddc->dbg_flag) { 38039162d606SStefano 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); 3804674ae819SStefano Zampini } 3805984c4197SStefano Zampini 3806fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 3807a717540cSStefano Zampini 3808a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 3809a717540cSStefano Zampini if (pcbddc->dbg_flag) { 38109162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3811a717540cSStefano Zampini } 3812984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 38139162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3814984c4197SStefano Zampini 3815984c4197SStefano Zampini /* compute QR decomposition of constraints */ 38163f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 38173f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 38183f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3819674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 38203f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 3821984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 3822674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3823984c4197SStefano Zampini 3824984c4197SStefano Zampini /* explictly compute R^-T */ 3825984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 3826984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 38273f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 38283f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 38293f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 38303f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 3831984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 38323f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 3833984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 3834984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3835984c4197SStefano Zampini 3836a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 38373f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 38383f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 38393f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 38403f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3841984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 38423f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 3843984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 3844984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3845984c4197SStefano Zampini 3846984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 3847984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 3848984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 38493f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 38503f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 38513f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 38523f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 38533f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 38543f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 3855984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 38569162d606SStefano 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)); 3857984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 38589162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 3859984c4197SStefano Zampini 3860984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 38619162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 3862984c4197SStefano Zampini /* insert cols for primal dofs */ 3863984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 3864984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 38659162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3866906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3867984c4197SStefano Zampini } 3868984c4197SStefano Zampini /* insert cols for dual dofs */ 3869984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 38709162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 3871984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 38729162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3873906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 3874984c4197SStefano Zampini j++; 3875674ae819SStefano Zampini } 3876674ae819SStefano Zampini } 3877984c4197SStefano Zampini 3878984c4197SStefano Zampini /* check change of basis */ 3879984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3880984c4197SStefano Zampini PetscInt ii,jj; 3881984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 3882c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 3883c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 3884c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 3885c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 3886c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 3887c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 3888984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3889cf5a6209SStefano 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)); 3890984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3891984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3892984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3893cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 3894cf5a6209SStefano 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; 3895674ae819SStefano Zampini } 3896674ae819SStefano Zampini } 3897984c4197SStefano Zampini if (!valid_qr) { 389822d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 3899984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 3900984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 3901cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 3902cf5a6209SStefano 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])); 3903674ae819SStefano Zampini } 3904cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 3905cf5a6209SStefano 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])); 3906984c4197SStefano Zampini } 3907984c4197SStefano Zampini } 3908984c4197SStefano Zampini } 3909674ae819SStefano Zampini } else { 391022d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 3911674ae819SStefano Zampini } 3912674ae819SStefano Zampini } 3913a717540cSStefano Zampini } else { /* simple transformation block */ 3914a717540cSStefano Zampini PetscInt row,col; 3915a6b551f4SStefano Zampini PetscScalar val,norm; 3916a6b551f4SStefano Zampini 3917a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 39189162d606SStefano 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)); 3919a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 39209162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 39219162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 3922bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 39239162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 3924906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 39259162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 3926a717540cSStefano Zampini } else { 3927a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 39289162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 3929a717540cSStefano Zampini if (row != col) { 39309162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 3931a717540cSStefano Zampini } else { 39329162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 3933a717540cSStefano Zampini } 3934906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 3935a717540cSStefano Zampini } 3936a717540cSStefano Zampini } 3937a717540cSStefano Zampini } 393898a51de6SStefano Zampini if (pcbddc->dbg_flag) { 393922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 3940a717540cSStefano Zampini } 3941674ae819SStefano Zampini } 3942984c4197SStefano Zampini } else { 3943984c4197SStefano Zampini if (pcbddc->dbg_flag) { 39449162d606SStefano 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); 3945674ae819SStefano Zampini } 3946674ae819SStefano Zampini } 3947674ae819SStefano Zampini } 3948a717540cSStefano Zampini 3949a717540cSStefano Zampini /* free workspace */ 3950a717540cSStefano Zampini if (qr_needed) { 3951984c4197SStefano Zampini if (pcbddc->dbg_flag) { 3952cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 3953984c4197SStefano Zampini } 3954984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 3955984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 3956984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 3957984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 3958984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 3959674ae819SStefano Zampini } 3960a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 3961906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3962906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3963906d46d4SStefano Zampini 3964906d46d4SStefano Zampini /* assembling of global change of variable */ 3965bbb9e6c6SStefano Zampini { 3966bbb9e6c6SStefano Zampini Mat tmat; 396716f15bc4SStefano Zampini PetscInt bs; 396816f15bc4SStefano Zampini 3969906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 3970906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 3971bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 3972bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 3973bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3974bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 397516f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 397616f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 3977906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 3978bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 3979bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3980bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 3981bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 3982bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 3983e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3984e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3985bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 3986bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 3987906d46d4SStefano Zampini } 3988906d46d4SStefano Zampini /* check */ 3989906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 3990906d46d4SStefano Zampini PetscReal error; 3991906d46d4SStefano Zampini Vec x,x_change; 3992906d46d4SStefano Zampini 3993906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 3994906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 3995906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 3996906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 3997e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3998e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3999bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 4000e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4001e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4002906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 4003906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4004906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4005906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4006bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 4007906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4008906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4009906d46d4SStefano Zampini } 4010b96c3477SStefano Zampini 4011b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 4012b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 4013b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4014b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 4015ac632422SStefano Zampini Mat S_new,tmat; 4016b087196eSStefano Zampini ISLocalToGlobalMapping NtoSall; 4017b087196eSStefano Zampini IS is_all_N,is_V,is_V_Sall; 4018b087196eSStefano Zampini const PetscScalar *array; 4019b087196eSStefano Zampini const PetscInt *idxs_V,*idxs_all; 4020b087196eSStefano Zampini PetscInt i,n_V; 4021bbb9e6c6SStefano Zampini 4022bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 40236816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 4024b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 4025b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 4026b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 4027b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 4028bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 4029b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 4030ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4031b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 4032ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4033b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4034b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 4035b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4036b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4037b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 4038b087196eSStefano Zampini for (i=0;i<n_V;i++) { 4039b087196eSStefano Zampini PetscScalar val; 4040b087196eSStefano Zampini PetscInt idx; 4041b087196eSStefano Zampini 4042b087196eSStefano Zampini idx = idxs_V[i]; 4043b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 4044b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 4045b087196eSStefano Zampini } 4046b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4047b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4048ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 4049ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4050ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 4051ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 4052b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 4053ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 4054b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 4055ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 4056ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 4057ac632422SStefano Zampini } 4058b087196eSStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 4059b087196eSStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 4060b087196eSStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 4061b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4062b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 4063b96c3477SStefano Zampini } 4064b96c3477SStefano Zampini } 4065906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 4066906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 4067b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4068b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 4069b9b85e73SStefano Zampini } 4070906d46d4SStefano Zampini 4071906d46d4SStefano Zampini /* set up change of basis context */ 4072906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 4073906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4074906d46d4SStefano Zampini 4075906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 4076906d46d4SStefano Zampini PetscInt global_size,local_size; 4077906d46d4SStefano Zampini 4078906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 4079906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 4080906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 4081906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 4082906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 4083906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 4084906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 4085906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 4086906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 4087906d46d4SStefano Zampini } else { 4088906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 4089906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 4090906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 4091906d46d4SStefano Zampini } 4092906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 4093906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 4094906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 4095906d46d4SStefano Zampini } else { 4096906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 4097906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 4098906d46d4SStefano Zampini } 4099906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 4100906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 4101906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4102906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4103a8661815SStefano Zampini } else { 4104a8661815SStefano Zampini ierr = MatDestroy(&pcbddc->new_global_mat);CHKERRQ(ierr); 4105b9b85e73SStefano Zampini } 4106a717540cSStefano Zampini 41074f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 41084f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 41094f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 41104f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 4111019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 4112019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 4113019a44ceSStefano Zampini pcbddc->local_primal_size++; 4114019a44ceSStefano Zampini } 4115019a44ceSStefano Zampini 4116019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 4117727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 4118727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 41199f47a83aSStefano 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); 4120c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 41210e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 41229f47a83aSStefano 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); 4123727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 4124727cdba6SStefano Zampini } 41250e6343abSStefano Zampini } 41260e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 4127727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 4128727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4129727cdba6SStefano Zampini 4130a717540cSStefano Zampini /* flush dbg viewer */ 4131b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 4132b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4133b8ffe317SStefano Zampini } 4134a717540cSStefano Zampini 4135e310c8b4SStefano Zampini /* free workspace */ 4136a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 41374641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 413808122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 41399162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 41409162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 414108122e43SStefano Zampini } else { 41429162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 41439162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 41449162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 414508122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 414608122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 41479162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 41489162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 414908122e43SStefano Zampini } 4150674ae819SStefano Zampini PetscFunctionReturn(0); 4151674ae819SStefano Zampini } 4152674ae819SStefano Zampini 4153674ae819SStefano Zampini #undef __FUNCT__ 4154674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 4155674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 4156674ae819SStefano Zampini { 4157674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4158674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4159674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 41607fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 4161674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 4162674ae819SStefano Zampini 4163674ae819SStefano Zampini PetscFunctionBegin; 41648e61c736SStefano Zampini /* Reset previously computed graph */ 41658e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 4166674ae819SStefano Zampini /* Init local Graph struct */ 41677fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 41683bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 4169674ae819SStefano Zampini 4170575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 41715099eff2SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 41725099eff2SStefano 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); 4173575ad6abSStefano Zampini } 41749577ea80SStefano Zampini 4175674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 41764d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 41774d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 41784d379d7bSStefano Zampini PetscInt nvtxs; 4179e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 4180674ae819SStefano Zampini 41814d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 41822fffb893SStefano Zampini 41832fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 41842fffb893SStefano Zampini if (flg_row) { 41854d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 4186b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 41872fffb893SStefano Zampini } 41882fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 41899b28b941SStefano Zampini } else if (pcbddc->current_level && pcis->n_B) { /* just compute subdomain's connected components for coarser levels when the local boundary is not empty */ 41904d379d7bSStefano Zampini IS is_dummy; 41914d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 41924d379d7bSStefano Zampini PetscInt j,sum; 41934d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 41944d379d7bSStefano Zampini const PetscInt *idxs; 41954d379d7bSStefano Zampini PCBDDCGraph graph; 41964d379d7bSStefano Zampini PetscBT is_on_boundary; 41974d379d7bSStefano Zampini 41984d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 41994d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 42004d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 42014d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 42027fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,pcis->n);CHKERRQ(ierr); 42034d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 4204e496cd5dSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 4205e496cd5dSStefano Zampini if (flg_row) { 42064d379d7bSStefano Zampini graph->xadj = xadj; 42074d379d7bSStefano Zampini graph->adjncy = adjncy; 4208e496cd5dSStefano Zampini } 42094d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 42104d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 4211e496cd5dSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 42124d379d7bSStefano Zampini 42134d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 42149b28b941SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains (local size %d)\n",PetscGlobalRank,graph->ncc,pcis->n);CHKERRQ(ierr); 42154d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 42164d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 42174d379d7bSStefano Zampini } 42184d379d7bSStefano Zampini } 42194d379d7bSStefano Zampini 4220e496cd5dSStefano Zampini ierr = PetscBTCreate(pcis->n,&is_on_boundary);CHKERRQ(ierr); 42214d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 42224d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 42234d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 42244d379d7bSStefano Zampini } 42254d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 42264d379d7bSStefano Zampini 4227e496cd5dSStefano Zampini ierr = PetscCalloc1(pcis->n+1,&cxadj);CHKERRQ(ierr); 42284d379d7bSStefano Zampini sum = 0; 42294d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 42304d379d7bSStefano Zampini PetscInt sizecc = 0; 42314d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 42324d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 42334d379d7bSStefano Zampini sizecc++; 42344d379d7bSStefano Zampini } 42354d379d7bSStefano Zampini } 42364d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 42374d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 42384d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 42394d379d7bSStefano Zampini } 42404d379d7bSStefano Zampini } 42414d379d7bSStefano Zampini sum += sizecc*sizecc; 42424d379d7bSStefano Zampini } 42434d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 42444d379d7bSStefano Zampini sum = 0; 4245e496cd5dSStefano Zampini for (i=0;i<pcis->n;i++) { 42464d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 42474d379d7bSStefano Zampini cxadj[i] = sum; 42484d379d7bSStefano Zampini sum += temp; 42494d379d7bSStefano Zampini } 4250e496cd5dSStefano Zampini cxadj[pcis->n] = sum; 42514d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 42524d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 42534d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 42544d379d7bSStefano Zampini PetscInt k,sizecc = 0; 42554d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 42564d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 42574d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 42584d379d7bSStefano Zampini sizecc++; 42594d379d7bSStefano Zampini } 42604d379d7bSStefano Zampini } 42614d379d7bSStefano Zampini } 42624d379d7bSStefano Zampini } 42634d379d7bSStefano Zampini } 42649b28b941SStefano Zampini if (sum) { 4265e496cd5dSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,pcis->n,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 42664d379d7bSStefano Zampini } else { 42674d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 42684d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 42694d379d7bSStefano Zampini } 42704d379d7bSStefano Zampini graph->xadj = 0; 42714d379d7bSStefano Zampini graph->adjncy = 0; 42724d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 42734d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 42744d379d7bSStefano Zampini } 4275674ae819SStefano Zampini } 42769b28b941SStefano Zampini if (pcbddc->dbg_flag) { 42779b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4278674ae819SStefano Zampini } 4279674ae819SStefano Zampini 428063602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 4281674ae819SStefano Zampini vertex_size = 1; 428263602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 428363602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 428495ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 428563602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 4286e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 428763602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 4288674ae819SStefano Zampini } 428963602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 429063602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 429163602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 4292674ae819SStefano Zampini } 429363602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 4294674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 429563602bcaSStefano Zampini } else { 429663602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 429763602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 4298854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 429963602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 430063602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 430163602bcaSStefano Zampini } 430263602bcaSStefano Zampini } 4303674ae819SStefano Zampini } 4304674ae819SStefano Zampini 4305674ae819SStefano Zampini /* Setup of Graph */ 4306785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 4307e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 4308785d1243SStefano Zampini } 4309785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 4310e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 4311785d1243SStefano Zampini } 431230368db7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { /* need to convert from global to local */ 431330368db7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 431430368db7SStefano Zampini } 431530368db7SStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 4316674ae819SStefano Zampini 43174f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 43184f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 43194f1b2e48SStefano Zampini PetscInt *local_subs; 43204f1b2e48SStefano Zampini 43214f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 43224f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 43234f1b2e48SStefano Zampini const PetscInt *idxs; 43244f1b2e48SStefano Zampini PetscInt nl,j; 43254f1b2e48SStefano Zampini 43264f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 43274f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 43284f1b2e48SStefano Zampini for (j=0;j<nl;j++) { 43294f1b2e48SStefano Zampini local_subs[idxs[j]] = i; 43304f1b2e48SStefano Zampini } 43314f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 43324f1b2e48SStefano Zampini } 43334f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 43344f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 43354f1b2e48SStefano Zampini } 43364f1b2e48SStefano Zampini 4337674ae819SStefano Zampini /* Graph's connected components analysis */ 4338674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 4339674ae819SStefano Zampini 4340674ae819SStefano Zampini /* print some info to stdout */ 4341674ae819SStefano Zampini if (pcbddc->dbg_flag) { 4342302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 4343674ae819SStefano Zampini } 4344fb180af4SStefano Zampini 4345fb180af4SStefano Zampini /* mark topography has done */ 4346fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 4347674ae819SStefano Zampini PetscFunctionReturn(0); 4348674ae819SStefano Zampini } 4349674ae819SStefano Zampini 4350dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 4351674ae819SStefano Zampini #undef __FUNCT__ 4352674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 4353dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 4354674ae819SStefano Zampini { 4355dc456d91SStefano Zampini PetscSF sf; 4356dc456d91SStefano Zampini PetscLayout map; 4357dc456d91SStefano Zampini const PetscInt *idxs; 4358dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 4359dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 4360dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 4361dc456d91SStefano Zampini PetscMPIInt commsize; 4362674ae819SStefano Zampini PetscBool first_found; 4363674ae819SStefano Zampini PetscErrorCode ierr; 4364674ae819SStefano Zampini 4365674ae819SStefano Zampini PetscFunctionBegin; 4366dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 4367dc456d91SStefano Zampini if (subset_mult) { 4368dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 4369dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 4370dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 4371674ae819SStefano Zampini } 4372dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 4373dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 4374dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 4375dc456d91SStefano Zampini for (i=0;i<n;i++) { 4376dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 4377dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 4378674ae819SStefano Zampini } 4379dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 4380dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4381dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 4382dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 4383dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 4384dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 4385dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 4386dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 4387dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 4388dc456d91SStefano Zampini 4389dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 4390dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 4391dc456d91SStefano Zampini if (subset_mult) { 4392dc456d91SStefano Zampini const PetscInt* idxs_mult; 4393dc456d91SStefano Zampini 4394dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4395dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 4396dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4397674ae819SStefano Zampini } else { 4398dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 4399674ae819SStefano Zampini } 4400dc456d91SStefano Zampini /* local size of new subset */ 4401dc456d91SStefano Zampini n_n = 0; 4402dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 4403dc456d91SStefano Zampini 4404dc456d91SStefano Zampini /* global indexes in layout */ 4405dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 4406dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 4407dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 4408dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 4409dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 4410dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 4411dc456d91SStefano Zampini 4412dc456d91SStefano Zampini /* reduce from leaves to roots */ 4413dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 441464a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 441564a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 4416dc456d91SStefano Zampini 4417dc456d91SStefano Zampini /* count indexes in local part of layout */ 4418674ae819SStefano Zampini nlocals = 0; 4419674ae819SStefano Zampini first_index = -1; 4420674ae819SStefano Zampini first_found = PETSC_FALSE; 4421dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 4422dc456d91SStefano Zampini if (!first_found && root_data[i]) { 4423674ae819SStefano Zampini first_found = PETSC_TRUE; 4424674ae819SStefano Zampini first_index = i; 4425674ae819SStefano Zampini } 4426dc456d91SStefano Zampini nlocals += root_data[i]; 4427674ae819SStefano Zampini } 4428dc456d91SStefano Zampini 4429dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 44305fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 4431dc456d91SStefano Zampini start = 0; 443264a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 44335fa240b1SStefano Zampini #else 443464a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 44355fa240b1SStefano Zampini start = start-nlocals; 44365fa240b1SStefano Zampini #endif 44375fa240b1SStefano Zampini 4438dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 4439dc456d91SStefano Zampini *N_n = start + nlocals; 4440dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 4441dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 4442674ae819SStefano Zampini } 44435fa240b1SStefano Zampini 44445fa240b1SStefano Zampini /* adapt root data with cumulative */ 4445674ae819SStefano Zampini if (first_found) { 4446dc456d91SStefano Zampini PetscInt old_index; 4447dc456d91SStefano Zampini 4448dc456d91SStefano Zampini root_data[first_index] += start; 4449674ae819SStefano Zampini old_index = first_index; 4450dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 4451dc456d91SStefano Zampini if (root_data[i]) { 4452dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 4453674ae819SStefano Zampini old_index = i; 4454674ae819SStefano Zampini } 4455674ae819SStefano Zampini } 4456674ae819SStefano Zampini } 4457dc456d91SStefano Zampini 4458dc456d91SStefano Zampini /* from roots to leaves */ 4459dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4460dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 4461dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 4462dc456d91SStefano Zampini 4463dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 4464dc456d91SStefano Zampini if (subset_mult) { 4465dc456d91SStefano Zampini const PetscInt* idxs_mult; 4466dc456d91SStefano Zampini PetscInt cum; 4467dc456d91SStefano Zampini 4468dc456d91SStefano Zampini cum = 0; 4469dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4470dc456d91SStefano Zampini for (i=0;i<n;i++) { 4471dc456d91SStefano Zampini PetscInt j; 4472dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 4473674ae819SStefano Zampini } 4474dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 4475674ae819SStefano Zampini } else { 4476dc456d91SStefano Zampini for (i=0;i<n;i++) { 4477dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 4478674ae819SStefano Zampini } 4479674ae819SStefano Zampini } 4480dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 4481dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 4482674ae819SStefano Zampini PetscFunctionReturn(0); 4483674ae819SStefano Zampini } 44849a7d3425SStefano Zampini 44859a7d3425SStefano Zampini #undef __FUNCT__ 44869a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 44879a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 44889a7d3425SStefano Zampini { 44899a7d3425SStefano Zampini PetscInt i,j; 44909a7d3425SStefano Zampini PetscScalar *alphas; 44919a7d3425SStefano Zampini PetscErrorCode ierr; 44929a7d3425SStefano Zampini 44939a7d3425SStefano Zampini PetscFunctionBegin; 44949a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 4495785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 44969a7d3425SStefano Zampini for (i=0;i<n;i++) { 44979a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 44989a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 44999a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 45009a7d3425SStefano Zampini } 45019a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 45029a7d3425SStefano Zampini PetscFunctionReturn(0); 45039a7d3425SStefano Zampini } 45049a7d3425SStefano Zampini 4505e7931f94SStefano Zampini #undef __FUNCT__ 450670cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 4507b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 4508e7931f94SStefano Zampini { 450952e5ac9dSStefano Zampini IS ranks_send_to; 4510e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 4511e7931f94SStefano Zampini PetscMPIInt size,rank,color; 451252e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 451352e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 45143837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 45152b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 4516e7931f94SStefano Zampini PetscSubcomm subcomm; 451752e5ac9dSStefano Zampini PetscErrorCode ierr; 4518a57a6d2fSStefano Zampini 4519e7931f94SStefano Zampini PetscFunctionBegin; 45202b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 45212b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 45222b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 4523e7931f94SStefano Zampini 4524e7931f94SStefano Zampini /* Get info on mapping */ 45253bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 45263bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4527e7931f94SStefano Zampini 4528e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 4529785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 4530e7931f94SStefano Zampini xadj[0] = 0; 4531e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 4532785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 4533785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 4534e7931f94SStefano Zampini 45352b510759SStefano Zampini if (threshold) { 4536d023bfaeSStefano Zampini PetscInt xadj_count = 0; 45372b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 4538d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 4539d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 4540d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 4541d023bfaeSStefano Zampini xadj_count++; 4542e7931f94SStefano Zampini } 4543e7931f94SStefano Zampini } 4544d023bfaeSStefano Zampini xadj[1] = xadj_count; 4545c8587f34SStefano Zampini } else { 4546e7931f94SStefano Zampini if (xadj[1]) { 4547e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 4548e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 4549c8587f34SStefano Zampini } 4550e7931f94SStefano Zampini } 45513bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 4552e7931f94SStefano Zampini if (use_square) { 4553e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4554e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 4555e7931f94SStefano Zampini } 4556e7931f94SStefano Zampini } 4557e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4558e7931f94SStefano Zampini 45593837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 4560e7931f94SStefano Zampini 4561e7931f94SStefano Zampini /* 4562e7931f94SStefano Zampini Restrict work on active processes only. 4563e7931f94SStefano Zampini */ 4564e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 4565e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 4566e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 45672b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 4568d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4569e7931f94SStefano Zampini if (color) { 4570e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 4571e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 4572e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4573c8587f34SStefano Zampini } else { 457452e5ac9dSStefano Zampini Mat subdomain_adj; 457552e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 457652e5ac9dSStefano Zampini MatPartitioning partitioner; 457752e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 457852e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 4579b0c7d250SStefano Zampini PetscBool aggregate; 4580b0c7d250SStefano Zampini 4581306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 4582785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 4583e7931f94SStefano Zampini prank = rank; 4584306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 45858002ef2cSStefano Zampini /* 4586e7931f94SStefano Zampini for (i=0;i<size;i++) { 4587e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 4588c8587f34SStefano Zampini } 45898002ef2cSStefano Zampini */ 4590e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 4591e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 4592c8587f34SStefano Zampini } 4593e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 4594b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 4595b0c7d250SStefano Zampini if (aggregate) { 4596b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 4597b0c7d250SStefano Zampini PetscMPIInt nrank; 4598b0c7d250SStefano Zampini PetscScalar *vals; 4599b0c7d250SStefano Zampini 4600b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 4601b0c7d250SStefano Zampini lrows = 0; 4602b0c7d250SStefano Zampini if (nrank<redprocs) { 4603b0c7d250SStefano Zampini lrows = size/redprocs; 4604b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 4605b0c7d250SStefano Zampini } 46065fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 4607b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 4608b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4609b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 4610b0c7d250SStefano Zampini row = nrank; 4611b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 4612b0c7d250SStefano Zampini cols = adjncy; 4613b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 4614b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 4615b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 4616b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4617b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 461852e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 461952e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 462052e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 4621b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4622b0c7d250SStefano Zampini } else { 4623306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 4624b0c7d250SStefano Zampini } 462522b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 4626e7931f94SStefano Zampini 4627e7931f94SStefano Zampini /* Partition */ 4628306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 4629e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 4630e7931f94SStefano Zampini if (use_vwgt) { 46313837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 4632e7931f94SStefano Zampini v_wgt[0] = local_size; 4633e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 4634c8587f34SStefano Zampini } 463528143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 463628143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 4637e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 4638e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 463922b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 4640e7931f94SStefano Zampini 464152e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 464252e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 464352e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 464452e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4645b0c7d250SStefano Zampini if (!redprocs) { 4646b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 464728143c3dSStefano Zampini } else { 4648b0c7d250SStefano Zampini PetscInt idxs[1]; 4649b0c7d250SStefano Zampini PetscMPIInt tag; 4650b0c7d250SStefano Zampini MPI_Request *reqs; 4651b0c7d250SStefano Zampini 4652b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 4653b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 4654b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 4655b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 465628143c3dSStefano Zampini } 4657b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 4658b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4659b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 4660b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 4661e7931f94SStefano Zampini } 466252e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4663e7931f94SStefano Zampini /* clean up */ 4664e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 466552e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 4666e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 4667e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 4668e7931f94SStefano Zampini } 4669e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 4670e7931f94SStefano Zampini 4671e7931f94SStefano Zampini /* assemble parallel IS for sends */ 4672e7931f94SStefano Zampini i = 1; 4673e7931f94SStefano Zampini if (color) i=0; 4674e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 4675e7931f94SStefano Zampini /* get back IS */ 4676e7931f94SStefano Zampini *is_sends = ranks_send_to; 4677e7931f94SStefano Zampini PetscFunctionReturn(0); 4678e7931f94SStefano Zampini } 4679e7931f94SStefano Zampini 4680e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 4681e7931f94SStefano Zampini 4682e7931f94SStefano Zampini #undef __FUNCT__ 4683e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 468453a05cb3SStefano 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[]) 4685e7931f94SStefano Zampini { 468670cf5478SStefano Zampini Mat local_mat; 4687e7931f94SStefano Zampini IS is_sends_internal; 46889d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 468928143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 46909d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 4691e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 4692e7931f94SStefano Zampini PetscInt* l2gmap_indices; 4693e7931f94SStefano Zampini const PetscInt* is_indices; 4694e7931f94SStefano Zampini MatType new_local_type; 4695e7931f94SStefano Zampini /* buffers */ 4696e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 469728143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 46989d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 4699e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 4700e7931f94SStefano Zampini /* MPI */ 470128143c3dSStefano Zampini MPI_Comm comm,comm_n; 470228143c3dSStefano Zampini PetscSubcomm subcomm; 4703e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 470428143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 470528143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 470628143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 470728143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 470828143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 4709e7931f94SStefano Zampini PetscErrorCode ierr; 4710e7931f94SStefano Zampini 4711e7931f94SStefano Zampini PetscFunctionBegin; 471228143c3dSStefano Zampini /* TODO: add missing checks */ 471328143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 471428143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 471528143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 471628143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 4717e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 471828143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 4719e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4720e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 4721e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 4722e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 4723e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 472428143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 472570cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 472670cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 472728143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 472870cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 472970cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 473070cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 473170cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 473270cf5478SStefano Zampini } 4733e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 4734e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 4735e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 4736e7931f94SStefano Zampini if (!is_sends) { 473728143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 4738b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 4739c8587f34SStefano Zampini } else { 4740e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 4741e7931f94SStefano Zampini is_sends_internal = is_sends; 4742c8587f34SStefano Zampini } 4743e7931f94SStefano Zampini 4744e7931f94SStefano Zampini /* get comm */ 4745a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 4746e7931f94SStefano Zampini 4747e7931f94SStefano Zampini /* compute number of sends */ 4748e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 4749e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 4750e7931f94SStefano Zampini 4751e7931f94SStefano Zampini /* compute number of receives */ 4752e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 4753785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 4754e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 4755e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4756e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 4757e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 4758e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 4759e7931f94SStefano Zampini 476028143c3dSStefano Zampini /* restrict comm if requested */ 476128143c3dSStefano Zampini subcomm = 0; 476228143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 476328143c3dSStefano Zampini if (restrict_comm) { 4764779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 4765779c1cceSStefano Zampini 476628143c3dSStefano Zampini color = 0; 476753a05cb3SStefano Zampini if (restrict_full) { 476853a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 476953a05cb3SStefano Zampini } else { 477053a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 477153a05cb3SStefano Zampini } 477228143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 477328143c3dSStefano Zampini subcommsize = commsize - subcommsize; 477428143c3dSStefano Zampini /* check if reuse has been requested */ 477528143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 477628143c3dSStefano Zampini if (*mat_n) { 477728143c3dSStefano Zampini PetscMPIInt subcommsize2; 477828143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 477928143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 478028143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 478128143c3dSStefano Zampini } else { 478228143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 478328143c3dSStefano Zampini } 478428143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 4785779c1cceSStefano Zampini PetscMPIInt rank; 4786779c1cceSStefano Zampini 4787779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 478828143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 478928143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 479028143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 4791306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 479228143c3dSStefano Zampini } 479328143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 479428143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 479528143c3dSStefano Zampini } else { 479628143c3dSStefano Zampini comm_n = comm; 479728143c3dSStefano Zampini } 479828143c3dSStefano Zampini 4799e7931f94SStefano Zampini /* prepare send/receive buffers */ 4800785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 4801e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 4802785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 4803e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 480428143c3dSStefano Zampini if (nis) { 4805854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 480628143c3dSStefano Zampini } 4807e7931f94SStefano Zampini 480828143c3dSStefano Zampini /* Get data from local matrices */ 4809e7931f94SStefano Zampini if (!isdense) { 4810a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 4811e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 4812e7931f94SStefano Zampini /* 4813e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 4814e7931f94SStefano Zampini send_buffer_idxs should contain: 4815e7931f94SStefano Zampini - MatType_PRIVATE type 4816e7931f94SStefano Zampini - PetscInt size_of_l2gmap 4817e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 4818e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 4819e7931f94SStefano Zampini */ 4820e7931f94SStefano Zampini } else { 4821e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 48223bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 4823854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 4824e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 4825e7931f94SStefano Zampini send_buffer_idxs[1] = i; 48263bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4827e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 48283bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 4829e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 4830e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4831e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 4832e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 4833c8587f34SStefano Zampini } 4834c8587f34SStefano Zampini } 4835e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 483628143c3dSStefano Zampini /* additional is (if any) */ 483728143c3dSStefano Zampini if (nis) { 483828143c3dSStefano Zampini PetscMPIInt psum; 483928143c3dSStefano Zampini PetscInt j; 484028143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 484128143c3dSStefano Zampini PetscInt plen; 484228143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 484328143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 484428143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 484528143c3dSStefano Zampini } 4846854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 484728143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 484828143c3dSStefano Zampini PetscInt plen; 484928143c3dSStefano Zampini const PetscInt *is_array_idxs; 485028143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 485128143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 485228143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 485328143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 485428143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 485528143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 485628143c3dSStefano Zampini } 485728143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 485828143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 485928143c3dSStefano Zampini } 486028143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 486128143c3dSStefano Zampini } 486228143c3dSStefano Zampini 4863e7931f94SStefano Zampini buf_size_idxs = 0; 4864e7931f94SStefano Zampini buf_size_vals = 0; 486528143c3dSStefano Zampini buf_size_idxs_is = 0; 4866e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4867e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 4868e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 486928143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 4870e7931f94SStefano Zampini } 4871785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 4872785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 487395ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 4874e7931f94SStefano Zampini 4875e7931f94SStefano Zampini /* get new tags for clean communications */ 4876e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 4877e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 487828143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 4879e7931f94SStefano Zampini 4880e7931f94SStefano Zampini /* allocate for requests */ 4881785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 4882785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 488395ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 4884785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 4885785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 488695ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 4887e7931f94SStefano Zampini 4888e7931f94SStefano Zampini /* communications */ 4889e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4890e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 489128143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 4892e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4893e7931f94SStefano Zampini source_dest = onodes[i]; 4894e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 4895e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 4896e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4897e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 489828143c3dSStefano Zampini if (nis) { 489928143c3dSStefano 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); 490028143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 490128143c3dSStefano Zampini } 4902e7931f94SStefano Zampini } 4903e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 4904e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 4905e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 4906e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 490728143c3dSStefano Zampini if (nis) { 490828143c3dSStefano 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); 490928143c3dSStefano Zampini } 4910e7931f94SStefano Zampini } 4911e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 4912e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 4913e7931f94SStefano Zampini 4914e7931f94SStefano Zampini /* assemble new l2g map */ 4915e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4916e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 49179d30be91SStefano Zampini new_local_rows = 0; 4918e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 49199d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4920e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4921e7931f94SStefano Zampini } 49229d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 4923e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 49249d30be91SStefano Zampini new_local_rows = 0; 4925e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 49269d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 49279d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 4928e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4929e7931f94SStefano Zampini } 49309d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 49319d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 4932e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 4933e7931f94SStefano Zampini 4934e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 4935e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 4936e7931f94SStefano 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) */ 4937e7931f94SStefano Zampini if (n_recvs) { 493828143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 4939e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 4940e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 4941e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 4942e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 4943e7931f94SStefano Zampini break; 4944e7931f94SStefano Zampini } 4945e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 4946e7931f94SStefano Zampini } 4947e7931f94SStefano Zampini switch (new_local_type_private) { 494828143c3dSStefano Zampini case MATDENSE_PRIVATE: 494928143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 4950e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4951e7931f94SStefano Zampini bs = 1; 495228143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 495328143c3dSStefano Zampini new_local_type = MATSEQDENSE; 495428143c3dSStefano Zampini bs = 1; 495528143c3dSStefano Zampini } 4956e7931f94SStefano Zampini break; 4957e7931f94SStefano Zampini case MATAIJ_PRIVATE: 4958e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 4959e7931f94SStefano Zampini bs = 1; 4960e7931f94SStefano Zampini break; 4961e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 4962e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 4963e7931f94SStefano Zampini break; 4964e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 4965e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 4966e7931f94SStefano Zampini break; 4967e7931f94SStefano Zampini default: 49689d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 4969e7931f94SStefano Zampini break; 4970e7931f94SStefano Zampini } 497128143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 497228143c3dSStefano Zampini new_local_type = MATSEQDENSE; 497328143c3dSStefano Zampini bs = 1; 4974e7931f94SStefano Zampini } 4975e7931f94SStefano Zampini 497670cf5478SStefano Zampini /* create MATIS object if needed */ 497770cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 4978e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 4979e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 498070cf5478SStefano Zampini } else { 498170cf5478SStefano Zampini /* it also destroys the local matrices */ 498270cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 498370cf5478SStefano Zampini } 498470cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 4985e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 49869d30be91SStefano Zampini 49879d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 49889d30be91SStefano Zampini 49899d30be91SStefano Zampini /* Global to local map of received indices */ 49909d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 49919d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 49929d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 49939d30be91SStefano Zampini 49949d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 49959d30be91SStefano Zampini buf_size_idxs = 0; 49969d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 49979d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 49989d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 49999d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 50009d30be91SStefano Zampini } 50019d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 50029d30be91SStefano Zampini 50039d30be91SStefano Zampini /* set preallocation */ 50049d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 50059d30be91SStefano Zampini if (!newisdense) { 50069d30be91SStefano Zampini PetscInt *new_local_nnz=0; 50079d30be91SStefano Zampini 50089d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 50099d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 50109d30be91SStefano Zampini if (n_recvs) { 50119d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 50129d30be91SStefano Zampini } 50139d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 50149d30be91SStefano Zampini PetscInt j; 50159d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 50169d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 50179d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 50189d30be91SStefano Zampini } 50199d30be91SStefano Zampini } else { 50209d30be91SStefano Zampini /* TODO */ 50219d30be91SStefano Zampini } 50229d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 50239d30be91SStefano Zampini } 50249d30be91SStefano Zampini if (new_local_nnz) { 50259d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 50269d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 50279d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 50289d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 50299d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 50309d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 50319d30be91SStefano Zampini } else { 50329d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 50339d30be91SStefano Zampini } 50349d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 50359d30be91SStefano Zampini } else { 50369d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 50379d30be91SStefano Zampini } 5038e7931f94SStefano Zampini 5039e7931f94SStefano Zampini /* set values */ 5040e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 50419d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 5042e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 5043e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 5044e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 50459d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 5046e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5047e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 5048e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 504928143c3dSStefano Zampini } else { 505028143c3dSStefano Zampini /* TODO */ 5051e7931f94SStefano Zampini } 5052e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 5053e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 5054e7931f94SStefano Zampini } 5055e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5056e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 505770cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 505870cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 50599d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 50609d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 5061e7931f94SStefano Zampini 5062dfd14d43SStefano Zampini #if 0 506328143c3dSStefano Zampini if (!restrict_comm) { /* check */ 5064e7931f94SStefano Zampini Vec lvec,rvec; 5065e7931f94SStefano Zampini PetscReal infty_error; 5066e7931f94SStefano Zampini 50672a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 5068e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 5069e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 5070e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 507170cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 5072e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 5073e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 5074e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 5075e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 5076e7931f94SStefano Zampini } 507728143c3dSStefano Zampini #endif 5078e7931f94SStefano Zampini 507928143c3dSStefano Zampini /* assemble new additional is (if any) */ 508028143c3dSStefano Zampini if (nis) { 508128143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 508228143c3dSStefano Zampini 508328143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5084854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 508528143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 508628143c3dSStefano Zampini psum = 0; 508728143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 508828143c3dSStefano Zampini for (j=0;j<nis;j++) { 508928143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 509028143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 509128143c3dSStefano Zampini psum += plen; 509228143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 509328143c3dSStefano Zampini } 509428143c3dSStefano Zampini } 5095854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 5096854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 509728143c3dSStefano Zampini for (i=1;i<nis;i++) { 509828143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 509928143c3dSStefano Zampini } 510028143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 510128143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 510228143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 510328143c3dSStefano Zampini for (j=0;j<nis;j++) { 510428143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 510528143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 510628143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 510728143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 510828143c3dSStefano Zampini } 510928143c3dSStefano Zampini } 511028143c3dSStefano Zampini for (i=0;i<nis;i++) { 511128143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 511228143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 511328143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 511428143c3dSStefano Zampini } 511528143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 511628143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 511728143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 511828143c3dSStefano Zampini } 5119e7931f94SStefano Zampini /* free workspace */ 512028143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 5121e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5122e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 5123e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 5124e7931f94SStefano Zampini if (isdense) { 5125e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 5126e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 5127e7931f94SStefano Zampini } else { 5128e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 5129e7931f94SStefano Zampini } 513028143c3dSStefano Zampini if (nis) { 513128143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 513228143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 513328143c3dSStefano Zampini } 5134e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 5135e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 513628143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 5137e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 5138e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 513928143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 5140e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 5141e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 5142e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 5143e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 5144e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 514528143c3dSStefano Zampini if (nis) { 514628143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 514728143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 514828143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 514928143c3dSStefano Zampini } 515028143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 515128143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 515228143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 515328143c3dSStefano Zampini for (i=0;i<nis;i++) { 515428143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 515528143c3dSStefano Zampini } 515653a05cb3SStefano Zampini *mat_n = NULL; 515728143c3dSStefano Zampini } 5158e7931f94SStefano Zampini PetscFunctionReturn(0); 5159e7931f94SStefano Zampini } 5160a57a6d2fSStefano Zampini 516112edc857SStefano Zampini /* temporary hack into ksp private data structure */ 5162af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 516312edc857SStefano Zampini 5164c8587f34SStefano Zampini #undef __FUNCT__ 5165c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 5166c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 5167c8587f34SStefano Zampini { 5168c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5169c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 517020a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 51719881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 517220a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 51736e683305SStefano Zampini IS coarse_is,*isarray; 51746e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 517530368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 5176f9eb5b7dSStefano Zampini PC pc_temp; 5177c8587f34SStefano Zampini PCType coarse_pc_type; 5178c8587f34SStefano Zampini KSPType coarse_ksp_type; 5179f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 51804f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 51816e683305SStefano Zampini Mat t_coarse_mat_is; 51826e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 51836e683305SStefano Zampini PetscMPIInt all_procs; 518474e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 518568457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 518622bc73bbSStefano Zampini PetscScalar *array; 51879881197aSStefano Zampini PetscErrorCode ierr; 5188fdc09c96SStefano Zampini 5189c8587f34SStefano Zampini PetscFunctionBegin; 5190c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 519168457ee5SStefano 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 */ 5192fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 51935a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 5194fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 5195f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 5196f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 5197f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 5198fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 519951bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 520051bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 5201dc4bcba2SStefano Zampini PC pc; 5202dc4bcba2SStefano Zampini PetscBool isbddc; 5203dc4bcba2SStefano Zampini 5204dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 5205dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 5206dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 5207dc4bcba2SStefano Zampini if (isbddc) { 5208dc4bcba2SStefano Zampini ierr = PCDestroy(&pc);CHKERRQ(ierr); 5209dc4bcba2SStefano Zampini } 5210727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 5211fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5212fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 5213fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5214f4ddd8eeSStefano Zampini } 5215fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 5216fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 5217f4ddd8eeSStefano Zampini } 521870cf5478SStefano Zampini /* reset any subassembling information */ 521970cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 52206e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 52216e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 5222fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 5223f4ddd8eeSStefano Zampini } 5224c8587f34SStefano Zampini 52256e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 52262b510759SStefano Zampini im_active = !!(pcis->n); 52272b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 52286e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 52296e683305SStefano Zampini void_procs = all_procs-active_procs; 52306e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 523174e2c79eSStefano Zampini redist = PETSC_FALSE; 523222bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 52336e683305SStefano Zampini csin_ml = PETSC_TRUE; 52346e683305SStefano Zampini ncoarse_ml = void_procs; 5235779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 5236779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 52376e683305SStefano Zampini csin_ds = PETSC_TRUE; 523818a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 523918a45a71SStefano Zampini redist = PETSC_TRUE; 524018a45a71SStefano Zampini } else { 52416e683305SStefano Zampini csin_ds = PETSC_TRUE; 5242779c1cceSStefano Zampini ncoarse_ds = active_procs; 5243779c1cceSStefano Zampini redist = PETSC_TRUE; 524418a45a71SStefano Zampini } 52456e683305SStefano Zampini } else { 52466e683305SStefano Zampini csin_ml = PETSC_FALSE; 52476e683305SStefano Zampini ncoarse_ml = all_procs; 52486e683305SStefano Zampini if (void_procs) { 52496e683305SStefano Zampini csin_ds = PETSC_TRUE; 52506e683305SStefano Zampini ncoarse_ds = void_procs; 52516e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 52526e683305SStefano Zampini } else { 5253779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 525474e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 525574e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 525674e2c79eSStefano Zampini redist = PETSC_TRUE; 525774e2c79eSStefano Zampini } else { 52586e683305SStefano Zampini csin_ds = PETSC_FALSE; 52596e683305SStefano Zampini ncoarse_ds = all_procs; 52606e683305SStefano Zampini } 52616e683305SStefano Zampini } 526274e2c79eSStefano Zampini } 52636e683305SStefano Zampini 52646e683305SStefano Zampini /* 52656e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 52666e683305SStefano Zampini - we have not exceeded the number of levels requested 52676e683305SStefano Zampini - we can actually subassemble the active processes 52686e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 52696e683305SStefano Zampini */ 52706e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 52716e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 52726e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 52736e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 52746e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 5275f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 52762b510759SStefano Zampini } else { 5277f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 5278c8587f34SStefano Zampini } 5279c8587f34SStefano Zampini } 52806e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 52816e683305SStefano Zampini if (multilevel_allowed) { 52826e683305SStefano Zampini ncoarse = ncoarse_ml; 52836e683305SStefano Zampini csin = csin_ml; 528458da7f69SStefano Zampini redist = PETSC_FALSE; 52856e683305SStefano Zampini } else { 52866e683305SStefano Zampini ncoarse = ncoarse_ds; 52876e683305SStefano Zampini csin = csin_ds; 52886e683305SStefano Zampini } 5289e7931f94SStefano Zampini 5290abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 5291abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 5292abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 5293abbbba34SStefano Zampini 5294abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 529522bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 529622bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 529722bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 529822bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 5299e176bc59SStefano 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); 53006e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 53016e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 53026e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5303abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 5304abbbba34SStefano Zampini 53056e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 530630368db7SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local))) { /* protects from unneded computations */ 53076e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 53086e683305SStefano Zampini const PetscInt *idxs; 53096e683305SStefano Zampini ISLocalToGlobalMapping tmap; 53106e683305SStefano Zampini 53116e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 53120be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 53136e683305SStefano Zampini /* allocate space for temporary storage */ 5314854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 5315854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 53166e683305SStefano Zampini /* allocate for IS array */ 53176e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 53186e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 531930368db7SStefano Zampini nisvert = 0; 532030368db7SStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local) { 532130368db7SStefano Zampini nisvert = 1; 532230368db7SStefano Zampini } 532330368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 5324854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 53256e683305SStefano Zampini /* dofs splitting */ 53266e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 53276e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 53286e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 53296e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 53306e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 53316e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 53326e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 533330368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 53346e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 53356e683305SStefano Zampini } 53366e683305SStefano Zampini /* neumann boundaries */ 53376e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 53386e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 53396e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 53406e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 53416e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 53426e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 53436e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 534430368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 53456e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 53466e683305SStefano Zampini } 534730368db7SStefano Zampini /* primal vertices (benign) */ 534830368db7SStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->user_primal_vertices_local) { 534930368db7SStefano Zampini ierr = ISGetLocalSize(pcbddc->user_primal_vertices_local,&tsize);CHKERRQ(ierr); 535030368db7SStefano Zampini ierr = ISGetIndices(pcbddc->user_primal_vertices_local,&idxs);CHKERRQ(ierr); 535130368db7SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 535230368db7SStefano Zampini ierr = ISRestoreIndices(pcbddc->user_primal_vertices_local,&idxs);CHKERRQ(ierr); 535330368db7SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 535430368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nis-1]);CHKERRQ(ierr); 535530368db7SStefano Zampini } 53566e683305SStefano Zampini /* free memory */ 53576e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 53586e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 53596e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 53606e683305SStefano Zampini } else { 53616e683305SStefano Zampini nis = 0; 53626e683305SStefano Zampini nisdofs = 0; 53636e683305SStefano Zampini nisneu = 0; 536430368db7SStefano Zampini nisvert = 0; 53656e683305SStefano Zampini isarray = NULL; 53666e683305SStefano Zampini } 53676e683305SStefano Zampini /* destroy no longer needed map */ 53686e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 53696e683305SStefano Zampini 53706e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 53716e683305SStefano Zampini coarse_mat_is = NULL; 53726e683305SStefano Zampini if (csin) { 53736e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 537474e2c79eSStefano Zampini if (redist) { 537574e2c79eSStefano Zampini PetscMPIInt rank; 5376779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 537774e2c79eSStefano Zampini 537874e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 537958da7f69SStefano Zampini spc = active_procs/ncoarse; 538058da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 5381779c1cceSStefano Zampini if (im_active) { 5382779c1cceSStefano Zampini destsize = 1; 538374e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 538474e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 538574e2c79eSStefano Zampini } else { 538674e2c79eSStefano Zampini dest[0] = rank/(spc+1); 538774e2c79eSStefano Zampini } 538874e2c79eSStefano Zampini } else { 5389779c1cceSStefano Zampini destsize = 0; 53906e683305SStefano Zampini } 5391779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 5392779c1cceSStefano Zampini } else if (csin_type_simple) { 53936e683305SStefano Zampini PetscMPIInt rank; 53946e683305SStefano Zampini PetscInt issize,isidx; 5395779c1cceSStefano Zampini 53966e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 53976e683305SStefano Zampini if (im_active) { 53986e683305SStefano Zampini issize = 1; 53996e683305SStefano Zampini isidx = (PetscInt)rank; 54006e683305SStefano Zampini } else { 54016e683305SStefano Zampini issize = 0; 54026e683305SStefano Zampini isidx = -1; 54036e683305SStefano Zampini } 54046e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 5405779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 5406b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 54076e683305SStefano Zampini } 5408779c1cceSStefano Zampini 5409779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 5410779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 5411779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 5412779c1cceSStefano Zampini PetscInt *coarse_candidates; 5413779c1cceSStefano Zampini const PetscInt* tisindices; 5414779c1cceSStefano Zampini 5415779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 5416779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 5417779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5418779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 5419779c1cceSStefano Zampini if (!coarse_candidates[i]) { 5420779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 5421779c1cceSStefano Zampini } 5422779c1cceSStefano Zampini } 5423779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 5424779c1cceSStefano Zampini 5425779c1cceSStefano Zampini 54266e683305SStefano Zampini if (pcbddc->dbg_flag) { 54276e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54286e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 54296e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 54306e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 5431779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 54326e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 54336e683305SStefano Zampini } 54346e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 54356e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54366e683305SStefano Zampini } 54376e683305SStefano Zampini /* shift the pattern on coarse candidates */ 54386e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 54396e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 5440854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 54416e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 54426e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 54436e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 54446e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 54456e683305SStefano Zampini } 54466e683305SStefano Zampini if (pcbddc->dbg_flag) { 54476e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54486e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 54496e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 54506e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54516e683305SStefano Zampini } 5452779c1cceSStefano Zampini } 54536e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 545453a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 545553a05cb3SStefano 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); 545653a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 545753a05cb3SStefano 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); 545853a05cb3SStefano Zampini } 54596e683305SStefano Zampini } else { 54606e683305SStefano Zampini if (pcbddc->dbg_flag) { 54616e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 54626e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 54636e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54646e683305SStefano Zampini } 54656e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 54666e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 54676e683305SStefano Zampini } 54686e683305SStefano Zampini 54696e683305SStefano Zampini /* create local to global scatters for coarse problem */ 547068457ee5SStefano Zampini if (compute_vecs) { 54716e683305SStefano Zampini PetscInt lrows; 54726e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 54736e683305SStefano Zampini if (coarse_mat_is) { 54746e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 54756e683305SStefano Zampini } else { 54766e683305SStefano Zampini lrows = 0; 54776e683305SStefano Zampini } 54786e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 54796e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 54806e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 54816e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 54826e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 54836e683305SStefano Zampini } 54846e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 54856e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 5486c8587f34SStefano Zampini 5487f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 5488f9eb5b7dSStefano Zampini if (multilevel_allowed) { 5489f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 5490f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 5491f9eb5b7dSStefano Zampini } else { 5492f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 5493f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 5494c8587f34SStefano Zampini } 5495c8587f34SStefano Zampini 54966e683305SStefano Zampini /* print some info if requested */ 54976e683305SStefano Zampini if (pcbddc->dbg_flag) { 54986e683305SStefano Zampini if (!multilevel_allowed) { 54996e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 55006e683305SStefano Zampini if (multilevel_requested) { 55016e683305SStefano 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); 55026e683305SStefano Zampini } else if (pcbddc->max_levels) { 55036e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 55046e683305SStefano Zampini } 55056e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 55066e683305SStefano Zampini } 55076e683305SStefano Zampini } 55086e683305SStefano Zampini 5509f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 55106e683305SStefano Zampini if (coarse_mat_is) { 55116e683305SStefano Zampini MatReuse coarse_mat_reuse; 55126a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 55136e683305SStefano Zampini if (pcbddc->dbg_flag) { 55146e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 55156e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 55166e683305SStefano Zampini } 5517f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 5518312be037SStefano Zampini char prefix[256],str_level[16]; 5519e604994aSStefano Zampini size_t len; 55206e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 5521422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 5522c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5523f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 55245f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 5525c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 55266e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 5527c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 5528c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5529e604994aSStefano Zampini /* prefix */ 5530e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 5531e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 5532e604994aSStefano Zampini if (!pcbddc->current_level) { 5533e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5534e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 5535c8587f34SStefano Zampini } else { 5536e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5537312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5538312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 553934d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5540312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 5541e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 5542e604994aSStefano Zampini } 5543e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 55443e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 55453e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 55463e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 55473e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 5548f9eb5b7dSStefano Zampini /* allow user customization */ 5549f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 55503e3c6dadSStefano Zampini } 55513e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 555251bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 55533e3c6dadSStefano Zampini if (nisdofs) { 55543e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 55553e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 55563e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 55573e3c6dadSStefano Zampini } 55583e3c6dadSStefano Zampini } 55593e3c6dadSStefano Zampini if (nisneu) { 55603e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 55613e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 5562312be037SStefano Zampini } 556330368db7SStefano Zampini if (nisvert) { 556430368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 556530368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 556630368db7SStefano Zampini } 5567f9eb5b7dSStefano Zampini 5568f9eb5b7dSStefano Zampini /* get some info after set from options */ 5569f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 5570f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 55714f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 55726e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 5573f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 5574f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 5575f9eb5b7dSStefano Zampini } 557639f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 55774f3a063dSStefano Zampini if (isredundant) { 55784f3a063dSStefano Zampini KSP inner_ksp; 55794f3a063dSStefano Zampini PC inner_pc; 55804f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 55814f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 55824f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 55834f3a063dSStefano Zampini } 5584f9eb5b7dSStefano Zampini 5585f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 5586fa7f1dd8SStefano Zampini if (coarse_reuse) { 558781d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 5588fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 55896e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 5590fa7f1dd8SStefano Zampini } else { 55916e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 5592fa7f1dd8SStefano Zampini } 5593c8587f34SStefano Zampini if (isbddc || isnn) { 559422bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 559570cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 5596b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 559722b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 55986e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 55996e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 56006e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 56016e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 560222b6e8a2SStefano Zampini } 560370cf5478SStefano Zampini } 560453a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 560570cf5478SStefano Zampini } else { 560622bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 560722bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 560822bc73bbSStefano Zampini } 560922bc73bbSStefano Zampini } else { 56102e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 5611c8587f34SStefano Zampini } 5612c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 5613c8587f34SStefano Zampini 56143301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 56155a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 56163301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 56173301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 56183301b35fSStefano Zampini } 56193301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 56203301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 56213301b35fSStefano Zampini } 56223301b35fSStefano Zampini if (pc->pmat->spd_set) { 56233301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 56243301b35fSStefano Zampini } 56256e683305SStefano Zampini /* set operators */ 56265f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 56276e683305SStefano Zampini if (pcbddc->dbg_flag) { 56286e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 56296e683305SStefano Zampini } 56306e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 56316e683305SStefano Zampini coarse_mat = 0; 56326e683305SStefano Zampini } 56336e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 5634b1ecc7b1SStefano Zampini #if 0 5635b9b85e73SStefano Zampini { 5636b9b85e73SStefano Zampini PetscViewer viewer; 5637b9b85e73SStefano Zampini char filename[256]; 5638b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 5639b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 5640b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5641b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 5642b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 5643b9b85e73SStefano Zampini } 5644b9b85e73SStefano Zampini #endif 5645c8587f34SStefano Zampini 5646c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 5647298c0119SStefano Zampini #if 0 5648c8587f34SStefano Zampini if (pcbddc->NullSpace) { 5649c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 565098a51de6SStefano Zampini } 5651298c0119SStefano Zampini #endif 5652b0f5fe93SStefano Zampini /* hack */ 565398a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 565498a51de6SStefano Zampini Vec crhs,csol; 565504708bb6SStefano Zampini 5656f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 5657f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 5658f347579bSStefano Zampini if (!csol) { 56592a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 5660f9eb5b7dSStefano Zampini } 5661f347579bSStefano Zampini if (!crhs) { 56622a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 5663f347579bSStefano Zampini } 5664b0f5fe93SStefano Zampini } 5665b0f5fe93SStefano Zampini 5666b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 5667b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 5668b0f5fe93SStefano Zampini 5669b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 56704f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 56714f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 56724f1b2e48SStefano Zampini } 5673b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 5674b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 5675b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5676b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5677b0f5fe93SStefano Zampini if (coarse_mat) { 5678b0f5fe93SStefano Zampini Vec nullv; 5679b0f5fe93SStefano Zampini PetscScalar *array,*array2; 5680b0f5fe93SStefano Zampini PetscInt nl; 5681b0f5fe93SStefano Zampini 5682b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 5683b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 5684b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5685b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 5686b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 5687b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 5688b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 5689b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 5690b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 5691b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 5692b0f5fe93SStefano Zampini } 5693b0f5fe93SStefano Zampini } 5694b0f5fe93SStefano Zampini 5695b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 5696b0f5fe93SStefano Zampini PetscBool ispreonly; 5697b0f5fe93SStefano Zampini 5698b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5699b0f5fe93SStefano Zampini PetscBool isnull; 5700b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 5701b0f5fe93SStefano Zampini if (isnull) { 570230368db7SStefano Zampini if (isbddc && !pcbddc->benign_saddle_point) { 5703b0f5fe93SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 5704b0f5fe93SStefano Zampini } else { 5705b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 5706b0f5fe93SStefano Zampini } 5707b0f5fe93SStefano Zampini } else { 5708b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5709b0f5fe93SStefano Zampini } 5710b0f5fe93SStefano Zampini } 5711b0f5fe93SStefano Zampini /* setup coarse ksp */ 5712b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 5713cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 5714cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 57156e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 5716c8587f34SStefano Zampini KSP check_ksp; 57172b510759SStefano Zampini KSPType check_ksp_type; 5718c8587f34SStefano Zampini PC check_pc; 57196e683305SStefano Zampini Vec check_vec,coarse_vec; 57206a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 57212b510759SStefano Zampini PetscInt its; 57226e683305SStefano Zampini PetscBool compute_eigs; 57236e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 57246e683305SStefano Zampini PetscInt neigs; 57258e185a42SStefano Zampini const char *prefix; 5726c8587f34SStefano Zampini 57272b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 57286e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 5729422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 573023ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 5731f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 57322b510759SStefano Zampini if (ispreonly) { 57332b510759SStefano Zampini check_ksp_type = KSPPREONLY; 57346e683305SStefano Zampini compute_eigs = PETSC_FALSE; 57352b510759SStefano Zampini } else { 5736cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 57376e683305SStefano Zampini compute_eigs = PETSC_TRUE; 5738c8587f34SStefano Zampini } 5739c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 57406e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 57416e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 57426e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 5743a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 5744a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 5745a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 5746a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 5747c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 5748c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 5749c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 5750c8587f34SStefano Zampini /* create random vec */ 57516e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 57526e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 5753c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 5754c8587f34SStefano Zampini if (CoarseNullSpace) { 5755c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 5756c8587f34SStefano Zampini } 57576e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 5758c8587f34SStefano Zampini /* solve coarse problem */ 57596e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 5760c8587f34SStefano Zampini if (CoarseNullSpace) { 57616e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 5762c8587f34SStefano Zampini } 5763cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 57646e683305SStefano Zampini if (compute_eigs) { 5765854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 5766854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 57676e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 57686e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 57696e683305SStefano Zampini lambda_min = eigs_r[0]; 57706e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 57716e683305SStefano Zampini if (lambda_max>lambda_min) { 5772cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 5773cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 5774cbcc2c2aSStefano Zampini } 5775c8587f34SStefano Zampini } 5776c8587f34SStefano Zampini } 5777cbcc2c2aSStefano Zampini 5778c8587f34SStefano Zampini /* check coarse problem residual error */ 57796e683305SStefano Zampini if (pcbddc->dbg_flag) { 57806e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 57816e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 57826e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 5783c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 57846e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 57856e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 5786c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 5787779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 57886e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 57896e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 57906e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 57916e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 5792b0f5fe93SStefano Zampini if (CoarseNullSpace) { 5793b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 5794b0f5fe93SStefano Zampini } 57956e683305SStefano Zampini if (compute_eigs) { 57966e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 5797deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 5798c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 57996e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 58006e683305SStefano 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); 58016e683305SStefano Zampini for (i=0;i<neigs;i++) { 58026e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 5803c8587f34SStefano Zampini } 58046e683305SStefano Zampini } 58056e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 58066e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 58076e683305SStefano Zampini } 5808c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 58096e683305SStefano Zampini if (compute_eigs) { 58106e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 58116e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 5812c8587f34SStefano Zampini } 58136e683305SStefano Zampini } 58146e683305SStefano Zampini } 5815cbcc2c2aSStefano Zampini /* print additional info */ 5816cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 58176e683305SStefano Zampini /* waits until all processes reaches this point */ 58186e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 5819cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 5820cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5821cbcc2c2aSStefano Zampini } 5822cbcc2c2aSStefano Zampini 58232b510759SStefano Zampini /* free memory */ 5824c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 5825fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 5826c8587f34SStefano Zampini PetscFunctionReturn(0); 5827c8587f34SStefano Zampini } 5828674ae819SStefano Zampini 5829f34684f1SStefano Zampini #undef __FUNCT__ 5830f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 5831f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 5832f34684f1SStefano Zampini { 5833f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5834f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 5835f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5836dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 5837dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 583873be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 5839dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 5840f34684f1SStefano Zampini PetscErrorCode ierr; 5841f34684f1SStefano Zampini 5842f34684f1SStefano Zampini PetscFunctionBegin; 5843f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 58440e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 58450e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 5846727cdba6SStefano Zampini } 5847dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 58483bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 5849dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5850dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 5851dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 5852dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 5853dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 5854dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 58550e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 58560e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 58570e6343abSStefano Zampini } 5858dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 5859dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5860dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 5861dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 5862dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 5863f34684f1SStefano Zampini 5864f34684f1SStefano Zampini /* check numbering */ 5865f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 5866019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 5867dc456d91SStefano Zampini PetscInt i; 5868b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 5869f34684f1SStefano Zampini 5870f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5871f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5872f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 58731575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5874019a44ceSStefano Zampini /* counter */ 5875019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5876019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5877019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5878019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5879019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5880019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5881f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 5882f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 5883727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5884f34684f1SStefano Zampini } 5885f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 5886f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 5887f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5888e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5889e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5890e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5891e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5892f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5893019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5894f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5895019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 589675c01103SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]); 589775c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 5898b9b85e73SStefano Zampini set_error = PETSC_TRUE; 5899019a44ceSStefano 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); 5900f34684f1SStefano Zampini } 5901f34684f1SStefano Zampini } 5902019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 5903b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 5904f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5905f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 5906f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 5907f34684f1SStefano Zampini } 5908f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 5909f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5910e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5911e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5912f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 5913f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 5914b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 5915ca8b9ea9SStefano Zampini PetscInt *gidxs; 5916ca8b9ea9SStefano Zampini 5917ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 59183bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 5919f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 5920f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5921f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5922f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 59234bc2dc4bSStefano 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); 5924f34684f1SStefano Zampini } 5925f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5926ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 5927f34684f1SStefano Zampini } 5928f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 59291575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5930302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 5931f34684f1SStefano Zampini } 59328bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 5933f34684f1SStefano Zampini /* get back data */ 5934f34684f1SStefano Zampini *coarse_size_n = coarse_size; 5935f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 5936674ae819SStefano Zampini PetscFunctionReturn(0); 5937674ae819SStefano Zampini } 5938674ae819SStefano Zampini 5939e456f2a8SStefano Zampini #undef __FUNCT__ 5940e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 5941a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 5942e456f2a8SStefano Zampini { 5943e456f2a8SStefano Zampini IS localis_t; 5944a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 5945e456f2a8SStefano Zampini PetscScalar *vals; 5946e456f2a8SStefano Zampini PetscErrorCode ierr; 5947e456f2a8SStefano Zampini 5948e456f2a8SStefano Zampini PetscFunctionBegin; 5949a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 5950e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 5951854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 5952e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 5953e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5954a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 5955a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 59561035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 5957a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 59581035eff8SStefano Zampini } 5959a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 5960e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 5961e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 5962a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 5963a7dc3881SStefano Zampini /* now compute set in local ordering */ 5964a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5965a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5966a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5967a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 5968a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5969ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5970e456f2a8SStefano Zampini lsize++; 5971e456f2a8SStefano Zampini } 5972e456f2a8SStefano Zampini } 5973854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 5974a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 5975ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 5976e456f2a8SStefano Zampini idxs[lsize++] = i; 5977e456f2a8SStefano Zampini } 5978e456f2a8SStefano Zampini } 5979a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 5980a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 5981e456f2a8SStefano Zampini *localis = localis_t; 5982e456f2a8SStefano Zampini PetscFunctionReturn(0); 5983e456f2a8SStefano Zampini } 5984906d46d4SStefano Zampini 5985906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 5986906d46d4SStefano Zampini #undef __FUNCT__ 5987906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 5988906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 5989906d46d4SStefano Zampini { 5990906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 5991906d46d4SStefano Zampini PetscErrorCode ierr; 5992906d46d4SStefano Zampini 5993906d46d4SStefano Zampini PetscFunctionBegin; 5994906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 5995906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 5996906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 5997906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 5998906d46d4SStefano Zampini PetscFunctionReturn(0); 5999906d46d4SStefano Zampini } 6000906d46d4SStefano Zampini 6001906d46d4SStefano Zampini #undef __FUNCT__ 6002906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 6003906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 6004906d46d4SStefano Zampini { 6005906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 6006906d46d4SStefano Zampini PetscErrorCode ierr; 6007906d46d4SStefano Zampini 6008906d46d4SStefano Zampini PetscFunctionBegin; 6009906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 6010906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 6011906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 6012906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 6013906d46d4SStefano Zampini PetscFunctionReturn(0); 6014906d46d4SStefano Zampini } 6015b96c3477SStefano Zampini 6016b96c3477SStefano Zampini #undef __FUNCT__ 6017b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 601808122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 6019b96c3477SStefano Zampini { 6020a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6021b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6022b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6023a64f4aa4SStefano Zampini Mat S_j; 6024b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 6025b96c3477SStefano Zampini PetscBool free_used_adj; 6026b96c3477SStefano Zampini PetscErrorCode ierr; 6027b96c3477SStefano Zampini 6028b96c3477SStefano Zampini PetscFunctionBegin; 6029b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 6030b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 603108122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 6032b96c3477SStefano Zampini used_xadj = NULL; 6033b96c3477SStefano Zampini used_adjncy = NULL; 6034b96c3477SStefano Zampini } else { 603508122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 603608122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 603708122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 603808122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 6039b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 6040b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 6041b96c3477SStefano Zampini } else { 60422fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 6043b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 6044b96c3477SStefano Zampini PetscInt nvtxs; 6045b96c3477SStefano Zampini 60462fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 60472fffb893SStefano Zampini if (flg_row) { 6048b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 6049b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 6050b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 6051b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 60522fffb893SStefano Zampini } else { 60532fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 60542fffb893SStefano Zampini used_xadj = NULL; 60552fffb893SStefano Zampini used_adjncy = NULL; 60562fffb893SStefano Zampini } 60572fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 6058b96c3477SStefano Zampini } 6059b96c3477SStefano Zampini } 6060d5574798SStefano Zampini 6061d5574798SStefano Zampini /* setup sub_schurs data */ 6062a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6063a64f4aa4SStefano Zampini if (!sub_schurs->use_mumps) { 6064a64f4aa4SStefano Zampini /* pcbddc->ksp_D up to date only if not using MUMPS */ 6065a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6066ca92afb2SStefano 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); 6067a64f4aa4SStefano Zampini } else { 60686816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 606904708bb6SStefano Zampini PetscBool isseqaij; 6070*a3df083aSStefano Zampini PetscInt benign_n; 6071*a3df083aSStefano Zampini 60725feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 60735feab87aSStefano Zampini PetscInt n_vertices; 60745feab87aSStefano Zampini 60755feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 60762034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 60775feab87aSStefano Zampini } 607804708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 607904708bb6SStefano Zampini if (!isseqaij) { 608004708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 608104708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 608204708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 608304708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 608404708bb6SStefano Zampini } else { 608504708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 608604708bb6SStefano Zampini } 608704708bb6SStefano Zampini } 6088*a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 6089*a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 6090ca92afb2SStefano Zampini } else { 6091*a3df083aSStefano Zampini benign_n = 0; 6092ca92afb2SStefano Zampini } 6093*a3df083aSStefano 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); 6094ca92afb2SStefano Zampini } 6095b96c3477SStefano Zampini 6096b96c3477SStefano Zampini /* free adjacency */ 6097b96c3477SStefano Zampini if (free_used_adj) { 6098b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 6099b96c3477SStefano Zampini } 6100b96c3477SStefano Zampini PetscFunctionReturn(0); 6101b96c3477SStefano Zampini } 6102b96c3477SStefano Zampini 6103b96c3477SStefano Zampini #undef __FUNCT__ 6104b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 610508122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 6106b96c3477SStefano Zampini { 6107b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6108b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6109b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6110b96c3477SStefano Zampini PCBDDCGraph graph; 6111b96c3477SStefano Zampini PetscErrorCode ierr; 6112b96c3477SStefano Zampini 6113b96c3477SStefano Zampini PetscFunctionBegin; 6114b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 611508122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 61163301b35fSStefano Zampini IS verticesIS,verticescomm; 61173301b35fSStefano Zampini PetscInt vsize,*idxs; 6118b96c3477SStefano Zampini 6119b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 61203301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 61213301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 61223301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 61233301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 61243301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 6125b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 61267fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 61273301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 61283301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 6129b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 6130b96c3477SStefano Zampini /* 6131b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 6132b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 6133b96c3477SStefano Zampini } 6134b96c3477SStefano Zampini */ 6135b96c3477SStefano Zampini } else { 6136b96c3477SStefano Zampini graph = pcbddc->mat_graph; 6137b96c3477SStefano Zampini } 6138b96c3477SStefano Zampini 6139b96c3477SStefano Zampini /* sub_schurs init */ 6140a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 6141a64f4aa4SStefano Zampini 6142b96c3477SStefano Zampini /* free graph struct */ 614308122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 6144b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 6145b96c3477SStefano Zampini } 6146b96c3477SStefano Zampini PetscFunctionReturn(0); 6147b96c3477SStefano Zampini } 6148fa34dd3eSStefano Zampini 6149fa34dd3eSStefano Zampini #undef __FUNCT__ 6150fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 6151fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 6152fa34dd3eSStefano Zampini { 6153fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 6154fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 6155fa34dd3eSStefano Zampini PetscErrorCode ierr; 6156fa34dd3eSStefano Zampini 6157fa34dd3eSStefano Zampini PetscFunctionBegin; 6158fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 6159fa34dd3eSStefano Zampini IS zerodiag = NULL; 61604f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 6161fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 61624f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 616375c01103SStefano Zampini PetscReal norm; 6164fa34dd3eSStefano Zampini PetscInt i; 6165fa34dd3eSStefano Zampini 6166fa34dd3eSStefano Zampini /* B0 and B0_B */ 6167fa34dd3eSStefano Zampini if (zerodiag) { 6168fa34dd3eSStefano Zampini IS dummy; 6169fa34dd3eSStefano Zampini 61704f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 61714f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 6172fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 6173fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 6174fa34dd3eSStefano Zampini } 6175fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 6176fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 6177fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 6178fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6179fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6180fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6181fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6182fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 6183fa34dd3eSStefano Zampini /* S_j */ 6184fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 6185fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 6186fa34dd3eSStefano Zampini 6187fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 6188fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 6189fa34dd3eSStefano Zampini /* continuous in primal space */ 6190fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 6191fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6192fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6193fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 61944f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 61954f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 6196fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6197fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6198fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6199fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6200fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6201fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6202fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 6203fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 6204fa34dd3eSStefano Zampini 6205fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 6206fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 6207fa34dd3eSStefano Zampini /* local with Schur */ 6208fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 6209fa34dd3eSStefano Zampini if (zerodiag) { 6210fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 62114f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 6212fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6213fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 6214fa34dd3eSStefano Zampini } 6215fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 6216fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6217fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6218fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6219fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6220fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 6221fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 6222fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 6223fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 6224fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6225fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6226fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6227fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6228fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6229fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 6230fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 6231fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 6232fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 6233fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 6234fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 6235fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6236fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6237fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 6238fa34dd3eSStefano Zampini if (zerodiag) { 6239fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 6240fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 62414f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 6242fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 6243fa34dd3eSStefano Zampini } 6244fa34dd3eSStefano Zampini /* BDDC */ 6245fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 6246fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 6247fa34dd3eSStefano Zampini 6248fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 6249fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 6250fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 6251fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 62524f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 62534f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 6254fa34dd3eSStefano Zampini } 62554f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 6256fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 6257fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 6258fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 6259fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 6260fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 6261fa34dd3eSStefano Zampini } 6262fa34dd3eSStefano Zampini PetscFunctionReturn(0); 6263fa34dd3eSStefano Zampini } 6264