1ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 3674ae819SStefano Zampini #include <petscblaslapack.h> 4674ae819SStefano Zampini 5906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y); 6906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y); 7906d46d4SStefano Zampini 8b1b3d7a2SStefano Zampini #undef __FUNCT__ 9b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 1008122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 11b1b3d7a2SStefano Zampini { 12b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1308122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 1408122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 1508122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 1608122e43SStefano Zampini PetscScalar *work,lwork; 1708122e43SStefano Zampini PetscScalar *St,*S,*eigv; 1808122e43SStefano Zampini PetscScalar *Sarray,*Starray; 1908122e43SStefano Zampini PetscScalar *Smult,*Seigv; 2008122e43SStefano Zampini PetscReal *eigs,thresh; 2108122e43SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs,maxneigs_r,cumsubs; 2208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2308122e43SStefano Zampini PetscReal *rwork; 2408122e43SStefano Zampini #endif 2508122e43SStefano Zampini PetscBool symmetric; 26b1b3d7a2SStefano Zampini PetscErrorCode ierr; 27b1b3d7a2SStefano Zampini 28b1b3d7a2SStefano Zampini PetscFunctionBegin; 2908122e43SStefano Zampini if (!sub_schurs->use_mumps) { 3008122e43SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS"); 3108122e43SStefano Zampini } 3208122e43SStefano Zampini ierr = MatIsSymmetric(sub_schurs->A,0.0,&symmetric);CHKERRQ(ierr); 3308122e43SStefano Zampini if (!symmetric) { 3408122e43SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Not yet implemented"); 3508122e43SStefano Zampini } 3608122e43SStefano Zampini 3708122e43SStefano Zampini /* max size of subsets */ 3808122e43SStefano Zampini mss = 0; 3908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4008122e43SStefano Zampini if (PetscBTLookup(sub_schurs->computed_Stilda_subs,i)) { 4108122e43SStefano Zampini PetscInt subset_size; 4208122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 4308122e43SStefano Zampini mss = PetscMax(mss,subset_size); 4408122e43SStefano Zampini } 4508122e43SStefano Zampini } 4608122e43SStefano Zampini 4708122e43SStefano Zampini /* min/max and threshold */ 4808122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 4908122e43SStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 1; 5008122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 5108122e43SStefano Zampini if (pcbddc->adaptive_threshold > 1.0) { 5208122e43SStefano Zampini thresh = 1.0/pcbddc->adaptive_threshold; 5308122e43SStefano Zampini } else { 5408122e43SStefano Zampini thresh = 1.0; 5508122e43SStefano Zampini } 5608122e43SStefano Zampini 5708122e43SStefano Zampini /* allocate lapack workspace */ 5808122e43SStefano Zampini cum = cum2 = 0; 5908122e43SStefano Zampini maxneigs = 0; 6008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6108122e43SStefano Zampini if (PetscBTLookup(sub_schurs->computed_Stilda_subs,i)) { 6208122e43SStefano Zampini PetscInt n,subset_size; 6308122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 6408122e43SStefano Zampini n = PetscMin(subset_size,nmax); 6508122e43SStefano Zampini n = PetscMax(n,nmin); 6608122e43SStefano Zampini cum += subset_size*n; 6708122e43SStefano Zampini cum2 += n; 6808122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 6908122e43SStefano Zampini } 7008122e43SStefano Zampini } 7108122e43SStefano Zampini 7208122e43SStefano Zampini if (mss) { 7308122e43SStefano Zampini if (symmetric) { 7408122e43SStefano Zampini PetscBLASInt B_itype = 1; 7508122e43SStefano Zampini PetscBLASInt B_N = mss; 7608122e43SStefano Zampini PetscScalar zero = 0.0; 7708122e43SStefano Zampini PetscScalar eps = 0.0; /* dlamch? */ 7808122e43SStefano Zampini 7908122e43SStefano Zampini B_lwork = -1; 8008122e43SStefano Zampini S = NULL; 8108122e43SStefano Zampini St = NULL; 8208122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 8308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 8408122e43SStefano 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)); 8508122e43SStefano Zampini #else 8608122e43SStefano 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)); 8708122e43SStefano Zampini #endif 8808122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 8908122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 9008122e43SStefano Zampini } else { 9108122e43SStefano Zampini /* TODO */ 9208122e43SStefano Zampini } 9308122e43SStefano Zampini } else { 9408122e43SStefano Zampini lwork = 0; 9508122e43SStefano Zampini } 9608122e43SStefano Zampini 9708122e43SStefano Zampini nv = 0; 9808122e43SStefano Zampini if (sub_schurs->is_Ej_com) { /* complement of subsets, each entry is a vertex */ 9908122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_Ej_com,&nv);CHKERRQ(ierr); 10008122e43SStefano Zampini } 10108122e43SStefano Zampini ierr = PetscBLASIntCast((PetscInt)lwork,&B_lwork);CHKERRQ(ierr); 10208122e43SStefano Zampini ierr = PetscMalloc7(mss*mss,&S,mss*mss,&St,mss*mss,&eigv,mss,&eigs, 10308122e43SStefano Zampini B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 10408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 10508122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 10608122e43SStefano Zampini #endif 10708122e43SStefano Zampini ierr = PetscMalloc2(mss*mss,&Smult,mss*mss,&Seigv);CHKERRQ(ierr); 10808122e43SStefano Zampini ierr = PetscMalloc4(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 10908122e43SStefano Zampini nv+cum2+1,&pcbddc->adaptive_constraints_ptrs, 11008122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 11108122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 11208122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 11308122e43SStefano Zampini 11408122e43SStefano Zampini maxneigs = 0; 11508122e43SStefano Zampini cum = cum2 = cumarray = 0; 11608122e43SStefano Zampini if (sub_schurs->is_Ej_com) { 11708122e43SStefano Zampini const PetscInt *idxs; 11808122e43SStefano Zampini 11908122e43SStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_com,&idxs);CHKERRQ(ierr); 12008122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 12108122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 12208122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 12308122e43SStefano Zampini pcbddc->adaptive_constraints_ptrs[cum] = cum; 12408122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 12508122e43SStefano Zampini } 12608122e43SStefano Zampini cum2 = cum; 12708122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_com,&idxs);CHKERRQ(ierr); 12808122e43SStefano Zampini } 12908122e43SStefano Zampini 13008122e43SStefano Zampini if (mss) { /* multilevel */ 13108122e43SStefano Zampini if (pcbddc->use_deluxe_scaling) { 13208122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 13308122e43SStefano Zampini } else { 13408122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_all,&Sarray);CHKERRQ(ierr); 13508122e43SStefano Zampini } 13608122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 13708122e43SStefano Zampini } 13808122e43SStefano Zampini 13908122e43SStefano Zampini cumsubs = 0; 14008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 14108122e43SStefano Zampini PetscInt j,subset_size; 14208122e43SStefano Zampini 14308122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 14408122e43SStefano Zampini if (PetscBTLookup(sub_schurs->computed_Stilda_subs,i)) { 14508122e43SStefano Zampini const PetscInt *idxs; 14608122e43SStefano Zampini PetscScalar one = 1.0,zero=0.0; 14708122e43SStefano Zampini PetscBLASInt B_N; 14808122e43SStefano Zampini 14908122e43SStefano Zampini /* S should be copied since we need it for deluxe scaling */ 15008122e43SStefano Zampini if (symmetric) { 15108122e43SStefano Zampini PetscInt j; 15208122e43SStefano Zampini for (j=0;j<subset_size;j++) { 15308122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 15408122e43SStefano Zampini } 15508122e43SStefano Zampini for (j=0;j<subset_size;j++) { 15608122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 15708122e43SStefano Zampini } 15808122e43SStefano Zampini } else { 15908122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 16008122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 16108122e43SStefano Zampini } 16208122e43SStefano Zampini /* is always this the right matrix? */ 16308122e43SStefano Zampini ierr = PetscMemcpy(Smult,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 16408122e43SStefano Zampini 16508122e43SStefano Zampini /* we could reuse space already allocated when building sum_S_Ej_tilda_all */ 16608122e43SStefano Zampini /* St = Starray+cumarray; */ 16708122e43SStefano Zampini 16808122e43SStefano Zampini if (symmetric) { 16908122e43SStefano Zampini PetscBLASInt B_itype = 1; 17008122e43SStefano Zampini PetscBLASInt B_IL = 1, B_IU; 17108122e43SStefano Zampini PetscScalar eps = -1.0; /* dlamch? */ 17208122e43SStefano Zampini 17308122e43SStefano Zampini /* ask for eigenvalues lower than thresh */ 17408122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] Computing for sub %d/%d.\n",PetscGlobalRank,i,sub_schurs->n_subs); 17508122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 17608122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 17708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 17808122e43SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&zero,&thresh,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 17908122e43SStefano Zampini #else 18008122e43SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&zero,&thresh,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 18108122e43SStefano Zampini #endif 18208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 18308122e43SStefano Zampini if (B_ierr) { 18408122e43SStefano Zampini if (B_ierr < 0 ) { 18508122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 18608122e43SStefano Zampini } else if (B_ierr <= B_N) { 18708122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 18808122e43SStefano Zampini } else { 18908122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d principal minor not posdef",(int)B_ierr-B_N-1); 19008122e43SStefano Zampini } 19108122e43SStefano Zampini } 19208122e43SStefano Zampini 19308122e43SStefano Zampini if (B_neigs > nmax) { 19408122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] found %d eigs, more than required %d.\n",PetscGlobalRank,B_neigs,nmax); 19508122e43SStefano Zampini B_neigs = nmax; 19608122e43SStefano Zampini } 19708122e43SStefano Zampini 19808122e43SStefano Zampini if (B_neigs < nmin) { 19908122e43SStefano Zampini PetscBLASInt B_neigs2; 20008122e43SStefano Zampini 20108122e43SStefano Zampini B_IL = B_neigs + 1; 20208122e43SStefano Zampini ierr = PetscBLASIntCast(nmin,&B_IU);CHKERRQ(ierr); 20308122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] found %d eigs, less than required %d. Asking for %d to %d incl (fortran like)\n",PetscGlobalRank,B_neigs,nmin,B_IL,B_IU); 20408122e43SStefano Zampini if (symmetric) { 20508122e43SStefano Zampini PetscInt j; 20608122e43SStefano Zampini for (j=0;j<subset_size;j++) { 20708122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 20808122e43SStefano Zampini } 20908122e43SStefano Zampini for (j=0;j<subset_size;j++) { 21008122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 21108122e43SStefano Zampini } 21208122e43SStefano Zampini } else { 21308122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 21408122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 21508122e43SStefano Zampini } 21608122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 21708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 21808122e43SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&zero,&thresh,&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)); 21908122e43SStefano Zampini #else 22008122e43SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&zero,&thresh,&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)); 22108122e43SStefano Zampini #endif 22208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 22308122e43SStefano Zampini B_neigs += B_neigs2; 22408122e43SStefano Zampini } 22508122e43SStefano Zampini if (B_ierr) { 22608122e43SStefano Zampini if (B_ierr < 0 ) { 22708122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 22808122e43SStefano Zampini } else if (B_ierr <= B_N) { 22908122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 23008122e43SStefano Zampini } else { 23108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d principal minor not posdef",(int)B_ierr-B_N-1); 23208122e43SStefano Zampini } 23308122e43SStefano Zampini } 23408122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] -> Got %d eigs\n",PetscGlobalRank,B_neigs); 23508122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 23608122e43SStefano Zampini if (eigs[j] == 0.0) { 23708122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] Inf\n",PetscGlobalRank); 23808122e43SStefano Zampini } else { 23908122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] %1.6e\n",PetscGlobalRank,1.0/eigs[j]); 24008122e43SStefano Zampini } 24108122e43SStefano Zampini } 24208122e43SStefano Zampini } else { 24308122e43SStefano Zampini /* TODO */ 24408122e43SStefano Zampini } 24508122e43SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 24608122e43SStefano Zampini pcbddc->adaptive_constraints_n[cumsubs+nv] = B_neigs; 24708122e43SStefano Zampini cumsubs++; 24808122e43SStefano Zampini 24908122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 25008122e43SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&B_N,&B_neigs,&B_N,&one,Smult,&B_N,eigv,&B_N,&zero,Seigv,&B_N)); 25108122e43SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_data+cum2,Seigv,B_neigs*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 25208122e43SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 25308122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 25408122e43SStefano Zampini #if 0 25508122e43SStefano Zampini { 25608122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 25708122e43SStefano Zampini PetscScalar norm; 25808122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 25908122e43SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+cum2,&Blas_one,pcbddc->adaptive_constraints_data+cum2,&Blas_one)); 26008122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 26108122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 26208122e43SStefano Zampini } else { 26308122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 26408122e43SStefano Zampini } 26508122e43SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+cum2,&Blas_one)); 266b1b3d7a2SStefano Zampini } 267b1b3d7a2SStefano Zampini #endif 26808122e43SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+cum2,idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 26908122e43SStefano Zampini pcbddc->adaptive_constraints_ptrs[cum++] = cum2; 27008122e43SStefano Zampini cum2 += subset_size; 27108122e43SStefano Zampini } 27208122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 27308122e43SStefano Zampini } 27408122e43SStefano Zampini /* shift for next computation */ 27508122e43SStefano Zampini cumarray += subset_size*subset_size; 27608122e43SStefano Zampini } 27708122e43SStefano Zampini pcbddc->adaptive_constraints_ptrs[cum] = cum2; 27808122e43SStefano Zampini ierr = PetscFree2(Smult,Seigv);CHKERRQ(ierr); 27908122e43SStefano Zampini 28008122e43SStefano Zampini if (mss) { 28108122e43SStefano Zampini if (pcbddc->use_deluxe_scaling) { 28208122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 28308122e43SStefano Zampini } else { 28408122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_all,&Sarray);CHKERRQ(ierr); 28508122e43SStefano Zampini } 28608122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 28708122e43SStefano Zampini } 28808122e43SStefano Zampini ierr = PetscFree7(S,St,eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 28908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 29008122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 29108122e43SStefano Zampini #endif 29208122e43SStefano Zampini if (pcbddc->dbg_flag) { 29308122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 29408122e43SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 29508122e43SStefano Zampini } 29608122e43SStefano Zampini PetscFunctionReturn(0); 29708122e43SStefano Zampini } 298b1b3d7a2SStefano Zampini 299674ae819SStefano Zampini #undef __FUNCT__ 300c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 301c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 302c8587f34SStefano Zampini { 303c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3048629588bSStefano Zampini PetscScalar *coarse_submat_vals; 305c8587f34SStefano Zampini PetscErrorCode ierr; 306c8587f34SStefano Zampini 307c8587f34SStefano Zampini PetscFunctionBegin; 308f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 3095e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 310c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 311c8587f34SStefano Zampini 312684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 3130fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 314684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 315c8587f34SStefano Zampini 316c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 317b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 318c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 319c8587f34SStefano Zampini } 320c8587f34SStefano Zampini 3218629588bSStefano Zampini /* 3228629588bSStefano Zampini Setup local correction and local part of coarse basis. 3238629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 3248629588bSStefano Zampini */ 32547f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 3268629588bSStefano Zampini 3278629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 3288629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 3298629588bSStefano Zampini 3308629588bSStefano Zampini /* free */ 3318629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 332c8587f34SStefano Zampini PetscFunctionReturn(0); 333c8587f34SStefano Zampini } 334c8587f34SStefano Zampini 335c8587f34SStefano Zampini #undef __FUNCT__ 336674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 337674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 338674ae819SStefano Zampini { 339674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 340674ae819SStefano Zampini PetscErrorCode ierr; 341674ae819SStefano Zampini 342674ae819SStefano Zampini PetscFunctionBegin; 343674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 344674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 345674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 346674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 347785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 348674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 349f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 350f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 351785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 35263602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 35363602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 354674ae819SStefano Zampini PetscFunctionReturn(0); 355674ae819SStefano Zampini } 356674ae819SStefano Zampini 357674ae819SStefano Zampini #undef __FUNCT__ 358674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 359674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 360674ae819SStefano Zampini { 361674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 362674ae819SStefano Zampini PetscErrorCode ierr; 363674ae819SStefano Zampini 364674ae819SStefano Zampini PetscFunctionBegin; 365b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 366674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 367674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 368674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 369b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 370674ae819SStefano Zampini PetscFunctionReturn(0); 371674ae819SStefano Zampini } 372674ae819SStefano Zampini 373674ae819SStefano Zampini #undef __FUNCT__ 374674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 375674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 376674ae819SStefano Zampini { 377674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 37806656605SStefano Zampini PetscScalar *array; 379674ae819SStefano Zampini PetscErrorCode ierr; 380674ae819SStefano Zampini 381674ae819SStefano Zampini PetscFunctionBegin; 382674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 383674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 38406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 38506656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 386674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 387674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 38815aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 38915aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 390674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 391674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 39206656605SStefano Zampini if (pcbddc->local_auxmat2) { 39306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 39406656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 39506656605SStefano Zampini } 396674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 39706656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 398674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 399674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 4008ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 401674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 402674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 403674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 404f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 405f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 406f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 407f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 408727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 409f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 41070cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 4116e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 412674ae819SStefano Zampini PetscFunctionReturn(0); 413674ae819SStefano Zampini } 414674ae819SStefano Zampini 415674ae819SStefano Zampini #undef __FUNCT__ 416f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 417f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 4186bfb1811SStefano Zampini { 4196bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4206bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4216bfb1811SStefano Zampini VecType impVecType; 422e9189074SStefano Zampini PetscInt n_constraints,n_R,old_size; 4236bfb1811SStefano Zampini PetscErrorCode ierr; 4246bfb1811SStefano Zampini 4256bfb1811SStefano Zampini PetscFunctionBegin; 426f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 427f4ddd8eeSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 428f4ddd8eeSStefano Zampini } 429e7b262bdSStefano Zampini /* get sizes */ 430e9189074SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->n_actual_vertices; 431e9189074SStefano Zampini n_R = pcis->n-pcbddc->n_actual_vertices; 4326bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 433e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 434e7b262bdSStefano Zampini /* R nodes */ 435e7b262bdSStefano Zampini old_size = -1; 436e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 437e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 438e7b262bdSStefano Zampini } 439e7b262bdSStefano Zampini if (n_R != old_size) { 440e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 441e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 4426bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 4436bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 4446bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 4456bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 446e7b262bdSStefano Zampini } 447e7b262bdSStefano Zampini /* local primal dofs */ 448e7b262bdSStefano Zampini old_size = -1; 449e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 450e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 451e7b262bdSStefano Zampini } 452e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 453e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 45483b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 455e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 4566bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 457e7b262bdSStefano Zampini } 458e7b262bdSStefano Zampini /* local explicit constraints */ 459e7b262bdSStefano Zampini old_size = -1; 460e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 461e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 462e7b262bdSStefano Zampini } 463e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 464e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 46583b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 46683b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 46783b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 46883b7ccabSStefano Zampini } 4696bfb1811SStefano Zampini PetscFunctionReturn(0); 4706bfb1811SStefano Zampini } 4716bfb1811SStefano Zampini 4726bfb1811SStefano Zampini #undef __FUNCT__ 47347f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 47447f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 47588ebb749SStefano Zampini { 47625084f0cSStefano Zampini PetscErrorCode ierr; 47725084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 47888ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 47988ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 48025084f0cSStefano Zampini /* submatrices of local problem */ 48188ebb749SStefano Zampini Mat A_RV,A_VR,A_VV; 48206656605SStefano Zampini /* submatrices of local coarse problem */ 48306656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 48425084f0cSStefano Zampini /* working matrices */ 48506656605SStefano Zampini Mat C_CR; 48625084f0cSStefano Zampini /* additional working stuff */ 48706656605SStefano Zampini PC pc_R; 48806656605SStefano Zampini Mat F; 48906656605SStefano Zampini PetscBool isLU,isCHOL,isILU; 49006656605SStefano Zampini 49125084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 49206656605SStefano Zampini PetscScalar *work; 49306656605SStefano Zampini PetscInt *idx_V_B; 49406656605SStefano Zampini PetscInt n,n_vertices,n_constraints; 49506656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 496b9d89cd5SStefano Zampini PetscBool unsymmetric_check; 49745a1bb75SStefano Zampini /* matrix type (vector type propagated downstream from vec1_C and local matrix type) */ 49888ebb749SStefano Zampini MatType impMatType; 49925084f0cSStefano Zampini /* some shortcuts to scalars */ 50006656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 50188ebb749SStefano Zampini 50288ebb749SStefano Zampini PetscFunctionBegin; 503e9189074SStefano Zampini /* get number of vertices (corners plus constraints with change of basis) 504e9189074SStefano Zampini pcbddc->n_actual_vertices stores the actual number of vertices, pcbddc->n_vertices the number of corners computed */ 505e9189074SStefano Zampini n_vertices = pcbddc->n_actual_vertices; 50688ebb749SStefano Zampini n_constraints = pcbddc->local_primal_size-n_vertices; 50788ebb749SStefano Zampini /* Set Non-overlapping dimensions */ 50888ebb749SStefano Zampini n_B = pcis->n_B; n_D = pcis->n - n_B; 50988ebb749SStefano Zampini n_R = pcis->n-n_vertices; 51088ebb749SStefano Zampini 51188ebb749SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 51288ebb749SStefano Zampini impMatType = MATSEQDENSE; 51388ebb749SStefano Zampini 51488ebb749SStefano Zampini /* vertices in boundary numbering */ 515785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 5165e8657edSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->primal_indices_local_idxs,&i,idx_V_B);CHKERRQ(ierr); 51788ebb749SStefano Zampini if (i != n_vertices) { 51822d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 51988ebb749SStefano Zampini } 52088ebb749SStefano Zampini 52106656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 52206656605SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 52306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 52406656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 52506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 52606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 52706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 52806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 52906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 53006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 53106656605SStefano Zampini 53206656605SStefano Zampini unsymmetric_check = PETSC_FALSE; 53306656605SStefano Zampini /* allocate workspace */ 53406656605SStefano Zampini n = 0; 53506656605SStefano Zampini if (n_constraints) { 53606656605SStefano Zampini n += n_R*n_constraints; 53706656605SStefano Zampini } 53806656605SStefano Zampini if (n_vertices) { 53906656605SStefano Zampini n = PetscMax(2*n_R*n_vertices,n); 54006656605SStefano Zampini } 54106656605SStefano Zampini if (!pcbddc->issym) { 54206656605SStefano Zampini n = PetscMax(2*n_R*pcbddc->local_primal_size,n); 54306656605SStefano Zampini unsymmetric_check = PETSC_TRUE; 54406656605SStefano Zampini } 54506656605SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 54606656605SStefano Zampini 54706656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 54806656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 54906656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 55006656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 55106656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 55206656605SStefano Zampini if (isLU || isILU || isCHOL) { 55306656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 55406656605SStefano Zampini } else { 55506656605SStefano Zampini F = NULL; 55606656605SStefano Zampini } 55706656605SStefano Zampini 55888ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 55988ebb749SStefano Zampini if (n_constraints) { 56006656605SStefano Zampini Mat M1,M2,M3; 56106656605SStefano Zampini IS is_aux; 562f4ddd8eeSStefano Zampini /* see if we can save some allocations */ 563f4ddd8eeSStefano Zampini if (pcbddc->local_auxmat2) { 564f4ddd8eeSStefano Zampini PetscInt on_R,on_constraints; 565f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->local_auxmat2,&on_R,&on_constraints);CHKERRQ(ierr); 566f4ddd8eeSStefano Zampini if (on_R != n_R || on_constraints != n_constraints) { 56706656605SStefano Zampini PetscScalar *marray; 56806656605SStefano Zampini 56906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&marray);CHKERRQ(ierr); 57006656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 571f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 572f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 573f4ddd8eeSStefano Zampini } 574f4ddd8eeSStefano Zampini } 57545a1bb75SStefano Zampini /* auxiliary matrices */ 576f4ddd8eeSStefano Zampini if (!pcbddc->local_auxmat2) { 57706656605SStefano Zampini PetscScalar *marray; 57806656605SStefano Zampini 57906656605SStefano Zampini ierr = PetscMalloc1(2*n_R*n_constraints,&marray);CHKERRQ(ierr); 58006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,marray,&pcbddc->local_auxmat2);CHKERRQ(ierr); 58106656605SStefano Zampini marray += n_R*n_constraints; 58206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_R,marray,&pcbddc->local_auxmat1);CHKERRQ(ierr); 583f4ddd8eeSStefano Zampini } 58488ebb749SStefano Zampini 58525084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 58625084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 5878ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 58825084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 58988ebb749SStefano Zampini 59088ebb749SStefano Zampini /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 59106656605SStefano Zampini ierr = PetscMemzero(work,n_R*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 59288ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 59306656605SStefano Zampini const PetscScalar *row_cmat_values; 59406656605SStefano Zampini const PetscInt *row_cmat_indices; 59506656605SStefano Zampini PetscInt size_of_constraint,j; 59688ebb749SStefano Zampini 59706656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 59806656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 59906656605SStefano Zampini work[row_cmat_indices[j]+i*n_R] = -row_cmat_values[j]; 60006656605SStefano Zampini } 60106656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 60206656605SStefano Zampini } 60306656605SStefano Zampini if (F) { 60406656605SStefano Zampini Mat B; 60506656605SStefano Zampini 60606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 60706656605SStefano Zampini ierr = MatMatSolve(F,B,pcbddc->local_auxmat2);CHKERRQ(ierr); 60806656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 60906656605SStefano Zampini } else { 61006656605SStefano Zampini PetscScalar *xarray; 61106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&xarray);CHKERRQ(ierr); 61206656605SStefano Zampini for (i=0;i<n_constraints;i++) { 61306656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 61406656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,xarray+i*n_R);CHKERRQ(ierr); 61506656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 61606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 61706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 61806656605SStefano Zampini } 61906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&xarray);CHKERRQ(ierr); 62006656605SStefano Zampini } 62106656605SStefano Zampini 62206656605SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 62306656605SStefano Zampini ierr = MatConvert(C_CR,impMatType,MAT_REUSE_MATRIX,&C_CR);CHKERRQ(ierr); 62425084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 62506656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 62606656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 62725084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 62806656605SStefano Zampini ierr = VecSet(pcbddc->vec1_C,m_one);CHKERRQ(ierr); 62906656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 63025084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 63125084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 63225084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 63306656605SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CR} needed by BDDC application in KSP and in preproc */ 634f4ddd8eeSStefano Zampini ierr = MatMatMult(M1,C_CR,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 63506656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 63606656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 63788ebb749SStefano Zampini } 63888ebb749SStefano Zampini 63988ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 64088ebb749SStefano Zampini if (n_vertices) { 64106656605SStefano Zampini Mat newmat; 64206656605SStefano Zampini IS is_aux; 6433a50541eSStefano Zampini PetscInt ibs,mbs; 6443a50541eSStefano Zampini PetscBool issbaij; 6453a50541eSStefano Zampini 6463a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 6479577ea80SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 6489577ea80SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 6493a50541eSStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ */ 6509577ea80SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 6519577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 6529577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 6539577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 6549577ea80SStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 6559577ea80SStefano Zampini } else { 6563a50541eSStefano Zampini /* this is safe */ 6579577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 6583a50541eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 6593a50541eSStefano Zampini if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 6603a50541eSStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 6613a50541eSStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 66206656605SStefano Zampini ierr = MatTranspose(A_VR,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 6633a50541eSStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 6643a50541eSStefano Zampini } else { 6659577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 6669577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 6679577ea80SStefano Zampini } 6683a50541eSStefano Zampini } 66925084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 67088ebb749SStefano Zampini } 67188ebb749SStefano Zampini 67288ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 673f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 67406656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 67506656605SStefano Zampini if (pcbddc->coarse_phi_D) { 67606656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 67706656605SStefano Zampini } 678f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 67906656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 68006656605SStefano Zampini PetscScalar *marray; 68106656605SStefano Zampini 68206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 68306656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 684f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 685f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 686f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 687f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 688f4ddd8eeSStefano Zampini } 689f4ddd8eeSStefano Zampini } 69006656605SStefano Zampini 691f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 69206656605SStefano Zampini PetscScalar *marray; 69388ebb749SStefano Zampini 69406656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 6958eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 69606656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 69788ebb749SStefano Zampini } 698b9d89cd5SStefano Zampini if (!pcbddc->issym) { 69906656605SStefano Zampini n *= 2; 700f4ddd8eeSStefano Zampini } 70106656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 70206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 70306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 70406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 70506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 70606656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 70788ebb749SStefano Zampini } 70806656605SStefano Zampini if (!pcbddc->issym) { 70906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 71006656605SStefano Zampini if (pcbddc->switch_static) { 71106656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 71206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 71388ebb749SStefano Zampini } 71488ebb749SStefano Zampini } else { 715c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 716c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 71706656605SStefano Zampini if (pcbddc->switch_static) { 718c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 719c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 720c0553b1fSStefano Zampini } 72188ebb749SStefano Zampini } 72206656605SStefano Zampini } 72306656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 72406656605SStefano Zampini /* vertices */ 72506656605SStefano Zampini if (n_vertices) { 72606656605SStefano Zampini Mat A_RRmA_RV,S_VVt; /* S_VVt with LDA=N */ 72706656605SStefano Zampini PetscScalar *x,*y; 72806656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 72906656605SStefano Zampini 73006656605SStefano Zampini ierr = PetscMemzero(work,2*n_R*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 73106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 73206656605SStefano Zampini ierr = MatConvert(A_RV,impMatType,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 73306656605SStefano Zampini if (F) { 73406656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 73506656605SStefano Zampini } else { 73606656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 73706656605SStefano Zampini for (i=0;i<n_vertices;i++) { 73806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*n_R);CHKERRQ(ierr); 73906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 74006656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 74106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 74206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 74306656605SStefano Zampini } 74406656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 74506656605SStefano Zampini } 74606656605SStefano Zampini ierr = MatScale(A_RRmA_RV,m_one);CHKERRQ(ierr); 74706656605SStefano Zampini /* S_VV and S_CV are the subdomain contribution to coarse matrix. WARNING -> column major ordering */ 74806656605SStefano Zampini if (n_constraints) { 74906656605SStefano Zampini Mat B; 75006656605SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,A_RRmA_RV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 75106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 75206656605SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat2,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 75306656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 75406656605SStefano Zampini ierr = PetscBLASIntCast(n_R*n_vertices,&B_N);CHKERRQ(ierr); 75506656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+n_R*n_vertices,&B_one,work,&B_one)); 75606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 75706656605SStefano Zampini } 75806656605SStefano Zampini ierr = MatConvert(A_VR,impMatType,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 75906656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 76006656605SStefano Zampini ierr = MatConvert(A_VV,impMatType,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 76106656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 76206656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 76306656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 76406656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 76506656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 76606656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 76706656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 76806656605SStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 76906656605SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 77006656605SStefano Zampini /* coarse basis functions */ 77106656605SStefano Zampini for (i=0;i<n_vertices;i++) { 77206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 77306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 77406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 77506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 77606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 77706656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 77806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 77906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 78006656605SStefano Zampini 78106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 78206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 78306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 78406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 78506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 78606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 78706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 78806656605SStefano Zampini } 78906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 79006656605SStefano Zampini } 79106656605SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 79206656605SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 79306656605SStefano Zampini } 79406656605SStefano Zampini 79506656605SStefano Zampini if (n_constraints) { 79606656605SStefano Zampini Mat B; 79706656605SStefano Zampini 79806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 79906656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 80006656605SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat2,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 80106656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 80206656605SStefano Zampini if (n_vertices) { 80306656605SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_VC);CHKERRQ(ierr); 80406656605SStefano Zampini } 80506656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 80606656605SStefano Zampini /* coarse basis functions */ 80706656605SStefano Zampini for (i=0;i<n_constraints;i++) { 80806656605SStefano Zampini PetscScalar *y; 80906656605SStefano Zampini 81006656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 81106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 81206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 81306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 81406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 81506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 81606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 81706656605SStefano Zampini 81806656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 81906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 82006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 82106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 82206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 82306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 82406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 82506656605SStefano Zampini } 82606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 82706656605SStefano Zampini } 82806656605SStefano Zampini } 82906656605SStefano Zampini 83006656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 83106656605SStefano Zampini if (!pcbddc->issym) { 83206656605SStefano Zampini Mat B,X; 83306656605SStefano Zampini 83406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,pcbddc->local_primal_size,work,&B);CHKERRQ(ierr); 83506656605SStefano Zampini 83606656605SStefano Zampini if (n_constraints) { 83706656605SStefano Zampini Mat S_VCT,S_CCT,B_C; 83806656605SStefano Zampini 83906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work+n_vertices*n_R,&B_C);CHKERRQ(ierr); 84006656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 84106656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_CCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 84206656605SStefano Zampini if (n_vertices) { 84306656605SStefano Zampini Mat B_V; 84406656605SStefano Zampini 84506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B_V);CHKERRQ(ierr); 84606656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 84706656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_VCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 84806656605SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 84906656605SStefano Zampini } 85006656605SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 85106656605SStefano Zampini } 85206656605SStefano Zampini if (n_vertices) { 85306656605SStefano Zampini Mat A_VRT; 85406656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 85506656605SStefano Zampini 85606656605SStefano Zampini if (!n_constraints) { /* if there are no constraints, reset work */ 85706656605SStefano Zampini ierr = PetscMemzero(work,n_R*pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 85806656605SStefano Zampini } 85906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work+pcbddc->local_primal_size*n_R,&A_VRT);CHKERRQ(ierr); 86006656605SStefano Zampini ierr = MatTranspose(A_VR,MAT_REUSE_MATRIX,&A_VRT);CHKERRQ(ierr); 86106656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_R,&B_N);CHKERRQ(ierr); 86206656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&m_one,work+pcbddc->local_primal_size*n_R,&B_one,work,&B_one)); 86306656605SStefano Zampini } 86406656605SStefano Zampini 86506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,pcbddc->local_primal_size,work+pcbddc->local_primal_size*n_R,&X);CHKERRQ(ierr); 86606656605SStefano Zampini if (F) { /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 86706656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 86806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 86906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 87006656605SStefano Zampini ierr = MatSolveTranspose(F,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 87106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 87206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 87306656605SStefano Zampini } 87406656605SStefano Zampini } else { 87506656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 87606656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 87706656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 87806656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 87906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 88006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 88106656605SStefano Zampini } 88206656605SStefano Zampini } 88306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 88406656605SStefano Zampini /* coarse basis functions */ 88506656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 88606656605SStefano Zampini PetscScalar *y; 88706656605SStefano Zampini 88806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*(i+pcbddc->local_primal_size));CHKERRQ(ierr); 88906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 89006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 89106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 89206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 89306656605SStefano Zampini if (i<n_vertices) { 89406656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 89506656605SStefano Zampini } 89606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 89706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 89806656605SStefano Zampini 89906656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 90006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 90106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 90206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 90306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 90406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 90506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 90606656605SStefano Zampini } 90706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 90806656605SStefano Zampini } 90906656605SStefano Zampini ierr = MatDestroy(&X);CHKERRQ(ierr); 91006656605SStefano Zampini } 91106656605SStefano Zampini 91288ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 91306656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 91406656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 91506656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 91606656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 91788ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 91888ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 91988ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 92025084f0cSStefano Zampini if (pcbddc->dbg_flag) { 92188ebb749SStefano Zampini Mat coarse_sub_mat; 92225084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 92388ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 92488ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 92588ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 92688ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 92788ebb749SStefano Zampini PetscReal real_value; 92888ebb749SStefano Zampini 92988ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 93088ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 93188ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 93288ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 93388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 93488ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 935c0553b1fSStefano Zampini if (unsymmetric_check) { 93688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 93788ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 93888ebb749SStefano Zampini } 93988ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 94088ebb749SStefano Zampini 94125084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 94206656605SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation\n");CHKERRQ(ierr); 94325084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 944c0553b1fSStefano Zampini if (unsymmetric_check) { 94588ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 94688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 94788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 94888ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 94988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 95088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 95188ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 95288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 95388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 95488ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 95588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 95688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 95788ebb749SStefano Zampini } else { 95888ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 95988ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 96088ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 96188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 96288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 96388ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 96488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 96588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 96688ebb749SStefano Zampini } 96788ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 96888ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 96988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 97088ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 97181d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 97288ebb749SStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&real_value);CHKERRQ(ierr); 97306656605SStefano Zampini 9740fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 97506656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 97625084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 97788ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 97888ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 97988ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 98088ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 98188ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 98288ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 98388ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 98488ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 98588ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 98688ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 987c0553b1fSStefano Zampini if (unsymmetric_check) { 98888ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 98988ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 99088ebb749SStefano Zampini } 99188ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 99288ebb749SStefano Zampini } 99306656605SStefano Zampini 99488ebb749SStefano Zampini /* free memory */ 99506656605SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 99688ebb749SStefano Zampini if (n_vertices) { 99788ebb749SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 99888ebb749SStefano Zampini } 99988ebb749SStefano Zampini if (n_constraints) { 100088ebb749SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 100188ebb749SStefano Zampini } 10028629588bSStefano Zampini /* get back data */ 10038629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 100488ebb749SStefano Zampini PetscFunctionReturn(0); 100588ebb749SStefano Zampini } 100688ebb749SStefano Zampini 100788ebb749SStefano Zampini #undef __FUNCT__ 1008d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 1009b96c3477SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, MatStructure reuse, Mat* B) 1010d65f70fdSStefano Zampini { 1011d65f70fdSStefano Zampini Mat *work_mat; 1012d65f70fdSStefano Zampini IS isrow_s,iscol_s; 1013d65f70fdSStefano Zampini PetscBool rsorted,csorted; 1014d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 1015d65f70fdSStefano Zampini PetscErrorCode ierr; 1016d65f70fdSStefano Zampini 1017d65f70fdSStefano Zampini PetscFunctionBegin; 1018d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 1019d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 1020d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 1021d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 1022d65f70fdSStefano Zampini 1023d65f70fdSStefano Zampini if (!rsorted) { 1024d65f70fdSStefano Zampini const PetscInt *idxs; 1025d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1026d65f70fdSStefano Zampini 1027d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 1028d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 1029d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1030d65f70fdSStefano Zampini idxs_perm_r[i] = i; 1031d65f70fdSStefano Zampini } 1032d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 1033d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 1034d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1035d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 1036d65f70fdSStefano Zampini } 1037d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 1038d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 1039d65f70fdSStefano Zampini } else { 1040d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 1041d65f70fdSStefano Zampini isrow_s = isrow; 1042d65f70fdSStefano Zampini } 1043d65f70fdSStefano Zampini 1044d65f70fdSStefano Zampini if (!csorted) { 1045d65f70fdSStefano Zampini if (isrow == iscol) { 1046d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 1047d65f70fdSStefano Zampini iscol_s = isrow_s; 1048d65f70fdSStefano Zampini } else { 1049d65f70fdSStefano Zampini const PetscInt *idxs; 1050d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1051d65f70fdSStefano Zampini 1052d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 1053d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 1054d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1055d65f70fdSStefano Zampini idxs_perm_c[i] = i; 1056d65f70fdSStefano Zampini } 1057d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 1058d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 1059d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1060d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 1061d65f70fdSStefano Zampini } 1062d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 1063d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 1064d65f70fdSStefano Zampini } 1065d65f70fdSStefano Zampini } else { 1066d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 1067d65f70fdSStefano Zampini iscol_s = iscol; 1068d65f70fdSStefano Zampini } 1069d65f70fdSStefano Zampini 1070b96c3477SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,reuse,&work_mat);CHKERRQ(ierr); 1071d65f70fdSStefano Zampini 1072d65f70fdSStefano Zampini if (!rsorted || !csorted) { 1073d65f70fdSStefano Zampini Mat new_mat; 1074d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 1075d65f70fdSStefano Zampini 1076d65f70fdSStefano Zampini if (!rsorted) { 1077d65f70fdSStefano Zampini PetscInt *idxs_r,i; 1078d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 1079d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1080d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 1081d65f70fdSStefano Zampini } 1082d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 1083d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 1084d65f70fdSStefano Zampini } else { 1085d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 1086d65f70fdSStefano Zampini } 1087d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 1088d65f70fdSStefano Zampini 1089d65f70fdSStefano Zampini if (!csorted) { 1090d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 1091d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 1092d65f70fdSStefano Zampini is_perm_c = is_perm_r; 1093d65f70fdSStefano Zampini } else { 1094d65f70fdSStefano Zampini PetscInt *idxs_c,i; 1095d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 1096d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1097d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 1098d65f70fdSStefano Zampini } 1099d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 1100d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 1101d65f70fdSStefano Zampini } 1102d65f70fdSStefano Zampini } else { 1103d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 1104d65f70fdSStefano Zampini } 1105d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 1106d65f70fdSStefano Zampini 1107d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 1108d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 1109d65f70fdSStefano Zampini work_mat[0] = new_mat; 1110d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 1111d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 1112d65f70fdSStefano Zampini } 1113d65f70fdSStefano Zampini 1114d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 1115d65f70fdSStefano Zampini *B = work_mat[0]; 1116d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 1117d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 1118d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 1119d65f70fdSStefano Zampini PetscFunctionReturn(0); 1120d65f70fdSStefano Zampini } 1121d65f70fdSStefano Zampini 1122d65f70fdSStefano Zampini #undef __FUNCT__ 11235e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 11245e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 1125aa0d41d4SStefano Zampini { 1126aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 11275e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1128d65f70fdSStefano Zampini Mat new_mat; 11295e8657edSStefano Zampini IS is_local,is_global; 1130d65f70fdSStefano Zampini PetscInt local_size; 1131d65f70fdSStefano Zampini PetscBool isseqaij; 1132aa0d41d4SStefano Zampini PetscErrorCode ierr; 1133aa0d41d4SStefano Zampini 1134aa0d41d4SStefano Zampini PetscFunctionBegin; 1135aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 11365e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 11375e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 1138906d46d4SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(matis->mapping,is_local,&is_global);CHKERRQ(ierr); 1139906d46d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 1140b96c3477SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,MAT_INITIAL_MATRIX,&new_mat);CHKERRQ(ierr); 1141906d46d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 1142906d46d4SStefano Zampini 1143906d46d4SStefano Zampini /* check */ 1144906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 1145906d46d4SStefano Zampini Vec x,x_change; 1146906d46d4SStefano Zampini PetscReal error; 1147906d46d4SStefano Zampini 11485e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 1149906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 11505e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 11515e8657edSStefano Zampini ierr = VecScatterBegin(matis->ctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11525e8657edSStefano Zampini ierr = VecScatterEnd(matis->ctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1153d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 11545e8657edSStefano Zampini ierr = VecScatterBegin(matis->ctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11555e8657edSStefano Zampini ierr = VecScatterEnd(matis->ctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1156906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 1157906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 1158906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1159906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 1160906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 1161906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 1162906d46d4SStefano Zampini } 1163906d46d4SStefano Zampini 116422d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 11659b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 116622d5777bSStefano Zampini if (isseqaij) { 1167d65f70fdSStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 1168aa0d41d4SStefano Zampini } else { 1169aa0d41d4SStefano Zampini Mat work_mat; 1170aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1171d65f70fdSStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 1172aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 1173aa0d41d4SStefano Zampini } 1174d65f70fdSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,pcbddc->issym);CHKERRQ(ierr); 117545a1bb75SStefano Zampini /* 117645a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1177d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 117845a1bb75SStefano Zampini */ 1179d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 1180aa0d41d4SStefano Zampini PetscFunctionReturn(0); 1181aa0d41d4SStefano Zampini } 1182aa0d41d4SStefano Zampini 1183aa0d41d4SStefano Zampini #undef __FUNCT__ 1184a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 11858ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 1186a64d13efSStefano Zampini { 1187a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1188a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 11898ce42a96SStefano Zampini IS is_aux1,is_aux2; 1190e9189074SStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 11913a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 11923a50541eSStefano Zampini PetscInt vbs,bs; 11934641a718SStefano Zampini PetscBT bitmask; 1194a64d13efSStefano Zampini PetscErrorCode ierr; 1195a64d13efSStefano Zampini 1196a64d13efSStefano Zampini PetscFunctionBegin; 1197b23d619eSStefano Zampini /* 1198b23d619eSStefano Zampini No need to setup local scatters if 1199b23d619eSStefano Zampini - primal space is unchanged 1200b23d619eSStefano Zampini AND 1201b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 1202b23d619eSStefano Zampini AND 1203b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 1204b23d619eSStefano Zampini */ 1205b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 1206f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 1207f4ddd8eeSStefano Zampini } 1208f4ddd8eeSStefano Zampini /* destroy old objects */ 1209f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1210f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1211f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1212a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 1213a64d13efSStefano Zampini n_B = pcis->n_B; n_D = pcis->n - n_B; 1214e9189074SStefano Zampini n_vertices = pcbddc->n_actual_vertices; 12154641a718SStefano Zampini /* create auxiliary bitmask */ 12164641a718SStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 12174641a718SStefano Zampini for (i=0;i<n_vertices;i++) { 1218e9189074SStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->primal_indices_local_idxs[i]);CHKERRQ(ierr); 12194641a718SStefano Zampini } 12203a50541eSStefano Zampini 1221a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 1222854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 1223a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 12244641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 1225a64d13efSStefano Zampini idx_R_local[n_R] = i; 1226a64d13efSStefano Zampini n_R++; 1227a64d13efSStefano Zampini } 1228a64d13efSStefano Zampini } 12293a50541eSStefano Zampini 12303a50541eSStefano Zampini /* Block code */ 12313a50541eSStefano Zampini vbs = 1; 12323a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 12333a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 12343a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 12353a50541eSStefano Zampini PetscInt *vary; 12363a50541eSStefano Zampini /* Verify if the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 1237785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 12383a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 1239e9189074SStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->primal_indices_local_idxs[i]/bs]++; 12403a50541eSStefano Zampini for (i=0; i<n_vertices; i++) { 12413a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 12423a50541eSStefano Zampini is_blocked = PETSC_FALSE; 12433a50541eSStefano Zampini break; 12443a50541eSStefano Zampini } 12453a50541eSStefano Zampini } 12463a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 12473a50541eSStefano Zampini vbs = bs; 12483a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 12493a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 12503a50541eSStefano Zampini } 12513a50541eSStefano Zampini } 12523a50541eSStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 12533a50541eSStefano Zampini } 12543a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 12553a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 1256a64d13efSStefano Zampini 1257a64d13efSStefano Zampini /* print some info if requested */ 1258a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 1259a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1260a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 12610fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1262a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 1263a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 12643a50541eSStefano 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->local_primal_size);CHKERRQ(ierr); 1265a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"pcbddc->n_vertices = %d, pcbddc->n_constraints = %d\n",pcbddc->n_vertices,pcbddc->n_constraints);CHKERRQ(ierr); 1266a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1267a64d13efSStefano Zampini } 1268a64d13efSStefano Zampini 1269a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 12703a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1271854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 1272854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 1273a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12744641a718SStefano Zampini for (i=0; i<n_D; i++) { 12754641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 12764641a718SStefano Zampini } 1277a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1278a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 12794641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 12804641a718SStefano Zampini aux_array1[j++] = i; 1281a64d13efSStefano Zampini } 1282a64d13efSStefano Zampini } 1283a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1284a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1285a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 12864641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 12874641a718SStefano Zampini aux_array2[j++] = i; 1288a64d13efSStefano Zampini } 1289a64d13efSStefano Zampini } 1290a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1291a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 1292a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 1293a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1294a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 1295a64d13efSStefano Zampini 12968eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1297785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 1298a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 12994641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 13004641a718SStefano Zampini aux_array1[j++] = i; 1301a64d13efSStefano Zampini } 1302a64d13efSStefano Zampini } 1303a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1304a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 1305a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1306a64d13efSStefano Zampini } 13074641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 13083a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1309a64d13efSStefano Zampini PetscFunctionReturn(0); 1310a64d13efSStefano Zampini } 1311a64d13efSStefano Zampini 1312304d26faSStefano Zampini 1313304d26faSStefano Zampini #undef __FUNCT__ 1314304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 1315684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 1316304d26faSStefano Zampini { 1317304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1318304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1319304d26faSStefano Zampini PC pc_temp; 1320304d26faSStefano Zampini Mat A_RR; 1321f4ddd8eeSStefano Zampini MatReuse reuse; 1322304d26faSStefano Zampini PetscScalar m_one = -1.0; 1323304d26faSStefano Zampini PetscReal value; 1324af732b37SStefano Zampini PetscInt n_D,n_R,ibs,mbs; 13259577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 1326304d26faSStefano Zampini PetscErrorCode ierr; 1327e604994aSStefano Zampini /* prefixes stuff */ 1328312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 1329e604994aSStefano Zampini size_t len; 1330304d26faSStefano Zampini 1331304d26faSStefano Zampini PetscFunctionBegin; 1332304d26faSStefano Zampini 1333e604994aSStefano Zampini /* compute prefixes */ 1334e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 1335e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 1336e604994aSStefano Zampini if (!pcbddc->current_level) { 1337e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1338e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1339e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1340e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1341e604994aSStefano Zampini } else { 1342e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 1343312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 1344e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 1345e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 1346312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 1347312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 134834d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 134934d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 1350e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1351e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1352e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 1353e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 1354e604994aSStefano Zampini } 1355e604994aSStefano Zampini 1356304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 1357684f6988SStefano Zampini if (dirichlet) { 1358ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 13598ce42a96SStefano Zampini ierr = ISGetSize(pcis->is_I_local,&n_D);CHKERRQ(ierr); 1360304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 1361304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 1362304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 1363304d26faSStefano Zampini /* default */ 1364304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1365e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 13669577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1367304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 13689577ea80SStefano Zampini if (issbaij) { 13699577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 13709577ea80SStefano Zampini } else { 1371304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 13729577ea80SStefano Zampini } 1373304d26faSStefano Zampini /* Allow user's customization */ 1374304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 1375304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1376304d26faSStefano Zampini } 1377d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 1378304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1379304d26faSStefano Zampini if (!n_D) { 1380304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 1381304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1382304d26faSStefano Zampini } 1383304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 1384304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 1385304d26faSStefano Zampini /* set ksp_D into pcis data */ 1386304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 1387304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 1388304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 1389684f6988SStefano Zampini } 1390304d26faSStefano Zampini 1391304d26faSStefano Zampini /* NEUMANN PROBLEM */ 1392684f6988SStefano Zampini A_RR = 0; 1393684f6988SStefano Zampini if (neumann) { 1394f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 13958ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 1396f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 1397f4ddd8eeSStefano Zampini PetscInt nn_R; 139881d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 1399f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 1400f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 1401f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 1402f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 1403f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1404f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1405f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 1406727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 1407f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1408f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1409f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 1410f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 1411f4ddd8eeSStefano Zampini } 1412f4ddd8eeSStefano Zampini } 1413f4ddd8eeSStefano Zampini /* last check */ 1414d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 1415f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1416f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1417f4ddd8eeSStefano Zampini } 1418f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 1419f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1420f4ddd8eeSStefano Zampini } 1421f4ddd8eeSStefano Zampini /* extract A_RR */ 1422af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 1423af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 14243a50541eSStefano Zampini if (ibs != mbs) { 1425af732b37SStefano Zampini Mat newmat; 1426af732b37SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 1427f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(newmat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 1428af732b37SStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 1429af732b37SStefano Zampini } else { 1430f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 1431af732b37SStefano Zampini } 1432f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 1433304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 1434304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 1435304d26faSStefano Zampini /* default */ 1436304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1437e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 1438304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 14399577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 14409577ea80SStefano Zampini if (issbaij) { 14419577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 14429577ea80SStefano Zampini } else { 1443304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 14449577ea80SStefano Zampini } 1445304d26faSStefano Zampini /* Allow user's customization */ 1446304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 1447304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1448304d26faSStefano Zampini } 1449d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 1450304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1451304d26faSStefano Zampini if (!n_R) { 1452304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 1453304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1454304d26faSStefano Zampini } 1455304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 1456304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1457684f6988SStefano Zampini } 1458304d26faSStefano Zampini 1459304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 14600fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 1461684f6988SStefano Zampini if (pcbddc->dbg_flag) { 1462684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1463684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1464684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1465684f6988SStefano Zampini } 1466684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 14670fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 14680fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 14690fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 14700fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 14710fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 1472304d26faSStefano Zampini /* need to be adapted? */ 1473b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 1474b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1475b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 1476304d26faSStefano Zampini /* print info */ 1477304d26faSStefano Zampini if (pcbddc->dbg_flag) { 1478e604994aSStefano 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); 1479304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1480304d26faSStefano Zampini } 1481b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 14828ce42a96SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,pcis->is_I_local);CHKERRQ(ierr); 1483304d26faSStefano Zampini } 1484684f6988SStefano Zampini } 1485684f6988SStefano Zampini if (neumann) { /* Neumann */ 14860fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 14870fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 14880fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 14890fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 14900fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 1491304d26faSStefano Zampini /* need to be adapted? */ 1492b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 1493b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1494304d26faSStefano Zampini /* print info */ 1495304d26faSStefano Zampini if (pcbddc->dbg_flag) { 1496e604994aSStefano 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); 1497304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1498304d26faSStefano Zampini } 1499b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 15008ce42a96SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,pcbddc->is_R_local);CHKERRQ(ierr); 1501304d26faSStefano Zampini } 15020fccc4e9SStefano Zampini } 1503684f6988SStefano Zampini } 1504304d26faSStefano Zampini /* free Neumann problem's matrix */ 1505304d26faSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1506304d26faSStefano Zampini PetscFunctionReturn(0); 1507304d26faSStefano Zampini } 1508304d26faSStefano Zampini 1509304d26faSStefano Zampini #undef __FUNCT__ 1510ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 151120c7b377SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec rhs, Vec sol, Vec work, PetscBool applytranspose) 1512674ae819SStefano Zampini { 1513674ae819SStefano Zampini PetscErrorCode ierr; 1514674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 1515674ae819SStefano Zampini 1516674ae819SStefano Zampini PetscFunctionBegin; 151720c7b377SStefano Zampini if (applytranspose) { 1518674ae819SStefano Zampini if (pcbddc->local_auxmat1) { 151920c7b377SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,rhs,work);CHKERRQ(ierr); 152020c7b377SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,work,rhs,rhs);CHKERRQ(ierr); 152120c7b377SStefano Zampini } 152220c7b377SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,rhs,sol);CHKERRQ(ierr); 152320c7b377SStefano Zampini } else { 152420c7b377SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,rhs,sol);CHKERRQ(ierr); 152520c7b377SStefano Zampini if (pcbddc->local_auxmat1) { 152620c7b377SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,sol,work);CHKERRQ(ierr); 152720c7b377SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,work,sol,sol);CHKERRQ(ierr); 152820c7b377SStefano Zampini } 1529674ae819SStefano Zampini } 1530674ae819SStefano Zampini PetscFunctionReturn(0); 1531674ae819SStefano Zampini } 1532674ae819SStefano Zampini 1533dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 1534674ae819SStefano Zampini #undef __FUNCT__ 1535674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 1536dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 1537674ae819SStefano Zampini { 1538674ae819SStefano Zampini PetscErrorCode ierr; 1539674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 1540674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 1541674ae819SStefano Zampini const PetscScalar zero = 0.0; 1542674ae819SStefano Zampini 1543674ae819SStefano Zampini PetscFunctionBegin; 1544dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 1545dc359a40SStefano Zampini if (applytranspose) { 1546674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 15478eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 1548dc359a40SStefano Zampini } else { 1549674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 1550674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 155115aaf578SStefano Zampini } 155212edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 155312edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 155412edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155612edc857SStefano Zampini 15579f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 155812edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 155912edc857SStefano Zampini if (pcbddc->coarse_ksp) { 156012edc857SStefano Zampini if (applytranspose) { 156112edc857SStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,NULL,NULL);CHKERRQ(ierr); 156212edc857SStefano Zampini } else { 156312edc857SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,NULL,NULL);CHKERRQ(ierr); 156412edc857SStefano Zampini } 156512edc857SStefano Zampini } 1566674ae819SStefano Zampini 1567674ae819SStefano Zampini /* Local solution on R nodes */ 15689f00e9b4SStefano Zampini if (pcis->n) { 1569674ae819SStefano Zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 1570674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1571674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15728eeda7d8SStefano Zampini if (pcbddc->switch_static) { 1573674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1574674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1575674ae819SStefano Zampini } 157620c7b377SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcbddc->vec1_R,pcbddc->vec2_R,pcbddc->vec1_C,applytranspose);CHKERRQ(ierr); 1577674ae819SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1578674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1579674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15808eeda7d8SStefano Zampini if (pcbddc->switch_static) { 1581674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1582674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1583674ae819SStefano Zampini } 15849f00e9b4SStefano Zampini } 1585674ae819SStefano Zampini 15869f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 15879f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 158812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1589674ae819SStefano Zampini 1590674ae819SStefano Zampini /* Sum contributions from two levels */ 1591dc359a40SStefano Zampini if (applytranspose) { 1592dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 1593dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1594dc359a40SStefano Zampini } else { 1595674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 15968eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1597dc359a40SStefano Zampini } 1598674ae819SStefano Zampini PetscFunctionReturn(0); 1599674ae819SStefano Zampini } 1600674ae819SStefano Zampini 160112edc857SStefano Zampini /* TODO: the following two function can be optimized using VecPlaceArray whenever possible and using overlap flag */ 1602674ae819SStefano Zampini #undef __FUNCT__ 1603674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 160412edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 1605674ae819SStefano Zampini { 1606674ae819SStefano Zampini PetscErrorCode ierr; 1607674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 160812edc857SStefano Zampini PetscScalar *array,*array2; 160912edc857SStefano Zampini Vec from,to; 1610674ae819SStefano Zampini 1611674ae819SStefano Zampini PetscFunctionBegin; 161212edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 161312edc857SStefano Zampini from = pcbddc->coarse_vec; 161412edc857SStefano Zampini to = pcbddc->vec1_P; 161512edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 161612edc857SStefano Zampini Vec tvec; 161712edc857SStefano Zampini PetscInt lsize; 161812edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 161912edc857SStefano Zampini ierr = VecGetLocalSize(tvec,&lsize);CHKERRQ(ierr); 162012edc857SStefano Zampini ierr = VecGetArrayRead(tvec,(const PetscScalar**)&array);CHKERRQ(ierr); 162112edc857SStefano Zampini ierr = VecGetArray(from,&array2);CHKERRQ(ierr); 162212edc857SStefano Zampini ierr = PetscMemcpy(array2,array,lsize*sizeof(PetscScalar));CHKERRQ(ierr); 162312edc857SStefano Zampini ierr = VecRestoreArrayRead(tvec,(const PetscScalar**)&array);CHKERRQ(ierr); 162412edc857SStefano Zampini ierr = VecRestoreArray(from,&array2);CHKERRQ(ierr); 162512edc857SStefano Zampini } 162612edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 162712edc857SStefano Zampini from = pcbddc->vec1_P; 162812edc857SStefano Zampini to = pcbddc->coarse_vec; 162912edc857SStefano Zampini } 163012edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 1631674ae819SStefano Zampini PetscFunctionReturn(0); 1632674ae819SStefano Zampini } 1633674ae819SStefano Zampini 1634674ae819SStefano Zampini #undef __FUNCT__ 1635674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 163612edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 1637674ae819SStefano Zampini { 1638674ae819SStefano Zampini PetscErrorCode ierr; 1639674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 164012edc857SStefano Zampini PetscScalar *array,*array2; 164112edc857SStefano Zampini Vec from,to; 1642674ae819SStefano Zampini 1643674ae819SStefano Zampini PetscFunctionBegin; 164412edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 164512edc857SStefano Zampini from = pcbddc->coarse_vec; 164612edc857SStefano Zampini to = pcbddc->vec1_P; 164712edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 164812edc857SStefano Zampini from = pcbddc->vec1_P; 164912edc857SStefano Zampini to = pcbddc->coarse_vec; 165012edc857SStefano Zampini } 165112edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 165212edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 165312edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 165412edc857SStefano Zampini Vec tvec; 165512edc857SStefano Zampini PetscInt lsize; 165612edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 165712edc857SStefano Zampini ierr = VecGetLocalSize(tvec,&lsize);CHKERRQ(ierr); 165812edc857SStefano Zampini ierr = VecGetArrayRead(to,(const PetscScalar**)&array);CHKERRQ(ierr); 165912edc857SStefano Zampini ierr = VecGetArray(tvec,&array2);CHKERRQ(ierr); 166012edc857SStefano Zampini ierr = PetscMemcpy(array2,array,lsize*sizeof(PetscScalar));CHKERRQ(ierr); 166112edc857SStefano Zampini ierr = VecRestoreArrayRead(to,(const PetscScalar**)&array);CHKERRQ(ierr); 166212edc857SStefano Zampini ierr = VecRestoreArray(tvec,&array2);CHKERRQ(ierr); 166312edc857SStefano Zampini } 166412edc857SStefano Zampini } 1665674ae819SStefano Zampini PetscFunctionReturn(0); 1666674ae819SStefano Zampini } 1667674ae819SStefano Zampini 1668984c4197SStefano Zampini /* uncomment for testing purposes */ 1669984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 1670674ae819SStefano Zampini #undef __FUNCT__ 1671674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 1672674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 1673674ae819SStefano Zampini { 1674674ae819SStefano Zampini PetscErrorCode ierr; 1675674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1676674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1677674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 1678984c4197SStefano Zampini /* constraint and (optionally) change of basis matrix implemented as SeqAIJ */ 1679674ae819SStefano Zampini MatType impMatType=MATSEQAIJ; 1680984c4197SStefano Zampini /* one and zero */ 1681984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 1682984c4197SStefano Zampini /* space to store constraints and their local indices */ 1683984c4197SStefano Zampini PetscScalar *temp_quadrature_constraint; 1684984c4197SStefano Zampini PetscInt *temp_indices,*temp_indices_to_constraint,*temp_indices_to_constraint_B; 1685984c4197SStefano Zampini /* iterators */ 1686984c4197SStefano Zampini PetscInt i,j,k,total_counts,temp_start_ptr; 1687984c4197SStefano Zampini /* stuff to store connected components stored in pcbddc->mat_graph */ 1688984c4197SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges,*used_IS; 1689984c4197SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges; 1690984c4197SStefano Zampini /* near null space stuff */ 1691674ae819SStefano Zampini MatNullSpace nearnullsp; 1692674ae819SStefano Zampini const Vec *nearnullvecs; 1693674ae819SStefano Zampini Vec *localnearnullsp; 1694984c4197SStefano Zampini PetscBool nnsp_has_cnst; 1695984c4197SStefano Zampini PetscInt nnsp_size; 1696984c4197SStefano Zampini PetscScalar *array; 1697984c4197SStefano Zampini /* BLAS integers */ 1698e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 1699e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 1700c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 1701984c4197SStefano Zampini /* LAPACK working arrays for SVD or POD */ 1702242a89d7SStefano Zampini PetscBool skip_lapack; 1703984c4197SStefano Zampini PetscScalar *work; 1704984c4197SStefano Zampini PetscReal *singular_vals; 1705984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1706984c4197SStefano Zampini PetscReal *rwork; 1707674ae819SStefano Zampini #endif 1708984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1709e310c8b4SStefano Zampini PetscBLASInt Blas_one_2=1; 1710984c4197SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 1711b7d8b9f8SStefano Zampini #else 1712b7d8b9f8SStefano Zampini PetscBLASInt dummy_int_1=1,dummy_int_2=1; 1713b7d8b9f8SStefano Zampini PetscScalar dummy_scalar_1=0.0,dummy_scalar_2=0.0; 1714984c4197SStefano Zampini #endif 1715727cdba6SStefano Zampini /* reuse */ 1716727cdba6SStefano Zampini PetscInt olocal_primal_size; 1717727cdba6SStefano Zampini PetscInt *oprimal_indices_local_idxs; 1718984c4197SStefano Zampini /* change of basis */ 1719984c4197SStefano Zampini PetscInt *aux_primal_numbering,*aux_primal_minloc,*global_indices; 1720a717540cSStefano Zampini PetscBool boolforchange,qr_needed; 1721a717540cSStefano Zampini PetscBT touched,change_basis,qr_needed_idx; 1722984c4197SStefano Zampini /* auxiliary stuff */ 172339e2fb2aSStefano Zampini PetscInt *nnz,*is_indices,*aux_primal_numbering_B; 1724911cabfeSStefano Zampini PetscInt ncc,*gidxs,*permutation,*temp_indices_to_constraint_work; 1725911cabfeSStefano Zampini PetscScalar *temp_quadrature_constraint_work; 1726984c4197SStefano Zampini /* some quantities */ 172745a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 1728984c4197SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint,max_constraints,temp_constraints; 1729984c4197SStefano Zampini 1730674ae819SStefano Zampini 1731674ae819SStefano Zampini PetscFunctionBegin; 17328e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 17338e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 17348e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 173508122e43SStefano Zampini /* TODO synch with adaptive selection */ 1736674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 1737d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 1738d06fc5fdSStefano Zampini /* free unneeded index sets */ 1739d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 1740d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 1741674ae819SStefano Zampini } 1742d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 1743d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 1744d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 1745d06fc5fdSStefano Zampini } 1746d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 1747d06fc5fdSStefano Zampini n_ISForEdges = 0; 1748d06fc5fdSStefano Zampini } 1749d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 1750d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 1751d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 1752d06fc5fdSStefano Zampini } 1753d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 1754d06fc5fdSStefano Zampini n_ISForFaces = 0; 1755d06fc5fdSStefano Zampini } 1756d06fc5fdSStefano Zampini /* HACKS (the following two blocks of code) */ 1757b9b85e73SStefano Zampini if (!ISForVertices && pcbddc->NullSpace && !pcbddc->user_ChangeOfBasisMatrix) { 1758b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 1759d06fc5fdSStefano Zampini if (!ISForEdges) { 1760d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 1761d06fc5fdSStefano Zampini } 1762b8ffe317SStefano Zampini } 176398a51de6SStefano Zampini if (pcbddc->NullSpace) { 176498a51de6SStefano Zampini /* use_change_of_basis should be consistent among processors */ 1765d06fc5fdSStefano Zampini PetscBool tbool[2],gbool[2]; 1766d06fc5fdSStefano Zampini tbool [0] = pcbddc->use_change_of_basis; 1767d06fc5fdSStefano Zampini tbool [1] = pcbddc->use_change_on_faces; 1768d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1769d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 1770d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 177198a51de6SStefano Zampini } 1772984c4197SStefano Zampini /* print some info */ 1773674ae819SStefano Zampini if (pcbddc->dbg_flag) { 17740fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1775674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 1776674ae819SStefano Zampini i = 0; 1777674ae819SStefano Zampini if (ISForVertices) { 1778674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&i);CHKERRQ(ierr); 1779674ae819SStefano Zampini } 1780674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices\n",PetscGlobalRank,i);CHKERRQ(ierr); 1781674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges\n",PetscGlobalRank,n_ISForEdges);CHKERRQ(ierr); 178215aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces\n",PetscGlobalRank,n_ISForFaces);CHKERRQ(ierr); 1783674ae819SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1784674ae819SStefano Zampini } 178508122e43SStefano Zampini 178608122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 1787674ae819SStefano Zampini /* check if near null space is attached to global mat */ 1788674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 1789674ae819SStefano Zampini if (nearnullsp) { 1790674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1791f4ddd8eeSStefano Zampini /* remove any stored info */ 1792f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1793f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1794f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 1795f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 1796f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 1797473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1798f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1799f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 1800f4ddd8eeSStefano Zampini } 1801984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 1802984c4197SStefano Zampini nnsp_size = 0; 1803674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 1804674ae819SStefano Zampini } 1805984c4197SStefano Zampini /* get max number of constraints on a single cc */ 1806984c4197SStefano Zampini max_constraints = nnsp_size; 1807984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 1808984c4197SStefano Zampini 1809674ae819SStefano Zampini /* 1810674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 1811674ae819SStefano Zampini - temp_indices will contain start index of each constraint stored as follows 1812911cabfeSStefano Zampini - temp_indices_to_constraint [temp_indices[i],...,temp_indices[i+1]-1] will contain the indices (in local numbering) on which the constraint acts 1813911cabfeSStefano Zampini - temp_indices_to_constraint_B[temp_indices[i],...,temp_indices[i+1]-1] will contain the indices (in boundary numbering) on which the constraint acts 1814911cabfeSStefano Zampini - temp_quadrature_constraint [temp_indices[i],...,temp_indices[i+1]-1] will contain the scalars representing the constraint itself 1815674ae819SStefano Zampini */ 1816674ae819SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 1817984c4197SStefano Zampini total_counts *= max_constraints; 1818674ae819SStefano Zampini n_vertices = 0; 1819674ae819SStefano Zampini if (ISForVertices) { 1820674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 1821674ae819SStefano Zampini } 1822674ae819SStefano Zampini total_counts += n_vertices; 1823854ce69bSBarry Smith ierr = PetscMalloc1(total_counts+1,&temp_indices);CHKERRQ(ierr); 18244641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 1825674ae819SStefano Zampini total_counts = 0; 1826674ae819SStefano Zampini max_size_of_constraint = 0; 1827674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 1828674ae819SStefano Zampini if (i<n_ISForEdges) { 1829674ae819SStefano Zampini used_IS = &ISForEdges[i]; 1830674ae819SStefano Zampini } else { 1831674ae819SStefano Zampini used_IS = &ISForFaces[i-n_ISForEdges]; 1832674ae819SStefano Zampini } 1833674ae819SStefano Zampini ierr = ISGetSize(*used_IS,&j);CHKERRQ(ierr); 1834674ae819SStefano Zampini total_counts += j; 1835674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 1836674ae819SStefano Zampini } 1837984c4197SStefano Zampini total_counts *= max_constraints; 1838674ae819SStefano Zampini total_counts += n_vertices; 1839906d46d4SStefano Zampini ierr = PetscMalloc3(total_counts,&temp_quadrature_constraint,total_counts,&temp_indices_to_constraint,total_counts,&temp_indices_to_constraint_B);CHKERRQ(ierr); 1840984c4197SStefano Zampini /* get local part of global near null space vectors */ 1841785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 1842984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 1843984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 1844984c4197SStefano Zampini ierr = VecScatterBegin(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1845984c4197SStefano Zampini ierr = VecScatterEnd(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1846984c4197SStefano Zampini } 1847674ae819SStefano Zampini 1848242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 1849242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 1850a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 1851242a89d7SStefano Zampini 18528f1c130eSStefano Zampini /* allocate some auxiliary stuff */ 18538f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 18548f1c130eSStefano Zampini ierr = PetscMalloc4(max_size_of_constraint,&gidxs,max_size_of_constraint,&permutation,max_size_of_constraint,&temp_indices_to_constraint_work,max_size_of_constraint,&temp_quadrature_constraint_work);CHKERRQ(ierr); 18558f1c130eSStefano Zampini } 18568f1c130eSStefano Zampini 1857984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 1858a773dcb8SStefano Zampini if (!skip_lapack) { 1859674ae819SStefano Zampini PetscScalar temp_work; 1860911cabfeSStefano Zampini 1861674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1862984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 1863785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 1864785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 1865785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 1866674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1867785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 1868674ae819SStefano Zampini #endif 1869674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 1870c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 1871c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 1872674ae819SStefano Zampini lwork = -1; 1873674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1874674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1875c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 1876674ae819SStefano Zampini #else 1877c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 1878674ae819SStefano Zampini #endif 1879674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1880984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 1881674ae819SStefano Zampini #else /* on missing GESVD */ 1882674ae819SStefano Zampini /* SVD */ 1883674ae819SStefano Zampini PetscInt max_n,min_n; 1884674ae819SStefano Zampini max_n = max_size_of_constraint; 1885984c4197SStefano Zampini min_n = max_constraints; 1886984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 1887674ae819SStefano Zampini min_n = max_size_of_constraint; 1888984c4197SStefano Zampini max_n = max_constraints; 1889674ae819SStefano Zampini } 1890785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 1891674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1892785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 1893674ae819SStefano Zampini #endif 1894674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 1895674ae819SStefano Zampini lwork = -1; 1896e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 1897e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 1898b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 1899674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1900674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1901e310c8b4SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&temp_quadrature_constraint[0],&Blas_LDA,singular_vals,&dummy_scalar_1,&dummy_int_1,&dummy_scalar_2,&dummy_int_2,&temp_work,&lwork,&lierr)); 1902674ae819SStefano Zampini #else 1903e310c8b4SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&temp_quadrature_constraint[0],&Blas_LDA,singular_vals,&dummy_scalar_1,&dummy_int_1,&dummy_scalar_2,&dummy_int_2,&temp_work,&lwork,rwork,&lierr)); 1904674ae819SStefano Zampini #endif 1905674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1906984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 1907984c4197SStefano Zampini #endif /* on missing GESVD */ 1908674ae819SStefano Zampini /* Allocate optimal workspace */ 1909674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 1910854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 1911674ae819SStefano Zampini } 1912674ae819SStefano Zampini /* Now we can loop on constraining sets */ 1913674ae819SStefano Zampini total_counts = 0; 1914674ae819SStefano Zampini temp_indices[0] = 0; 1915674ae819SStefano Zampini /* vertices */ 1916674ae819SStefano Zampini if (ISForVertices) { 1917674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1918674ae819SStefano Zampini if (nnsp_has_cnst) { /* consider all vertices */ 191939e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 1920674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 1921674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1922674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1923674ae819SStefano Zampini total_counts++; 1924674ae819SStefano Zampini } 1925674ae819SStefano Zampini } else { /* consider vertices for which exist at least a localnearnullsp which is not null there */ 1926984c4197SStefano Zampini PetscBool used_vertex; 1927674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 1928674ae819SStefano Zampini used_vertex = PETSC_FALSE; 1929674ae819SStefano Zampini k = 0; 1930674ae819SStefano Zampini while (!used_vertex && k<nnsp_size) { 1931984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 1932984c4197SStefano Zampini if (PetscAbsScalar(array[is_indices[i]])>0.0) { 1933674ae819SStefano Zampini temp_indices_to_constraint[temp_indices[total_counts]]=is_indices[i]; 1934674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1935674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1936674ae819SStefano Zampini total_counts++; 1937674ae819SStefano Zampini used_vertex = PETSC_TRUE; 1938674ae819SStefano Zampini } 1939984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 1940674ae819SStefano Zampini k++; 1941674ae819SStefano Zampini } 1942674ae819SStefano Zampini } 1943674ae819SStefano Zampini } 1944674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1945674ae819SStefano Zampini n_vertices = total_counts; 1946674ae819SStefano Zampini } 1947984c4197SStefano Zampini 1948674ae819SStefano Zampini /* edges and faces */ 1949911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 1950911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 1951911cabfeSStefano Zampini used_IS = &ISForEdges[ncc]; 1952984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 1953674ae819SStefano Zampini } else { 1954911cabfeSStefano Zampini used_IS = &ISForFaces[ncc-n_ISForEdges]; 1955984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 1956674ae819SStefano Zampini } 1957674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 1958674ae819SStefano Zampini temp_start_ptr = total_counts; /* need to know the starting index of constraints stored */ 1959674ae819SStefano Zampini ierr = ISGetSize(*used_IS,&size_of_constraint);CHKERRQ(ierr); 1960674ae819SStefano Zampini ierr = ISGetIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1961984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 1962984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 1963674ae819SStefano Zampini if (nnsp_has_cnst) { 19645b08dc53SStefano Zampini PetscScalar quad_value; 1965674ae819SStefano Zampini temp_constraints++; 1966a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 1967674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 1968a773dcb8SStefano Zampini } else { 1969a773dcb8SStefano Zampini quad_value = 1.0; 1970a773dcb8SStefano Zampini } 197139e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1972674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1973674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=quad_value; 1974674ae819SStefano Zampini } 197508122e43SStefano Zampini /* sort by global ordering if using lapack subroutines (not needed!) */ 19768f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 1977911cabfeSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,size_of_constraint,temp_indices_to_constraint+temp_indices[total_counts],gidxs);CHKERRQ(ierr); 1978911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 1979911cabfeSStefano Zampini permutation[j]=j; 1980911cabfeSStefano Zampini } 1981911cabfeSStefano Zampini ierr = PetscSortIntWithPermutation(size_of_constraint,gidxs,permutation);CHKERRQ(ierr); 1982911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 198308122e43SStefano Zampini if (permutation[j]!=j) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This should not happen"); 198408122e43SStefano Zampini } 198508122e43SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1986911cabfeSStefano Zampini temp_indices_to_constraint_work[j] = temp_indices_to_constraint[temp_indices[total_counts]+permutation[j]]; 1987911cabfeSStefano Zampini temp_quadrature_constraint_work[j] = temp_quadrature_constraint[temp_indices[total_counts]+permutation[j]]; 1988911cabfeSStefano Zampini } 1989911cabfeSStefano Zampini ierr = PetscMemcpy(temp_indices_to_constraint+temp_indices[total_counts],temp_indices_to_constraint_work,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1990911cabfeSStefano Zampini ierr = PetscMemcpy(temp_quadrature_constraint+temp_indices[total_counts],temp_quadrature_constraint_work,size_of_constraint*sizeof(PetscScalar));CHKERRQ(ierr); 1991911cabfeSStefano Zampini } 1992674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 1993674ae819SStefano Zampini total_counts++; 1994674ae819SStefano Zampini } 1995674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 1996984c4197SStefano Zampini PetscReal real_value; 1997984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 199839e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1999674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 2000984c4197SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=array[is_indices[j]]; 2001674ae819SStefano Zampini } 2002984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2003984c4197SStefano Zampini /* check if array is null on the connected component */ 2004e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2005e310c8b4SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,&temp_quadrature_constraint[temp_indices[total_counts]],&Blas_one)); 20065b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 2007911cabfeSStefano Zampini /* sort by global ordering if using lapack subroutines */ 20088f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 2009911cabfeSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,size_of_constraint,temp_indices_to_constraint+temp_indices[total_counts],gidxs);CHKERRQ(ierr); 2010911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 2011911cabfeSStefano Zampini permutation[j]=j; 2012911cabfeSStefano Zampini } 2013911cabfeSStefano Zampini ierr = PetscSortIntWithPermutation(size_of_constraint,gidxs,permutation);CHKERRQ(ierr); 2014911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 2015911cabfeSStefano Zampini temp_indices_to_constraint_work[j] = temp_indices_to_constraint[temp_indices[total_counts]+permutation[j]]; 2016911cabfeSStefano Zampini temp_quadrature_constraint_work[j] = temp_quadrature_constraint[temp_indices[total_counts]+permutation[j]]; 2017911cabfeSStefano Zampini } 2018911cabfeSStefano Zampini ierr = PetscMemcpy(temp_indices_to_constraint+temp_indices[total_counts],temp_indices_to_constraint_work,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 2019911cabfeSStefano Zampini ierr = PetscMemcpy(temp_quadrature_constraint+temp_indices[total_counts],temp_quadrature_constraint_work,size_of_constraint*sizeof(PetscScalar));CHKERRQ(ierr); 2020911cabfeSStefano Zampini } 2021674ae819SStefano Zampini temp_constraints++; 2022674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 2023674ae819SStefano Zampini total_counts++; 2024674ae819SStefano Zampini } 2025674ae819SStefano Zampini } 2026674ae819SStefano Zampini ierr = ISRestoreIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 202745a1bb75SStefano Zampini valid_constraints = temp_constraints; 2028eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 2029a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 2030a773dcb8SStefano Zampini PetscScalar norm; 2031a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2032a773dcb8SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,temp_quadrature_constraint+temp_indices[temp_start_ptr],&Blas_one,temp_quadrature_constraint+temp_indices[temp_start_ptr],&Blas_one)); 2033a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 2034a773dcb8SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,temp_quadrature_constraint+temp_indices[temp_start_ptr],&Blas_one)); 2035a773dcb8SStefano Zampini } else { /* perform SVD */ 2036984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 2037674ae819SStefano Zampini 2038674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2039984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 2040984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 2041984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 2042984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 2043984c4197SStefano Zampini from that computed using LAPACKgesvd 2044984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 2045984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 2046984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 2047674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 2048e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2049984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2050674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 2051674ae819SStefano Zampini for (k=0;k<j+1;k++) { 2052e310c8b4SStefano Zampini PetscStackCallBLAS("BLASdot",correlation_mat[j*temp_constraints+k]=BLASdot_(&Blas_N,&temp_quadrature_constraint[temp_indices[temp_start_ptr+k]],&Blas_one,&temp_quadrature_constraint[temp_indices[temp_start_ptr+j]],&Blas_one_2)); 2053674ae819SStefano Zampini } 2054674ae819SStefano Zampini } 2055e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 2056e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2057e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 2058674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2059c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 2060674ae819SStefano Zampini #else 2061c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 2062674ae819SStefano Zampini #endif 2063674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2064984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 2065984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 2066674ae819SStefano Zampini j = 0; 2067984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 2068674ae819SStefano Zampini total_counts = total_counts-j; 206945a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 2070e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 2071c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2072c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2073c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 2074c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2075c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 2076c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2077674ae819SStefano Zampini if (j<temp_constraints) { 2078984c4197SStefano Zampini PetscInt ii; 2079984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k]=1.0/PetscSqrtReal(singular_vals[k]); 2080674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2081c4303822SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Blas_LDA,correlation_mat,&Blas_LDB,&zero,temp_basis,&Blas_LDC)); 2082674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2083984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 2084674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 2085984c4197SStefano Zampini temp_quadrature_constraint[temp_indices[temp_start_ptr+k]+ii]=singular_vals[temp_constraints-1-k]*temp_basis[(temp_constraints-1-k)*size_of_constraint+ii]; 2086674ae819SStefano Zampini } 2087674ae819SStefano Zampini } 2088674ae819SStefano Zampini } 2089674ae819SStefano Zampini #else /* on missing GESVD */ 2090e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2091e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2092b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2093674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2094674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2095e310c8b4SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Blas_LDA,singular_vals,&dummy_scalar_1,&dummy_int_1,&dummy_scalar_2,&dummy_int_2,work,&lwork,&lierr)); 2096674ae819SStefano Zampini #else 2097e310c8b4SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&temp_quadrature_constraint[temp_indices[temp_start_ptr]],&Blas_LDA,singular_vals,&dummy_scalar_1,&dummy_int_1,&dummy_scalar_2,&dummy_int_2,work,&lwork,rwork,&lierr)); 2098674ae819SStefano Zampini #endif 2099984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 2100674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2101984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 2102e310c8b4SStefano Zampini k = temp_constraints; 2103e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 2104674ae819SStefano Zampini j = 0; 2105e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 210645a1bb75SStefano Zampini valid_constraints = k-j; 2107911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 2108984c4197SStefano Zampini #endif /* on missing GESVD */ 2109674ae819SStefano Zampini } 2110a773dcb8SStefano Zampini } 211145a1bb75SStefano Zampini /* setting change_of_basis flag is safe now */ 211245a1bb75SStefano Zampini if (boolforchange) { 211345a1bb75SStefano Zampini for (j=0;j<valid_constraints;j++) { 211445a1bb75SStefano Zampini PetscBTSet(change_basis,total_counts-j-1); 211545a1bb75SStefano Zampini } 211645a1bb75SStefano Zampini } 2117674ae819SStefano Zampini } 2118984c4197SStefano Zampini /* free workspace */ 21198f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 2120911cabfeSStefano Zampini ierr = PetscFree4(gidxs,permutation,temp_indices_to_constraint_work,temp_quadrature_constraint_work);CHKERRQ(ierr); 21218f1c130eSStefano Zampini } 21228f1c130eSStefano Zampini if (!skip_lapack) { 2123984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2124984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2125984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 2126984c4197SStefano Zampini #endif 2127984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 2128984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2129984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 2130984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 2131984c4197SStefano Zampini #endif 2132984c4197SStefano Zampini } 2133984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2134984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 2135984c4197SStefano Zampini } 2136984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 213708122e43SStefano Zampini } else { 213808122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 213908122e43SStefano Zampini PetscInt cum = 0; 214008122e43SStefano Zampini 214108122e43SStefano Zampini total_counts = 0; 214208122e43SStefano Zampini n_vertices = 0; 214308122e43SStefano Zampini if (sub_schurs->is_Ej_com) { 214408122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_Ej_com,&n_vertices);CHKERRQ(ierr); 214508122e43SStefano Zampini } 214608122e43SStefano Zampini max_constraints = 0; 214708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 214808122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 214908122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 215008122e43SStefano Zampini } 215108122e43SStefano Zampini temp_indices = pcbddc->adaptive_constraints_ptrs; 215208122e43SStefano Zampini temp_indices_to_constraint = pcbddc->adaptive_constraints_idxs; 215308122e43SStefano Zampini temp_quadrature_constraint = pcbddc->adaptive_constraints_data; 215408122e43SStefano Zampini 215508122e43SStefano Zampini #if 0 215608122e43SStefano Zampini printf("Found %d totals\n",total_counts); 215708122e43SStefano Zampini for (i=0;i<total_counts;i++) { 215808122e43SStefano Zampini printf("const %d, start %d",i,temp_indices[i]); 215908122e43SStefano Zampini printf(" end %d:\n",temp_indices[i+1]); 216008122e43SStefano Zampini for (j=temp_indices[i];j<temp_indices[i+1];j++) { 216108122e43SStefano Zampini printf(" idxs %d",temp_indices_to_constraint[j]); 216208122e43SStefano Zampini printf(" data %1.2e\n",temp_quadrature_constraint[j]); 216308122e43SStefano Zampini } 216408122e43SStefano Zampini } 216508122e43SStefano Zampini #endif 216608122e43SStefano Zampini 216708122e43SStefano Zampini for (i=0;i<total_counts;i++) max_size_of_constraint = PetscMax(max_size_of_constraint,temp_indices[i+1]-temp_indices[i]); 216808122e43SStefano Zampini ierr = PetscMalloc1(temp_indices[total_counts],&temp_indices_to_constraint_B);CHKERRQ(ierr); 216908122e43SStefano Zampini /* Change of basis */ 217008122e43SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 217108122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 2172*bbb9e6c6SStefano Zampini cum = n_vertices; 217308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 217408122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 2175*bbb9e6c6SStefano Zampini for (j=0;j<pcbddc->adaptive_constraints_n[i+n_vertices];j++) { 217608122e43SStefano Zampini ierr = PetscBTSet(change_basis,cum+j);CHKERRQ(ierr); 217708122e43SStefano Zampini } 217808122e43SStefano Zampini } 2179*bbb9e6c6SStefano Zampini cum += pcbddc->adaptive_constraints_n[i+n_vertices]; 218008122e43SStefano Zampini } 218108122e43SStefano Zampini } 218208122e43SStefano Zampini } 218308122e43SStefano Zampini 218408122e43SStefano Zampini /* free index sets of faces, edges and vertices */ 218508122e43SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 218608122e43SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 218708122e43SStefano Zampini } 218808122e43SStefano Zampini if (n_ISForFaces) { 218908122e43SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 219008122e43SStefano Zampini } 219108122e43SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 219208122e43SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 219308122e43SStefano Zampini } 219408122e43SStefano Zampini if (n_ISForEdges) { 219508122e43SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 219608122e43SStefano Zampini } 219708122e43SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 219808122e43SStefano Zampini 219908122e43SStefano Zampini /* map temp_indices_to_constraint in boundary numbering */ 220008122e43SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,temp_indices[total_counts],temp_indices_to_constraint,&i,temp_indices_to_constraint_B);CHKERRQ(ierr); 220108122e43SStefano Zampini if (i != temp_indices[total_counts]) { 220208122e43SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %d != %d\n",temp_indices[total_counts],i); 220308122e43SStefano Zampini } 2204984c4197SStefano Zampini 2205727cdba6SStefano Zampini /* set quantities in pcbddc data structure and store previous primal size */ 2206984c4197SStefano Zampini /* n_vertices defines the number of subdomain corners in the primal space */ 2207674ae819SStefano Zampini /* n_constraints defines the number of averages (they can be point primal dofs if change of basis is requested) */ 2208727cdba6SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 2209984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 2210674ae819SStefano Zampini pcbddc->n_vertices = n_vertices; 2211984c4197SStefano Zampini pcbddc->n_constraints = pcbddc->local_primal_size-pcbddc->n_vertices; 2212674ae819SStefano Zampini 2213674ae819SStefano Zampini /* Create constraint matrix */ 2214674ae819SStefano Zampini /* The constraint matrix is used to compute the l2g map of primal dofs */ 2215674ae819SStefano Zampini /* so we need to set it up properly either with or without change of basis */ 2216674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2217674ae819SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,impMatType);CHKERRQ(ierr); 2218984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 2219984c4197SStefano Zampini /* array to compute a local numbering of constraints : vertices first then constraints */ 2220785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&aux_primal_numbering);CHKERRQ(ierr); 2221984c4197SStefano Zampini /* array to select the proper local node (of minimum index with respect to global ordering) when changing the basis */ 2222984c4197SStefano Zampini /* note: it should not be needed since IS for faces and edges are already sorted by global ordering when analyzing the graph but... just in case */ 2223785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&aux_primal_minloc);CHKERRQ(ierr); 2224984c4197SStefano Zampini /* auxiliary stuff for basis change */ 2225785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint,&global_indices);CHKERRQ(ierr); 22264641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&touched);CHKERRQ(ierr); 2227984c4197SStefano Zampini 2228984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 2229984c4197SStefano Zampini total_primal_vertices=0; 2230984c4197SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2231674ae819SStefano Zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 2232984c4197SStefano Zampini if (size_of_constraint == 1) { 22334641a718SStefano Zampini ierr = PetscBTSet(touched,temp_indices_to_constraint_B[temp_indices[i]]);CHKERRQ(ierr); 2234984c4197SStefano Zampini aux_primal_numbering[total_primal_vertices]=temp_indices_to_constraint[temp_indices[i]]; 2235984c4197SStefano Zampini aux_primal_minloc[total_primal_vertices]=0; 2236984c4197SStefano Zampini total_primal_vertices++; 22374641a718SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { /* Same procedure used in PCBDDCGetPrimalConstraintsLocalIdx */ 2238984c4197SStefano Zampini PetscInt min_loc,min_index; 2239984c4197SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcbddc->mat_graph->l2gmap,size_of_constraint,&temp_indices_to_constraint[temp_indices[i]],global_indices);CHKERRQ(ierr); 2240984c4197SStefano Zampini /* find first untouched local node */ 2241674ae819SStefano Zampini k = 0; 22424641a718SStefano Zampini while (PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k])) k++; 2243984c4197SStefano Zampini min_index = global_indices[k]; 2244984c4197SStefano Zampini min_loc = k; 2245984c4197SStefano Zampini /* search the minimum among global nodes already untouched on the cc */ 2246984c4197SStefano Zampini for (k=1;k<size_of_constraint;k++) { 2247984c4197SStefano Zampini /* there can be more than one constraint on a single connected component */ 22484641a718SStefano Zampini if (!PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k]) && min_index > global_indices[k]) { 2249984c4197SStefano Zampini min_index = global_indices[k]; 2250984c4197SStefano Zampini min_loc = k; 2251674ae819SStefano Zampini } 2252674ae819SStefano Zampini } 22534641a718SStefano Zampini ierr = PetscBTSet(touched,temp_indices_to_constraint_B[temp_indices[i]+min_loc]);CHKERRQ(ierr); 2254984c4197SStefano Zampini aux_primal_numbering[total_primal_vertices]=temp_indices_to_constraint[temp_indices[i]+min_loc]; 2255984c4197SStefano Zampini aux_primal_minloc[total_primal_vertices]=min_loc; 2256984c4197SStefano Zampini total_primal_vertices++; 2257984c4197SStefano Zampini } 2258984c4197SStefano Zampini } 2259a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 2260a717540cSStefano Zampini qr_needed = PETSC_FALSE; 2261a717540cSStefano Zampini ierr = PetscBTCreate(pcbddc->local_primal_size,&qr_needed_idx);CHKERRQ(ierr); 2262a717540cSStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 2263a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 2264fa434743SStefano Zampini if (!pcbddc->use_qr_single) { 2265a717540cSStefano Zampini size_of_constraint = temp_indices[i+1]-temp_indices[i]; 2266a717540cSStefano Zampini j = 0; 2267a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 2268a717540cSStefano Zampini if (PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k])) { 2269a717540cSStefano Zampini j++; 2270a717540cSStefano Zampini } 2271a717540cSStefano Zampini } 2272a717540cSStefano Zampini /* found more than one primal dof on the cc */ 2273a717540cSStefano Zampini if (j > 1) { 2274a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 2275a717540cSStefano Zampini qr_needed = PETSC_TRUE; 2276a717540cSStefano Zampini } 2277fa434743SStefano Zampini } else { 2278fa434743SStefano Zampini PetscBTSet(qr_needed_idx,i); 2279fa434743SStefano Zampini qr_needed = PETSC_TRUE; 2280fa434743SStefano Zampini } 2281a717540cSStefano Zampini } 2282a717540cSStefano Zampini } 2283984c4197SStefano Zampini /* free workspace */ 2284984c4197SStefano Zampini ierr = PetscFree(global_indices);CHKERRQ(ierr); 228545a1bb75SStefano Zampini 2286674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 2287a717540cSStefano Zampini ierr = PetscSortInt(total_primal_vertices,aux_primal_numbering);CHKERRQ(ierr); 2288984c4197SStefano Zampini 2289984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 2290785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 2291984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i]=1; 2292984c4197SStefano Zampini j=total_primal_vertices; 2293984c4197SStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 22944641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2295674ae819SStefano Zampini nnz[j]=temp_indices[i+1]-temp_indices[i]; 2296674ae819SStefano Zampini j++; 2297674ae819SStefano Zampini } 2298674ae819SStefano Zampini } 2299674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 2300674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2301674ae819SStefano Zampini /* set values in constraint matrix */ 2302984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 2303984c4197SStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,aux_primal_numbering[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 2304674ae819SStefano Zampini } 2305984c4197SStefano Zampini total_counts = total_primal_vertices; 2306984c4197SStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 23074641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2308674ae819SStefano Zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 2309674ae819SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&total_counts,size_of_constraint,&temp_indices_to_constraint[temp_indices[i]],&temp_quadrature_constraint[temp_indices[i]],INSERT_VALUES);CHKERRQ(ierr); 2310674ae819SStefano Zampini total_counts++; 2311674ae819SStefano Zampini } 2312674ae819SStefano Zampini } 2313674ae819SStefano Zampini /* assembling */ 2314674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2315674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2316984c4197SStefano Zampini /* 231745a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2318984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 2319984c4197SStefano Zampini */ 2320674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 2321674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 2322026de310SStefano Zampini /* dual and primal dofs on a single cc */ 2323984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 2324026de310SStefano Zampini /* iterator on aux_primal_minloc (ordered as read from nearnullspace: vertices, edges and then constraints) */ 2325026de310SStefano Zampini PetscInt primal_counter; 2326984c4197SStefano Zampini /* working stuff for GEQRF */ 232781d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 2328984c4197SStefano Zampini PetscBLASInt lqr_work; 2329984c4197SStefano Zampini /* working stuff for UNGQR */ 2330984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 2331984c4197SStefano Zampini PetscBLASInt lgqr_work; 2332984c4197SStefano Zampini /* working stuff for TRTRS */ 2333984c4197SStefano Zampini PetscScalar *trs_rhs; 23343f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 2335984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 2336984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 2337984c4197SStefano Zampini PetscScalar *start_vals; 2338984c4197SStefano Zampini /* working stuff for values insertion */ 23394641a718SStefano Zampini PetscBT is_primal; 2340906d46d4SStefano Zampini /* matrix sizes */ 2341906d46d4SStefano Zampini PetscInt global_size,local_size; 2342906d46d4SStefano Zampini /* temporary change of basis */ 2343906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 2344984c4197SStefano Zampini 2345906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 2346906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 2347906d46d4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,impMatType);CHKERRQ(ierr); 2348*bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 2349906d46d4SStefano Zampini 2350906d46d4SStefano Zampini /* nonzeros for local mat */ 2351*bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 2352*bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 2353a717540cSStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 2354a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 2355a717540cSStefano Zampini size_of_constraint = temp_indices[i+1]-temp_indices[i]; 2356a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 2357*bbb9e6c6SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[temp_indices_to_constraint[temp_indices[i]+j]] = size_of_constraint; 2358a717540cSStefano Zampini } else { 2359*bbb9e6c6SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[temp_indices_to_constraint[temp_indices[i]+j]] = 2; 2360a717540cSStefano Zampini /* get local primal index on the cc */ 2361a717540cSStefano Zampini j = 0; 2362a717540cSStefano Zampini while (!PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+j])) j++; 2363*bbb9e6c6SStefano Zampini nnz[temp_indices_to_constraint[temp_indices[i]+j]] = size_of_constraint; 2364a717540cSStefano Zampini } 2365a717540cSStefano Zampini } 2366a717540cSStefano Zampini } 2367906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 2368*bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2369a717540cSStefano Zampini /* Set initial identity in the matrix */ 2370*bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 2371906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 2372a717540cSStefano Zampini } 2373a717540cSStefano Zampini 2374a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2375a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2376a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2377a717540cSStefano Zampini } 2378a717540cSStefano Zampini 2379a717540cSStefano Zampini 2380a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 2381a717540cSStefano Zampini /* 2382a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 2383a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 2384a717540cSStefano Zampini 2385a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 2386a717540cSStefano Zampini 2387a6b551f4SStefano 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) 2388a6b551f4SStefano Zampini 2389a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 2390a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 2391a717540cSStefano Zampini | ... | 2392a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 2393a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 2394a717540cSStefano Zampini 2395a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 2396a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 2397a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 2398a6b551f4SStefano Zampini 2399a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 2400a717540cSStefano Zampini */ 2401a717540cSStefano Zampini if (qr_needed) { 2402984c4197SStefano Zampini /* space to store Q */ 2403854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 2404984c4197SStefano Zampini /* first we issue queries for optimal work */ 24053f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 24063f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 24073f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2408984c4197SStefano Zampini lqr_work = -1; 24093f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 2410984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 2411984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 2412785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 2413984c4197SStefano Zampini lgqr_work = -1; 24143f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 24153f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 24163f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 24173f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 24183f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 24193f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 2420984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 2421984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 2422785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 2423984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 2424785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 2425984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 2426785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 2427a717540cSStefano Zampini /* allocating workspace for check */ 2428a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2429785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&work);CHKERRQ(ierr); 2430a717540cSStefano Zampini } 2431a717540cSStefano Zampini } 2432984c4197SStefano Zampini /* array to store whether a node is primal or not */ 24334641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 2434473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 24355e8657edSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,aux_primal_numbering,&i,aux_primal_numbering_B);CHKERRQ(ierr); 243639e2fb2aSStefano Zampini if (i != total_primal_vertices) { 243739e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 24384641a718SStefano Zampini } 243939e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 244039e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 244139e2fb2aSStefano Zampini } 244239e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 2443984c4197SStefano Zampini 2444a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 2445026de310SStefano Zampini /* -> using implicit ordering contained in temp_indices data */ 2446026de310SStefano Zampini total_counts = pcbddc->n_vertices; 2447026de310SStefano Zampini primal_counter = total_counts; 2448026de310SStefano Zampini while (total_counts<pcbddc->local_primal_size) { 2449026de310SStefano Zampini primal_dofs = 1; 24504641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 2451026de310SStefano Zampini /* get all constraints with same support: if more then one constraint is present on the cc then surely indices are stored contiguosly */ 2452*bbb9e6c6SStefano Zampini while (total_counts+primal_dofs < pcbddc->local_primal_size && temp_indices_to_constraint[temp_indices[total_counts]] == temp_indices_to_constraint[temp_indices[total_counts+primal_dofs]]) { 2453026de310SStefano Zampini primal_dofs++; 2454674ae819SStefano Zampini } 2455984c4197SStefano Zampini /* get constraint info */ 2456026de310SStefano Zampini size_of_constraint = temp_indices[total_counts+1]-temp_indices[total_counts]; 2457984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 2458984c4197SStefano Zampini 2459984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2460a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraints %d to %d (incl) need a change of basis (size %d)\n",total_counts,total_counts+primal_dofs-1,size_of_constraint);CHKERRQ(ierr); 2461674ae819SStefano Zampini } 2462984c4197SStefano Zampini 2463fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 2464a717540cSStefano Zampini 2465a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 2466a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2467a717540cSStefano Zampini ierr = PetscMemcpy(work,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2468a717540cSStefano Zampini } 2469984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 2470026de310SStefano Zampini ierr = PetscMemcpy(qr_basis,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2471984c4197SStefano Zampini 2472984c4197SStefano Zampini /* compute QR decomposition of constraints */ 24733f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 24743f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 24753f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2476674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 24773f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 2478984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 2479674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2480984c4197SStefano Zampini 2481984c4197SStefano Zampini /* explictly compute R^-T */ 2482984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 2483984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 24843f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 24853f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 24863f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 24873f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 2488984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 24893f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 2490984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 2491984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2492984c4197SStefano Zampini 2493a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 24943f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 24953f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 24963f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 24973f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2498984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 24993f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 2500984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 2501984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2502984c4197SStefano Zampini 2503984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 2504984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 2505984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 25063f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 25073f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 25083f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 25093f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 25103f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 25113f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2512984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2513c4303822SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&zero,&temp_quadrature_constraint[temp_indices[total_counts]],&Blas_LDC)); 2514984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2515026de310SStefano Zampini ierr = PetscMemcpy(qr_basis,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2516984c4197SStefano Zampini 2517984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 2518*bbb9e6c6SStefano Zampini start_rows = &temp_indices_to_constraint[temp_indices[total_counts]]; 2519984c4197SStefano Zampini /* insert cols for primal dofs */ 2520984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 2521984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 2522*bbb9e6c6SStefano Zampini start_cols = &temp_indices_to_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter+j]]; 2523906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 2524984c4197SStefano Zampini } 2525984c4197SStefano Zampini /* insert cols for dual dofs */ 2526984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 25274641a718SStefano Zampini if (!PetscBTLookup(is_primal,temp_indices_to_constraint_B[temp_indices[total_counts]+k])) { 2528984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 2529*bbb9e6c6SStefano Zampini start_cols = &temp_indices_to_constraint[temp_indices[total_counts]+k]; 2530906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 2531984c4197SStefano Zampini j++; 2532674ae819SStefano Zampini } 2533674ae819SStefano Zampini } 2534984c4197SStefano Zampini 2535984c4197SStefano Zampini /* check change of basis */ 2536984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2537984c4197SStefano Zampini PetscInt ii,jj; 2538984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 2539c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 2540c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2541c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 2542c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2543c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 2544c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 2545984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2546c4303822SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&Blas_M,&Blas_N,&Blas_K,&one,work,&Blas_LDA,qr_basis,&Blas_LDB,&zero,&work[size_of_constraint*primal_dofs],&Blas_LDC)); 2547984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2548984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 2549984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 2550984c4197SStefano Zampini if (ii != jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 2551984c4197SStefano Zampini if (ii == jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) valid_qr = PETSC_FALSE; 2552674ae819SStefano Zampini } 2553674ae819SStefano Zampini } 2554984c4197SStefano Zampini if (!valid_qr) { 255522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 2556984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 2557984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 2558984c4197SStefano Zampini if (ii != jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 2559984c4197SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not orthogonal to constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 2560674ae819SStefano Zampini } 2561984c4197SStefano Zampini if (ii == jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 2562984c4197SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not unitary w.r.t constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 2563984c4197SStefano Zampini } 2564984c4197SStefano Zampini } 2565984c4197SStefano Zampini } 2566674ae819SStefano Zampini } else { 256722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 2568674ae819SStefano Zampini } 2569674ae819SStefano Zampini } 2570a717540cSStefano Zampini } else { /* simple transformation block */ 2571a717540cSStefano Zampini PetscInt row,col; 2572a6b551f4SStefano Zampini PetscScalar val,norm; 2573a6b551f4SStefano Zampini 2574a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2575a6b551f4SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,temp_quadrature_constraint+temp_indices[total_counts],&Blas_one,temp_quadrature_constraint+temp_indices[total_counts],&Blas_one)); 2576a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 2577*bbb9e6c6SStefano Zampini PetscInt row_B = temp_indices_to_constraint_B[temp_indices[total_counts]+j]; 2578*bbb9e6c6SStefano Zampini row = temp_indices_to_constraint[temp_indices[total_counts]+j]; 2579*bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 2580*bbb9e6c6SStefano Zampini col = temp_indices_to_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]; 2581906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 2582a6b551f4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,temp_quadrature_constraint[temp_indices[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 2583a717540cSStefano Zampini } else { 2584a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 2585*bbb9e6c6SStefano Zampini col = temp_indices_to_constraint[temp_indices[total_counts]+k]; 2586a717540cSStefano Zampini if (row != col) { 2587a717540cSStefano Zampini val = -temp_quadrature_constraint[temp_indices[total_counts]+k]/temp_quadrature_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]; 2588a717540cSStefano Zampini } else { 2589a6b551f4SStefano Zampini val = temp_quadrature_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]/norm; 2590a717540cSStefano Zampini } 2591906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 2592a717540cSStefano Zampini } 2593a717540cSStefano Zampini } 2594a717540cSStefano Zampini } 259598a51de6SStefano Zampini if (pcbddc->dbg_flag) { 259622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 2597a717540cSStefano Zampini } 2598674ae819SStefano Zampini } 2599026de310SStefano Zampini /* increment primal counter */ 2600026de310SStefano Zampini primal_counter += primal_dofs; 2601984c4197SStefano Zampini } else { 2602984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2603026de310SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraint %d does not need a change of basis (size %d)\n",total_counts,temp_indices[total_counts+1]-temp_indices[total_counts]);CHKERRQ(ierr); 2604674ae819SStefano Zampini } 2605674ae819SStefano Zampini } 2606026de310SStefano Zampini /* increment constraint counter total_counts */ 2607026de310SStefano Zampini total_counts += primal_dofs; 2608674ae819SStefano Zampini } 2609a717540cSStefano Zampini 2610a717540cSStefano Zampini /* free workspace */ 2611a717540cSStefano Zampini if (qr_needed) { 2612984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2613984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2614984c4197SStefano Zampini } 2615984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 2616984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 2617984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 2618984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 2619984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 2620674ae819SStefano Zampini } 2621a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 2622906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2623906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2624906d46d4SStefano Zampini 2625906d46d4SStefano Zampini /* assembling of global change of variable */ 2626*bbb9e6c6SStefano Zampini { 2627*bbb9e6c6SStefano Zampini Mat tmat; 2628906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 2629906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 2630*bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 2631*bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 2632*bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2633*bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 2634906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 2635*bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 2636*bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2637*bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2638*bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2639*bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 2640*bbb9e6c6SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2641*bbb9e6c6SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2642*bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 2643*bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 2644906d46d4SStefano Zampini } 2645906d46d4SStefano Zampini /* check */ 2646906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2647906d46d4SStefano Zampini PetscReal error; 2648906d46d4SStefano Zampini Vec x,x_change; 2649906d46d4SStefano Zampini 2650906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 2651906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 2652906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 2653906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 2654*bbb9e6c6SStefano Zampini ierr = VecScatterBegin(matis->ctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2655*bbb9e6c6SStefano Zampini ierr = VecScatterEnd(matis->ctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2656*bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2657*bbb9e6c6SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2658*bbb9e6c6SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2659906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 2660906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2661906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2662906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2663*bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 2664906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2665906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2666906d46d4SStefano Zampini } 2667b96c3477SStefano Zampini 2668b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 2669b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2670b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 2671b96c3477SStefano Zampini if (sub_schurs->n_subs_par_g) { 2672b7eb3628SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Change of basis with deluxe scaling and parallel problems still needs to be implemented"); 2673b96c3477SStefano Zampini } 2674b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 2675b96c3477SStefano Zampini Mat S_1,S_2,tmat; 2676*bbb9e6c6SStefano Zampini IS is_all_N; 2677*bbb9e6c6SStefano Zampini 2678*bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 2679*bbb9e6c6SStefano Zampini ierr = MatGetSubMatrixUnsorted(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 2680*bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 2681b96c3477SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_1);CHKERRQ(ierr); 2682b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 2683b96c3477SStefano Zampini sub_schurs->S_Ej_all = S_1; 2684b96c3477SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_2);CHKERRQ(ierr); 2685b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 2686b96c3477SStefano Zampini sub_schurs->sum_S_Ej_all = S_2; 2687b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2688b96c3477SStefano Zampini } 2689b96c3477SStefano Zampini } 2690906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 2691906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 2692b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2693b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 2694b9b85e73SStefano Zampini } 2695906d46d4SStefano Zampini 2696906d46d4SStefano Zampini /* set up change of basis context */ 2697906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2698906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 2699906d46d4SStefano Zampini 2700906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 2701906d46d4SStefano Zampini PetscInt global_size,local_size; 2702906d46d4SStefano Zampini 2703906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 2704906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 2705906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 2706906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 2707906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 2708906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 2709906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 2710906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 2711906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 2712906d46d4SStefano Zampini } else { 2713906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 2714906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 2715906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 2716906d46d4SStefano Zampini } 2717906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 2718906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2719906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 2720906d46d4SStefano Zampini } else { 2721906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2722906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 2723906d46d4SStefano Zampini } 2724906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 2725906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 2726906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2727906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2728b9b85e73SStefano Zampini } 2729a717540cSStefano Zampini 2730727cdba6SStefano Zampini /* get indices in local ordering for vertices and constraints */ 2731727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { /* if this is true, I need to check if a new primal space has been introduced */ 2732473ba861SJed Brown ierr = PetscMalloc1(olocal_primal_size,&oprimal_indices_local_idxs);CHKERRQ(ierr); 2733727cdba6SStefano Zampini ierr = PetscMemcpy(oprimal_indices_local_idxs,pcbddc->primal_indices_local_idxs,olocal_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 2734727cdba6SStefano Zampini } 2735727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2736f347579bSStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2737473ba861SJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2738727cdba6SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&i,&aux_primal_numbering);CHKERRQ(ierr); 2739727cdba6SStefano Zampini ierr = PetscMemcpy(pcbddc->primal_indices_local_idxs,aux_primal_numbering,i*sizeof(PetscInt));CHKERRQ(ierr); 2740727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2741727cdba6SStefano Zampini ierr = PCBDDCGetPrimalConstraintsLocalIdx(pc,&j,&aux_primal_numbering);CHKERRQ(ierr); 2742727cdba6SStefano Zampini ierr = PetscMemcpy(&pcbddc->primal_indices_local_idxs[i],aux_primal_numbering,j*sizeof(PetscInt));CHKERRQ(ierr); 2743727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2744e9189074SStefano Zampini /* set quantities in PCBDDC data struct */ 2745e9189074SStefano Zampini pcbddc->n_actual_vertices = i; 2746727cdba6SStefano Zampini /* check if a new primal space has been introduced */ 2747727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 2748727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 2749727cdba6SStefano Zampini ierr = PetscMemcmp(pcbddc->primal_indices_local_idxs,oprimal_indices_local_idxs,olocal_primal_size,&pcbddc->new_primal_space_local);CHKERRQ(ierr); 2750c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 2751727cdba6SStefano Zampini ierr = PetscFree(oprimal_indices_local_idxs);CHKERRQ(ierr); 2752727cdba6SStefano Zampini } 2753727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 2754727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2755727cdba6SStefano Zampini 2756a717540cSStefano Zampini /* flush dbg viewer */ 2757b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 2758b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2759b8ffe317SStefano Zampini } 2760a717540cSStefano Zampini 2761e310c8b4SStefano Zampini /* free workspace */ 2762a717540cSStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 2763a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 2764984c4197SStefano Zampini ierr = PetscFree(aux_primal_minloc);CHKERRQ(ierr); 27654641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 276608122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 2767906d46d4SStefano Zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 2768906d46d4SStefano Zampini ierr = PetscFree3(temp_quadrature_constraint,temp_indices_to_constraint,temp_indices_to_constraint_B);CHKERRQ(ierr); 276908122e43SStefano Zampini } else { 277008122e43SStefano Zampini ierr = PetscFree4(pcbddc->adaptive_constraints_n, 277108122e43SStefano Zampini pcbddc->adaptive_constraints_ptrs, 277208122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 277308122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 277408122e43SStefano Zampini ierr = PetscFree(temp_indices_to_constraint_B);CHKERRQ(ierr); 277508122e43SStefano Zampini } 2776674ae819SStefano Zampini PetscFunctionReturn(0); 2777674ae819SStefano Zampini } 2778674ae819SStefano Zampini 2779674ae819SStefano Zampini #undef __FUNCT__ 2780674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 2781674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 2782674ae819SStefano Zampini { 2783674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2784674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2785674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 278663602bcaSStefano Zampini PetscInt ierr,i,vertex_size; 2787674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 2788674ae819SStefano Zampini 2789674ae819SStefano Zampini PetscFunctionBegin; 27908e61c736SStefano Zampini /* Reset previously computed graph */ 27918e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 2792674ae819SStefano Zampini /* Init local Graph struct */ 2793674ae819SStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,matis->mapping);CHKERRQ(ierr); 2794674ae819SStefano Zampini 2795575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 2796575ad6abSStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 2797575ad6abSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 2798575ad6abSStefano Zampini } 27999577ea80SStefano Zampini 2800674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 28014d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 2802674ae819SStefano Zampini Mat mat_adj; 28034d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 28044d379d7bSStefano Zampini PetscInt nvtxs; 2805674ae819SStefano Zampini PetscBool flg_row=PETSC_TRUE; 2806674ae819SStefano Zampini 2807674ae819SStefano Zampini ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 28084d379d7bSStefano Zampini ierr = MatGetRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 2809674ae819SStefano Zampini if (!flg_row) { 2810674ae819SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 2811674ae819SStefano Zampini } 28124d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 28134d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 2814b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 28154d379d7bSStefano Zampini } else { /* just compute subdomain's connected components */ 28164d379d7bSStefano Zampini IS is_dummy; 28174d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 28184d379d7bSStefano Zampini PetscInt j,sum; 28194d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 28204d379d7bSStefano Zampini const PetscInt *idxs; 28214d379d7bSStefano Zampini PCBDDCGraph graph; 28224d379d7bSStefano Zampini PetscBT is_on_boundary; 28234d379d7bSStefano Zampini 28244d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 28254d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 28264d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 28274d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 28284d379d7bSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy);CHKERRQ(ierr); 28294d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 28304d379d7bSStefano Zampini graph->xadj = xadj; 28314d379d7bSStefano Zampini graph->adjncy = adjncy; 28324d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 28334d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 28344d379d7bSStefano Zampini 28354d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 28364d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains\n",PetscGlobalRank,graph->ncc);CHKERRQ(ierr); 28374d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 28384d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 28394d379d7bSStefano Zampini } 28404d379d7bSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 28414d379d7bSStefano Zampini } 28424d379d7bSStefano Zampini 28434d379d7bSStefano Zampini ierr = PetscBTCreate(nvtxs,&is_on_boundary);CHKERRQ(ierr); 28444d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 28454d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 28464d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 28474d379d7bSStefano Zampini } 28484d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 28494d379d7bSStefano Zampini 28504d379d7bSStefano Zampini ierr = PetscCalloc1(nvtxs+1,&cxadj);CHKERRQ(ierr); 28514d379d7bSStefano Zampini sum = 0; 28524d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 28534d379d7bSStefano Zampini PetscInt sizecc = 0; 28544d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 28554d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 28564d379d7bSStefano Zampini sizecc++; 28574d379d7bSStefano Zampini } 28584d379d7bSStefano Zampini } 28594d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 28604d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 28614d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 28624d379d7bSStefano Zampini } 28634d379d7bSStefano Zampini } 28644d379d7bSStefano Zampini sum += sizecc*sizecc; 28654d379d7bSStefano Zampini } 28664d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 28674d379d7bSStefano Zampini sum = 0; 28684d379d7bSStefano Zampini for (i=0;i<nvtxs;i++) { 28694d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 28704d379d7bSStefano Zampini cxadj[i] = sum; 28714d379d7bSStefano Zampini sum += temp; 28724d379d7bSStefano Zampini } 28734d379d7bSStefano Zampini cxadj[nvtxs] = sum; 28744d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 28754d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 28764d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 28774d379d7bSStefano Zampini PetscInt k,sizecc = 0; 28784d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 28794d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 28804d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 28814d379d7bSStefano Zampini sizecc++; 28824d379d7bSStefano Zampini } 28834d379d7bSStefano Zampini } 28844d379d7bSStefano Zampini } 28854d379d7bSStefano Zampini } 28864d379d7bSStefano Zampini } 28874d379d7bSStefano Zampini if (nvtxs) { 28884d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 28894d379d7bSStefano Zampini } else { 28904d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 28914d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 28924d379d7bSStefano Zampini } 28934d379d7bSStefano Zampini graph->xadj = 0; 28944d379d7bSStefano Zampini graph->adjncy = 0; 28954d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 28964d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 28974d379d7bSStefano Zampini } 28984d379d7bSStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 2899674ae819SStefano Zampini if (!flg_row) { 2900674ae819SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 2901674ae819SStefano Zampini } 2902674ae819SStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 2903674ae819SStefano Zampini } 2904674ae819SStefano Zampini 290563602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 2906674ae819SStefano Zampini vertex_size = 1; 290763602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 290863602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 290995ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 291063602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 2911a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 291263602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2913674ae819SStefano Zampini } 291463602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 291563602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 291663602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 2917674ae819SStefano Zampini } 291863602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 2919674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 292063602bcaSStefano Zampini } else { 292163602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 292263602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 2923854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 292463602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 292563602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 292663602bcaSStefano Zampini } 292763602bcaSStefano Zampini } 2928674ae819SStefano Zampini } 2929674ae819SStefano Zampini 2930674ae819SStefano Zampini /* Setup of Graph */ 2931785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 2932a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 2933785d1243SStefano Zampini } 2934785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 2935a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 2936785d1243SStefano Zampini } 293763602bcaSStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices); 2938674ae819SStefano Zampini 2939674ae819SStefano Zampini /* Graph's connected components analysis */ 2940674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 2941674ae819SStefano Zampini 2942674ae819SStefano Zampini /* print some info to stdout */ 2943674ae819SStefano Zampini if (pcbddc->dbg_flag) { 2944e49050b4SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer); 2945674ae819SStefano Zampini } 2946fb180af4SStefano Zampini 2947fb180af4SStefano Zampini /* mark topography has done */ 2948fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 2949674ae819SStefano Zampini PetscFunctionReturn(0); 2950674ae819SStefano Zampini } 2951674ae819SStefano Zampini 2952674ae819SStefano Zampini #undef __FUNCT__ 2953674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGetPrimalVerticesLocalIdx" 2954f34684f1SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesLocalIdx(PC pc, PetscInt *n_vertices, PetscInt **vertices_idx) 2955674ae819SStefano Zampini { 2956674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2957674ae819SStefano Zampini PetscInt *vertices,*row_cmat_indices,n,i,size_of_constraint,local_primal_size; 2958674ae819SStefano Zampini PetscErrorCode ierr; 2959674ae819SStefano Zampini 2960674ae819SStefano Zampini PetscFunctionBegin; 2961674ae819SStefano Zampini n = 0; 2962674ae819SStefano Zampini vertices = 0; 2963674ae819SStefano Zampini if (pcbddc->ConstraintMatrix) { 2964674ae819SStefano Zampini ierr = MatGetSize(pcbddc->ConstraintMatrix,&local_primal_size,&i);CHKERRQ(ierr); 2965b120a5c6SStefano Zampini for (i=0;i<local_primal_size;i++) { 2966b120a5c6SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2967b120a5c6SStefano Zampini if (size_of_constraint == 1) n++; 2968b120a5c6SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2969b120a5c6SStefano Zampini } 2970811e8ca2SStefano Zampini if (vertices_idx) { 2971785e854fSJed Brown ierr = PetscMalloc1(n,&vertices);CHKERRQ(ierr); 2972b120a5c6SStefano Zampini n = 0; 2973674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 2974674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2975674ae819SStefano Zampini if (size_of_constraint == 1) { 2976674ae819SStefano Zampini vertices[n++]=row_cmat_indices[0]; 2977674ae819SStefano Zampini } 2978674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2979674ae819SStefano Zampini } 2980674ae819SStefano Zampini } 2981811e8ca2SStefano Zampini } 2982674ae819SStefano Zampini *n_vertices = n; 2983811e8ca2SStefano Zampini if (vertices_idx) *vertices_idx = vertices; 2984674ae819SStefano Zampini PetscFunctionReturn(0); 2985674ae819SStefano Zampini } 2986674ae819SStefano Zampini 2987674ae819SStefano Zampini #undef __FUNCT__ 2988674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGetPrimalConstraintsLocalIdx" 2989f34684f1SStefano Zampini PetscErrorCode PCBDDCGetPrimalConstraintsLocalIdx(PC pc, PetscInt *n_constraints, PetscInt **constraints_idx) 2990674ae819SStefano Zampini { 2991674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2992674ae819SStefano Zampini PetscInt *constraints_index,*row_cmat_indices,*row_cmat_global_indices; 2993674ae819SStefano Zampini PetscInt n,i,j,size_of_constraint,local_primal_size,local_size,max_size_of_constraint,min_index,min_loc; 29944641a718SStefano Zampini PetscBT touched; 2995674ae819SStefano Zampini PetscErrorCode ierr; 2996674ae819SStefano Zampini 2997f34684f1SStefano Zampini /* This function assumes that the number of local constraints per connected component 2998f34684f1SStefano Zampini is not greater than the number of nodes defined for the connected component 2999f34684f1SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 3000674ae819SStefano Zampini PetscFunctionBegin; 3001674ae819SStefano Zampini n = 0; 3002674ae819SStefano Zampini constraints_index = 0; 3003674ae819SStefano Zampini if (pcbddc->ConstraintMatrix) { 3004674ae819SStefano Zampini ierr = MatGetSize(pcbddc->ConstraintMatrix,&local_primal_size,&local_size);CHKERRQ(ierr); 3005674ae819SStefano Zampini max_size_of_constraint = 0; 3006674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 3007674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 3008674ae819SStefano Zampini if (size_of_constraint > 1) { 3009674ae819SStefano Zampini n++; 3010674ae819SStefano Zampini } 3011674ae819SStefano Zampini max_size_of_constraint = PetscMax(size_of_constraint,max_size_of_constraint); 3012674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 3013674ae819SStefano Zampini } 3014811e8ca2SStefano Zampini if (constraints_idx) { 3015785e854fSJed Brown ierr = PetscMalloc1(n,&constraints_index);CHKERRQ(ierr); 3016785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint,&row_cmat_global_indices);CHKERRQ(ierr); 30174641a718SStefano Zampini ierr = PetscBTCreate(local_size,&touched);CHKERRQ(ierr); 3018674ae819SStefano Zampini n = 0; 3019674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 3020674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 3021674ae819SStefano Zampini if (size_of_constraint > 1) { 3022674ae819SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcbddc->mat_graph->l2gmap,size_of_constraint,row_cmat_indices,row_cmat_global_indices);CHKERRQ(ierr); 302382d3d8afSStefano Zampini /* find first untouched local node */ 302482d3d8afSStefano Zampini j = 0; 30254641a718SStefano Zampini while (PetscBTLookup(touched,row_cmat_indices[j])) j++; 302682d3d8afSStefano Zampini min_index = row_cmat_global_indices[j]; 302782d3d8afSStefano Zampini min_loc = j; 302882d3d8afSStefano Zampini /* search the minimum among nodes not yet touched on the connected component 302982d3d8afSStefano Zampini since there can be more than one constraint on a single cc */ 3030674ae819SStefano Zampini for (j=1;j<size_of_constraint;j++) { 30314641a718SStefano Zampini if (!PetscBTLookup(touched,row_cmat_indices[j]) && min_index > row_cmat_global_indices[j]) { 3032674ae819SStefano Zampini min_index = row_cmat_global_indices[j]; 3033674ae819SStefano Zampini min_loc = j; 3034674ae819SStefano Zampini } 3035674ae819SStefano Zampini } 30364641a718SStefano Zampini ierr = PetscBTSet(touched,row_cmat_indices[min_loc]);CHKERRQ(ierr); 3037674ae819SStefano Zampini constraints_index[n++] = row_cmat_indices[min_loc]; 3038674ae819SStefano Zampini } 3039674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 3040674ae819SStefano Zampini } 30414641a718SStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 3042674ae819SStefano Zampini ierr = PetscFree(row_cmat_global_indices);CHKERRQ(ierr); 3043811e8ca2SStefano Zampini } 3044811e8ca2SStefano Zampini } 3045674ae819SStefano Zampini *n_constraints = n; 3046811e8ca2SStefano Zampini if (constraints_idx) *constraints_idx = constraints_index; 3047674ae819SStefano Zampini PetscFunctionReturn(0); 3048674ae819SStefano Zampini } 3049674ae819SStefano Zampini 3050674ae819SStefano Zampini #undef __FUNCT__ 3051674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 3052674ae819SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(MPI_Comm comm,ISLocalToGlobalMapping l2gmap, PetscInt n_local_dofs, PetscInt local_dofs[], PetscInt local_dofs_mult[], PetscInt* n_global_subset, PetscInt* global_numbering_subset[]) 3053674ae819SStefano Zampini { 3054674ae819SStefano Zampini Vec local_vec,global_vec; 3055674ae819SStefano Zampini IS seqis,paris; 3056674ae819SStefano Zampini VecScatter scatter_ctx; 3057674ae819SStefano Zampini PetscScalar *array; 3058674ae819SStefano Zampini PetscInt *temp_global_dofs; 3059674ae819SStefano Zampini PetscScalar globalsum; 3060674ae819SStefano Zampini PetscInt i,j,s; 3061674ae819SStefano Zampini PetscInt nlocals,first_index,old_index,max_local; 3062674ae819SStefano Zampini PetscMPIInt rank_prec_comm,size_prec_comm,max_global; 3063674ae819SStefano Zampini PetscMPIInt *dof_sizes,*dof_displs; 3064674ae819SStefano Zampini PetscBool first_found; 3065674ae819SStefano Zampini PetscErrorCode ierr; 3066674ae819SStefano Zampini 3067674ae819SStefano Zampini PetscFunctionBegin; 3068674ae819SStefano Zampini /* mpi buffers */ 3069b9b85e73SStefano Zampini ierr = MPI_Comm_size(comm,&size_prec_comm);CHKERRQ(ierr); 3070b9b85e73SStefano Zampini ierr = MPI_Comm_rank(comm,&rank_prec_comm);CHKERRQ(ierr); 3071674ae819SStefano Zampini j = ( !rank_prec_comm ? size_prec_comm : 0); 3072785e854fSJed Brown ierr = PetscMalloc1(j,&dof_sizes);CHKERRQ(ierr); 3073785e854fSJed Brown ierr = PetscMalloc1(j,&dof_displs);CHKERRQ(ierr); 3074674ae819SStefano Zampini /* get maximum size of subset */ 3075785e854fSJed Brown ierr = PetscMalloc1(n_local_dofs,&temp_global_dofs);CHKERRQ(ierr); 3076674ae819SStefano Zampini ierr = ISLocalToGlobalMappingApply(l2gmap,n_local_dofs,local_dofs,temp_global_dofs);CHKERRQ(ierr); 3077674ae819SStefano Zampini max_local = 0; 3078b9b85e73SStefano Zampini for (i=0;i<n_local_dofs;i++) { 3079674ae819SStefano Zampini if (max_local < temp_global_dofs[i] ) { 3080674ae819SStefano Zampini max_local = temp_global_dofs[i]; 3081674ae819SStefano Zampini } 3082674ae819SStefano Zampini } 3083b9b85e73SStefano Zampini ierr = MPI_Allreduce(&max_local,&max_global,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 3084674ae819SStefano Zampini max_global++; 3085674ae819SStefano Zampini max_local = 0; 3086b9b85e73SStefano Zampini for (i=0;i<n_local_dofs;i++) { 3087674ae819SStefano Zampini if (max_local < local_dofs[i] ) { 3088674ae819SStefano Zampini max_local = local_dofs[i]; 3089674ae819SStefano Zampini } 3090674ae819SStefano Zampini } 3091674ae819SStefano Zampini max_local++; 3092674ae819SStefano Zampini /* allocate workspace */ 3093674ae819SStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&local_vec);CHKERRQ(ierr); 3094674ae819SStefano Zampini ierr = VecSetSizes(local_vec,PETSC_DECIDE,max_local);CHKERRQ(ierr); 3095674ae819SStefano Zampini ierr = VecSetType(local_vec,VECSEQ);CHKERRQ(ierr); 3096674ae819SStefano Zampini ierr = VecCreate(comm,&global_vec);CHKERRQ(ierr); 3097674ae819SStefano Zampini ierr = VecSetSizes(global_vec,PETSC_DECIDE,max_global);CHKERRQ(ierr); 3098674ae819SStefano Zampini ierr = VecSetType(global_vec,VECMPI);CHKERRQ(ierr); 3099674ae819SStefano Zampini /* create scatter */ 3100674ae819SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_local_dofs,local_dofs,PETSC_COPY_VALUES,&seqis);CHKERRQ(ierr); 3101674ae819SStefano Zampini ierr = ISCreateGeneral(comm,n_local_dofs,temp_global_dofs,PETSC_COPY_VALUES,&paris);CHKERRQ(ierr); 3102674ae819SStefano Zampini ierr = VecScatterCreate(local_vec,seqis,global_vec,paris,&scatter_ctx);CHKERRQ(ierr); 3103674ae819SStefano Zampini ierr = ISDestroy(&seqis);CHKERRQ(ierr); 3104674ae819SStefano Zampini ierr = ISDestroy(&paris);CHKERRQ(ierr); 3105674ae819SStefano Zampini /* init array */ 3106674ae819SStefano Zampini ierr = VecSet(global_vec,0.0);CHKERRQ(ierr); 3107674ae819SStefano Zampini ierr = VecSet(local_vec,0.0);CHKERRQ(ierr); 3108674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 3109674ae819SStefano Zampini if (local_dofs_mult) { 3110674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 3111674ae819SStefano Zampini array[local_dofs[i]]=(PetscScalar)local_dofs_mult[i]; 3112674ae819SStefano Zampini } 3113674ae819SStefano Zampini } else { 3114674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 3115674ae819SStefano Zampini array[local_dofs[i]]=1.0; 3116674ae819SStefano Zampini } 3117674ae819SStefano Zampini } 3118674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 3119674ae819SStefano Zampini /* scatter into global vec and get total number of global dofs */ 3120674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,local_vec,global_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3121674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,local_vec,global_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3122674ae819SStefano Zampini ierr = VecSum(global_vec,&globalsum);CHKERRQ(ierr); 31235b08dc53SStefano Zampini *n_global_subset = (PetscInt)PetscRealPart(globalsum); 3124674ae819SStefano Zampini /* Fill global_vec with cumulative function for global numbering */ 3125674ae819SStefano Zampini ierr = VecGetArray(global_vec,&array);CHKERRQ(ierr); 3126674ae819SStefano Zampini ierr = VecGetLocalSize(global_vec,&s);CHKERRQ(ierr); 3127674ae819SStefano Zampini nlocals = 0; 3128674ae819SStefano Zampini first_index = -1; 3129674ae819SStefano Zampini first_found = PETSC_FALSE; 3130674ae819SStefano Zampini for (i=0;i<s;i++) { 3131b9b85e73SStefano Zampini if (!first_found && PetscRealPart(array[i]) > 0.1) { 3132674ae819SStefano Zampini first_found = PETSC_TRUE; 3133674ae819SStefano Zampini first_index = i; 3134674ae819SStefano Zampini } 31355b08dc53SStefano Zampini nlocals += (PetscInt)PetscRealPart(array[i]); 3136674ae819SStefano Zampini } 3137674ae819SStefano Zampini ierr = MPI_Gather(&nlocals,1,MPIU_INT,dof_sizes,1,MPIU_INT,0,comm);CHKERRQ(ierr); 3138674ae819SStefano Zampini if (!rank_prec_comm) { 3139674ae819SStefano Zampini dof_displs[0]=0; 3140674ae819SStefano Zampini for (i=1;i<size_prec_comm;i++) { 3141674ae819SStefano Zampini dof_displs[i] = dof_displs[i-1]+dof_sizes[i-1]; 3142674ae819SStefano Zampini } 3143674ae819SStefano Zampini } 3144674ae819SStefano Zampini ierr = MPI_Scatter(dof_displs,1,MPIU_INT,&nlocals,1,MPIU_INT,0,comm);CHKERRQ(ierr); 3145674ae819SStefano Zampini if (first_found) { 3146674ae819SStefano Zampini array[first_index] += (PetscScalar)nlocals; 3147674ae819SStefano Zampini old_index = first_index; 3148674ae819SStefano Zampini for (i=first_index+1;i<s;i++) { 3149b9b85e73SStefano Zampini if (PetscRealPart(array[i]) > 0.1) { 3150674ae819SStefano Zampini array[i] += array[old_index]; 3151674ae819SStefano Zampini old_index = i; 3152674ae819SStefano Zampini } 3153674ae819SStefano Zampini } 3154674ae819SStefano Zampini } 3155674ae819SStefano Zampini ierr = VecRestoreArray(global_vec,&array);CHKERRQ(ierr); 3156674ae819SStefano Zampini ierr = VecSet(local_vec,0.0);CHKERRQ(ierr); 3157674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3158674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3159674ae819SStefano Zampini /* get global ordering of local dofs */ 3160674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 3161674ae819SStefano Zampini if (local_dofs_mult) { 3162674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 31635b08dc53SStefano Zampini temp_global_dofs[i] = (PetscInt)PetscRealPart(array[local_dofs[i]])-local_dofs_mult[i]; 3164674ae819SStefano Zampini } 3165674ae819SStefano Zampini } else { 3166674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 31675b08dc53SStefano Zampini temp_global_dofs[i] = (PetscInt)PetscRealPart(array[local_dofs[i]])-1; 3168674ae819SStefano Zampini } 3169674ae819SStefano Zampini } 3170674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 3171674ae819SStefano Zampini /* free workspace */ 3172674ae819SStefano Zampini ierr = VecScatterDestroy(&scatter_ctx);CHKERRQ(ierr); 3173674ae819SStefano Zampini ierr = VecDestroy(&local_vec);CHKERRQ(ierr); 3174674ae819SStefano Zampini ierr = VecDestroy(&global_vec);CHKERRQ(ierr); 3175674ae819SStefano Zampini ierr = PetscFree(dof_sizes);CHKERRQ(ierr); 3176674ae819SStefano Zampini ierr = PetscFree(dof_displs);CHKERRQ(ierr); 3177674ae819SStefano Zampini /* return pointer to global ordering of local dofs */ 3178674ae819SStefano Zampini *global_numbering_subset = temp_global_dofs; 3179674ae819SStefano Zampini PetscFunctionReturn(0); 3180674ae819SStefano Zampini } 31819a7d3425SStefano Zampini 31829a7d3425SStefano Zampini #undef __FUNCT__ 31839a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 31849a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 31859a7d3425SStefano Zampini { 31869a7d3425SStefano Zampini PetscInt i,j; 31879a7d3425SStefano Zampini PetscScalar *alphas; 31889a7d3425SStefano Zampini PetscErrorCode ierr; 31899a7d3425SStefano Zampini 31909a7d3425SStefano Zampini PetscFunctionBegin; 31919a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 3192785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 31939a7d3425SStefano Zampini for (i=0;i<n;i++) { 31949a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 31959a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 31969a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 31979a7d3425SStefano Zampini } 31989a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 31999a7d3425SStefano Zampini PetscFunctionReturn(0); 32009a7d3425SStefano Zampini } 32019a7d3425SStefano Zampini 3202e7931f94SStefano Zampini #undef __FUNCT__ 320370cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 320428143c3dSStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscBool contiguous, IS* is_sends) 3205e7931f94SStefano Zampini { 3206e7931f94SStefano Zampini Mat subdomain_adj; 3207e7931f94SStefano Zampini IS new_ranks,ranks_send_to; 3208e7931f94SStefano Zampini MatPartitioning partitioner; 3209e7931f94SStefano Zampini Mat_IS *matis; 3210e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 3211e7931f94SStefano Zampini PetscInt prank; 3212e7931f94SStefano Zampini PetscMPIInt size,rank,color; 3213e7931f94SStefano Zampini PetscInt *xadj,*adjncy,*oldranks; 3214e7931f94SStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*is_indices,*ranks_send_to_idx; 32153837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 3216e7931f94SStefano Zampini PetscErrorCode ierr; 32172b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 3218e7931f94SStefano Zampini PetscSubcomm subcomm; 3219a57a6d2fSStefano Zampini 3220e7931f94SStefano Zampini PetscFunctionBegin; 32212b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 32222b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 32232b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 3224e7931f94SStefano Zampini 3225e7931f94SStefano Zampini /* Get info on mapping */ 3226e7931f94SStefano Zampini matis = (Mat_IS*)(mat->data); 3227e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->mapping,&local_size);CHKERRQ(ierr); 3228e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(matis->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3229e7931f94SStefano Zampini 3230e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 3231785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 3232e7931f94SStefano Zampini xadj[0] = 0; 3233e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 3234785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 3235785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 3236e7931f94SStefano Zampini 32372b510759SStefano Zampini if (threshold) { 3238d023bfaeSStefano Zampini PetscInt xadj_count = 0; 32392b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 3240d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 3241d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 3242d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 3243d023bfaeSStefano Zampini xadj_count++; 3244e7931f94SStefano Zampini } 3245e7931f94SStefano Zampini } 3246d023bfaeSStefano Zampini xadj[1] = xadj_count; 3247c8587f34SStefano Zampini } else { 3248e7931f94SStefano Zampini if (xadj[1]) { 3249e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 3250e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 3251c8587f34SStefano Zampini } 3252e7931f94SStefano Zampini } 3253e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(matis->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3254e7931f94SStefano Zampini if (use_square) { 3255e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3256e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 3257e7931f94SStefano Zampini } 3258e7931f94SStefano Zampini } 3259e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3260e7931f94SStefano Zampini 32613837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 3262e7931f94SStefano Zampini 3263e7931f94SStefano Zampini /* 3264e7931f94SStefano Zampini Restrict work on active processes only. 3265e7931f94SStefano Zampini */ 3266e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 3267e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 3268e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 32692b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 3270d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 3271e7931f94SStefano Zampini if (color) { 3272e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 3273e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 3274e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3275c8587f34SStefano Zampini } else { 327628143c3dSStefano Zampini PetscInt coarsening_ratio; 3277e7931f94SStefano Zampini ierr = MPI_Comm_size(subcomm->comm,&size);CHKERRQ(ierr); 3278785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 3279e7931f94SStefano Zampini prank = rank; 3280e7931f94SStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm->comm);CHKERRQ(ierr); 32818002ef2cSStefano Zampini /* 3282e7931f94SStefano Zampini for (i=0;i<size;i++) { 3283e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 3284c8587f34SStefano Zampini } 32858002ef2cSStefano Zampini */ 3286e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3287e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 3288c8587f34SStefano Zampini } 3289e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3290e7931f94SStefano Zampini ierr = MatCreateMPIAdj(subcomm->comm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 329122b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 3292e7931f94SStefano Zampini 3293e7931f94SStefano Zampini /* Partition */ 3294e7931f94SStefano Zampini ierr = MatPartitioningCreate(subcomm->comm,&partitioner);CHKERRQ(ierr); 3295e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 3296e7931f94SStefano Zampini if (use_vwgt) { 32973837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 3298e7931f94SStefano Zampini v_wgt[0] = local_size; 3299e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 3300c8587f34SStefano Zampini } 330128143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 330228143c3dSStefano Zampini coarsening_ratio = size/n_subdomains; 330328143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 3304e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 3305e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 330622b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 3307e7931f94SStefano Zampini 3308e7931f94SStefano Zampini ierr = ISGetIndices(new_ranks,(const PetscInt**)&is_indices);CHKERRQ(ierr); 330928143c3dSStefano Zampini if (contiguous) { 331028143c3dSStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; /* contiguos set of processes */ 331128143c3dSStefano Zampini } else { 331284ba6060SStefano Zampini ranks_send_to_idx[0] = coarsening_ratio*oldranks[is_indices[0]]; /* scattered set of processes */ 331328143c3dSStefano Zampini } 3314e7931f94SStefano Zampini ierr = ISRestoreIndices(new_ranks,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3315e7931f94SStefano Zampini /* clean up */ 3316e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 3317e7931f94SStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 3318e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 3319e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 3320e7931f94SStefano Zampini } 3321e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 3322e7931f94SStefano Zampini 3323e7931f94SStefano Zampini /* assemble parallel IS for sends */ 3324e7931f94SStefano Zampini i = 1; 3325e7931f94SStefano Zampini if (color) i=0; 3326e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 3327e7931f94SStefano Zampini 3328e7931f94SStefano Zampini /* get back IS */ 3329e7931f94SStefano Zampini *is_sends = ranks_send_to; 3330e7931f94SStefano Zampini PetscFunctionReturn(0); 3331e7931f94SStefano Zampini } 3332e7931f94SStefano Zampini 3333e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 3334e7931f94SStefano Zampini 3335e7931f94SStefano Zampini #undef __FUNCT__ 3336e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 333728143c3dSStefano Zampini PetscErrorCode MatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, MatReuse reuse, Mat *mat_n, PetscInt nis, IS isarray[]) 3338e7931f94SStefano Zampini { 333970cf5478SStefano Zampini Mat local_mat; 3340e7931f94SStefano Zampini Mat_IS *matis; 3341e7931f94SStefano Zampini IS is_sends_internal; 33429d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 334328143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 33449d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 3345e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 3346e7931f94SStefano Zampini PetscInt* l2gmap_indices; 3347e7931f94SStefano Zampini const PetscInt* is_indices; 3348e7931f94SStefano Zampini MatType new_local_type; 3349e7931f94SStefano Zampini /* buffers */ 3350e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 335128143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 33529d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 3353e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 3354e7931f94SStefano Zampini /* MPI */ 335528143c3dSStefano Zampini MPI_Comm comm,comm_n; 335628143c3dSStefano Zampini PetscSubcomm subcomm; 3357e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 335828143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 335928143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 336028143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 336128143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 336228143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 3363e7931f94SStefano Zampini PetscErrorCode ierr; 3364e7931f94SStefano Zampini 3365e7931f94SStefano Zampini PetscFunctionBegin; 336628143c3dSStefano Zampini /* TODO: add missing checks */ 336728143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 336828143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 336928143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 337028143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 3371e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 337228143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 3373e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3374e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 3375e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 3376e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 3377e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 337828143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 337970cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 338070cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 338128143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 338270cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 338370cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 338470cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 338570cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 338670cf5478SStefano Zampini } 3387e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 3388e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 3389e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 3390e7931f94SStefano Zampini if (!is_sends) { 339128143c3dSStefano Zampini PetscBool pcontig = PETSC_TRUE; 339228143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 339328143c3dSStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,pcontig,&is_sends_internal);CHKERRQ(ierr); 3394c8587f34SStefano Zampini } else { 3395e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 3396e7931f94SStefano Zampini is_sends_internal = is_sends; 3397c8587f34SStefano Zampini } 3398e7931f94SStefano Zampini 3399e7931f94SStefano Zampini /* get pointer of MATIS data */ 3400e7931f94SStefano Zampini matis = (Mat_IS*)mat->data; 3401e7931f94SStefano Zampini 3402e7931f94SStefano Zampini /* get comm */ 3403a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 3404e7931f94SStefano Zampini 3405e7931f94SStefano Zampini /* compute number of sends */ 3406e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 3407e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 3408e7931f94SStefano Zampini 3409e7931f94SStefano Zampini /* compute number of receives */ 3410e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 3411785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 3412e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 3413e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3414e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 3415e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 3416e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 3417e7931f94SStefano Zampini 341828143c3dSStefano Zampini /* restrict comm if requested */ 341928143c3dSStefano Zampini subcomm = 0; 342028143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 342128143c3dSStefano Zampini if (restrict_comm) { 342228143c3dSStefano Zampini PetscMPIInt color,rank,subcommsize; 342328143c3dSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 342428143c3dSStefano Zampini color = 0; 342528143c3dSStefano Zampini if (n_sends && !n_recvs) color = 1; /* sending only processes will not partecipate in new comm */ 342628143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 342728143c3dSStefano Zampini subcommsize = commsize - subcommsize; 342828143c3dSStefano Zampini /* check if reuse has been requested */ 342928143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 343028143c3dSStefano Zampini if (*mat_n) { 343128143c3dSStefano Zampini PetscMPIInt subcommsize2; 343228143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 343328143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 343428143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 343528143c3dSStefano Zampini } else { 343628143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 343728143c3dSStefano Zampini } 343828143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 343928143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 344028143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 344128143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 344228143c3dSStefano Zampini comm_n = subcomm->comm; 344328143c3dSStefano Zampini } 344428143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 344528143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 344628143c3dSStefano Zampini } else { 344728143c3dSStefano Zampini comm_n = comm; 344828143c3dSStefano Zampini } 344928143c3dSStefano Zampini 3450e7931f94SStefano Zampini /* prepare send/receive buffers */ 3451785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 3452e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 3453785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 3454e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 345528143c3dSStefano Zampini if (nis) { 3456854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 345728143c3dSStefano Zampini } 3458e7931f94SStefano Zampini 345928143c3dSStefano Zampini /* Get data from local matrices */ 3460e7931f94SStefano Zampini if (!isdense) { 3461a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 3462e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 3463e7931f94SStefano Zampini /* 3464e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 3465e7931f94SStefano Zampini send_buffer_idxs should contain: 3466e7931f94SStefano Zampini - MatType_PRIVATE type 3467e7931f94SStefano Zampini - PetscInt size_of_l2gmap 3468e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 3469e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 3470e7931f94SStefano Zampini */ 3471e7931f94SStefano Zampini } else { 3472e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 3473e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->mapping,&i);CHKERRQ(ierr); 3474854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 3475e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 3476e7931f94SStefano Zampini send_buffer_idxs[1] = i; 3477e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 3478e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 3479e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 3480e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 3481e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 3482e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 3483e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 3484c8587f34SStefano Zampini } 3485c8587f34SStefano Zampini } 3486e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 348728143c3dSStefano Zampini /* additional is (if any) */ 348828143c3dSStefano Zampini if (nis) { 348928143c3dSStefano Zampini PetscMPIInt psum; 349028143c3dSStefano Zampini PetscInt j; 349128143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 349228143c3dSStefano Zampini PetscInt plen; 349328143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 349428143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 349528143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 349628143c3dSStefano Zampini } 3497854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 349828143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 349928143c3dSStefano Zampini PetscInt plen; 350028143c3dSStefano Zampini const PetscInt *is_array_idxs; 350128143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 350228143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 350328143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 350428143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 350528143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 350628143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 350728143c3dSStefano Zampini } 350828143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 350928143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 351028143c3dSStefano Zampini } 351128143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 351228143c3dSStefano Zampini } 351328143c3dSStefano Zampini 3514e7931f94SStefano Zampini buf_size_idxs = 0; 3515e7931f94SStefano Zampini buf_size_vals = 0; 351628143c3dSStefano Zampini buf_size_idxs_is = 0; 3517e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3518e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 3519e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 352028143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 3521e7931f94SStefano Zampini } 3522785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 3523785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 352495ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 3525e7931f94SStefano Zampini 3526e7931f94SStefano Zampini /* get new tags for clean communications */ 3527e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 3528e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 352928143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 3530e7931f94SStefano Zampini 3531e7931f94SStefano Zampini /* allocate for requests */ 3532785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 3533785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 353495ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 3535785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 3536785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 353795ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 3538e7931f94SStefano Zampini 3539e7931f94SStefano Zampini /* communications */ 3540e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 3541e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 354228143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 3543e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3544e7931f94SStefano Zampini source_dest = onodes[i]; 3545e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 3546e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 3547e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3548e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 354928143c3dSStefano Zampini if (nis) { 355028143c3dSStefano 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); 355128143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 355228143c3dSStefano Zampini } 3553e7931f94SStefano Zampini } 3554e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 3555e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 3556e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 3557e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 355828143c3dSStefano Zampini if (nis) { 355928143c3dSStefano 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); 356028143c3dSStefano Zampini } 3561e7931f94SStefano Zampini } 3562e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3563e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 3564e7931f94SStefano Zampini 3565e7931f94SStefano Zampini /* assemble new l2g map */ 3566e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3567e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 35689d30be91SStefano Zampini new_local_rows = 0; 3569e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 35709d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 3571e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3572e7931f94SStefano Zampini } 35739d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 3574e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 35759d30be91SStefano Zampini new_local_rows = 0; 3576e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 35779d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 35789d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 3579e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3580e7931f94SStefano Zampini } 35819d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 35829d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 3583e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 3584e7931f94SStefano Zampini 3585e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 3586e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 3587e7931f94SStefano 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) */ 3588e7931f94SStefano Zampini if (n_recvs) { 358928143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 3590e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 3591e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3592e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 3593e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 3594e7931f94SStefano Zampini break; 3595e7931f94SStefano Zampini } 3596e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3597e7931f94SStefano Zampini } 3598e7931f94SStefano Zampini switch (new_local_type_private) { 359928143c3dSStefano Zampini case MATDENSE_PRIVATE: 360028143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 3601e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 3602e7931f94SStefano Zampini bs = 1; 360328143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 360428143c3dSStefano Zampini new_local_type = MATSEQDENSE; 360528143c3dSStefano Zampini bs = 1; 360628143c3dSStefano Zampini } 3607e7931f94SStefano Zampini break; 3608e7931f94SStefano Zampini case MATAIJ_PRIVATE: 3609e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 3610e7931f94SStefano Zampini bs = 1; 3611e7931f94SStefano Zampini break; 3612e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 3613e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 3614e7931f94SStefano Zampini break; 3615e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 3616e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 3617e7931f94SStefano Zampini break; 3618e7931f94SStefano Zampini default: 36199d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 3620e7931f94SStefano Zampini break; 3621e7931f94SStefano Zampini } 362228143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 362328143c3dSStefano Zampini new_local_type = MATSEQDENSE; 362428143c3dSStefano Zampini bs = 1; 3625e7931f94SStefano Zampini } 3626e7931f94SStefano Zampini 362770cf5478SStefano Zampini /* create MATIS object if needed */ 362870cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 3629e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 363028143c3dSStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,mat_n);CHKERRQ(ierr); 363170cf5478SStefano Zampini } else { 363270cf5478SStefano Zampini /* it also destroys the local matrices */ 363370cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 363470cf5478SStefano Zampini } 363570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 3636e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 36379d30be91SStefano Zampini 36389d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 36399d30be91SStefano Zampini 36409d30be91SStefano Zampini /* Global to local map of received indices */ 36419d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 36429d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 36439d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 36449d30be91SStefano Zampini 36459d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 36469d30be91SStefano Zampini buf_size_idxs = 0; 36479d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 36489d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 36499d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 36509d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 36519d30be91SStefano Zampini } 36529d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 36539d30be91SStefano Zampini 36549d30be91SStefano Zampini /* set preallocation */ 36559d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 36569d30be91SStefano Zampini if (!newisdense) { 36579d30be91SStefano Zampini PetscInt *new_local_nnz=0; 36589d30be91SStefano Zampini 36599d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 36609d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 36619d30be91SStefano Zampini if (n_recvs) { 36629d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 36639d30be91SStefano Zampini } 36649d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 36659d30be91SStefano Zampini PetscInt j; 36669d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 36679d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 36689d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 36699d30be91SStefano Zampini } 36709d30be91SStefano Zampini } else { 36719d30be91SStefano Zampini /* TODO */ 36729d30be91SStefano Zampini } 36739d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 36749d30be91SStefano Zampini } 36759d30be91SStefano Zampini if (new_local_nnz) { 36769d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 36779d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 36789d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 36799d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 36809d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 36819d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 36829d30be91SStefano Zampini } else { 36839d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 36849d30be91SStefano Zampini } 36859d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 36869d30be91SStefano Zampini } else { 36879d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 36889d30be91SStefano Zampini } 3689e7931f94SStefano Zampini 3690e7931f94SStefano Zampini /* set values */ 3691e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 36929d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 3693e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3694e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 3695e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 36969d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 3697e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 3698e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 3699e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 370028143c3dSStefano Zampini } else { 370128143c3dSStefano Zampini /* TODO */ 3702e7931f94SStefano Zampini } 3703e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3704e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 3705e7931f94SStefano Zampini } 3706e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3707e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 370870cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 370970cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 37109d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 37119d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 3712e7931f94SStefano Zampini 3713dfd14d43SStefano Zampini #if 0 371428143c3dSStefano Zampini if (!restrict_comm) { /* check */ 3715e7931f94SStefano Zampini Vec lvec,rvec; 3716e7931f94SStefano Zampini PetscReal infty_error; 3717e7931f94SStefano Zampini 37182a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 3719e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 3720e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 3721e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 372270cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 3723e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 3724e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 3725e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 3726e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 3727e7931f94SStefano Zampini } 372828143c3dSStefano Zampini #endif 3729e7931f94SStefano Zampini 373028143c3dSStefano Zampini /* assemble new additional is (if any) */ 373128143c3dSStefano Zampini if (nis) { 373228143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 373328143c3dSStefano Zampini 373428143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3735854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 373628143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 373728143c3dSStefano Zampini psum = 0; 373828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 373928143c3dSStefano Zampini for (j=0;j<nis;j++) { 374028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 374128143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 374228143c3dSStefano Zampini psum += plen; 374328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 374428143c3dSStefano Zampini } 374528143c3dSStefano Zampini } 3746854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 3747854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 374828143c3dSStefano Zampini for (i=1;i<nis;i++) { 374928143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 375028143c3dSStefano Zampini } 375128143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 375228143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 375328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 375428143c3dSStefano Zampini for (j=0;j<nis;j++) { 375528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 375628143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 375728143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 375828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 375928143c3dSStefano Zampini } 376028143c3dSStefano Zampini } 376128143c3dSStefano Zampini for (i=0;i<nis;i++) { 376228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 376328143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 376428143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 376528143c3dSStefano Zampini } 376628143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 376728143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 376828143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 376928143c3dSStefano Zampini } 3770e7931f94SStefano Zampini /* free workspace */ 377128143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 3772e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3773e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 3774e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3775e7931f94SStefano Zampini if (isdense) { 3776e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3777e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 3778e7931f94SStefano Zampini } else { 3779e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 3780e7931f94SStefano Zampini } 378128143c3dSStefano Zampini if (nis) { 378228143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 378328143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 378428143c3dSStefano Zampini } 3785e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 3786e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 378728143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 3788e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 3789e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 379028143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 3791e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 3792e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 3793e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 3794e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 3795e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 379628143c3dSStefano Zampini if (nis) { 379728143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 379828143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 379928143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 380028143c3dSStefano Zampini } 380128143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 380228143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 380328143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 380428143c3dSStefano Zampini for (i=0;i<nis;i++) { 380528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 380628143c3dSStefano Zampini } 380728143c3dSStefano Zampini } 3808e7931f94SStefano Zampini PetscFunctionReturn(0); 3809e7931f94SStefano Zampini } 3810a57a6d2fSStefano Zampini 381112edc857SStefano Zampini /* temporary hack into ksp private data structure */ 381212edc857SStefano Zampini #include <petsc-private/kspimpl.h> 381312edc857SStefano Zampini 3814c8587f34SStefano Zampini #undef __FUNCT__ 3815c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 3816c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 3817c8587f34SStefano Zampini { 3818c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3819c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 382020a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 38219881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 382220a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 38236e683305SStefano Zampini IS coarse_is,*isarray; 38246e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 38256e683305SStefano Zampini PetscInt nis,nisdofs,nisneu; 3826f9eb5b7dSStefano Zampini PC pc_temp; 3827c8587f34SStefano Zampini PCType coarse_pc_type; 3828c8587f34SStefano Zampini KSPType coarse_ksp_type; 3829f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 38304f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 38316e683305SStefano Zampini Mat t_coarse_mat_is; 38326e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 38336e683305SStefano Zampini PetscMPIInt all_procs; 383474e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 383568457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 383622bc73bbSStefano Zampini PetscScalar *array; 38379881197aSStefano Zampini PetscErrorCode ierr; 3838fdc09c96SStefano Zampini 3839c8587f34SStefano Zampini PetscFunctionBegin; 3840c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 384168457ee5SStefano 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 */ 384268457ee5SStefano Zampini compute_vecs = PETSC_TRUE; 3843fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 3844fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 3845f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 3846f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 3847f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 3848fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 3849fa7f1dd8SStefano Zampini if (ocoarse_size != pcbddc->coarse_size) { /* ...but with different size, so reset it and set reuse flag to false */ 3850727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3851fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 3852fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 3853fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 3854f4ddd8eeSStefano Zampini } 3855fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 3856fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 3857f4ddd8eeSStefano Zampini } 385870cf5478SStefano Zampini /* reset any subassembling information */ 385970cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 38606e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 38616e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 3862fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 3863f4ddd8eeSStefano Zampini } 3864c8587f34SStefano Zampini 38656e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 38662b510759SStefano Zampini im_active = !!(pcis->n); 38672b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 38686e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 38696e683305SStefano Zampini void_procs = all_procs-active_procs; 38706e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 387174e2c79eSStefano Zampini redist = PETSC_FALSE; 387222bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 38736e683305SStefano Zampini csin_ml = PETSC_TRUE; 38746e683305SStefano Zampini ncoarse_ml = void_procs; 38756e683305SStefano Zampini csin_ds = PETSC_TRUE; 38766e683305SStefano Zampini ncoarse_ds = void_procs; 38776e683305SStefano Zampini } else { 38786e683305SStefano Zampini csin_ml = PETSC_FALSE; 38796e683305SStefano Zampini ncoarse_ml = all_procs; 38806e683305SStefano Zampini if (void_procs) { 38816e683305SStefano Zampini csin_ds = PETSC_TRUE; 38826e683305SStefano Zampini ncoarse_ds = void_procs; 38836e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 38846e683305SStefano Zampini } else { 388574e2c79eSStefano Zampini if (pcbddc->redistribute_coarse && pcbddc->redistribute_coarse < all_procs) { 388674e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 388774e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 388874e2c79eSStefano Zampini redist = PETSC_TRUE; 388974e2c79eSStefano Zampini } else { 38906e683305SStefano Zampini csin_ds = PETSC_FALSE; 38916e683305SStefano Zampini ncoarse_ds = all_procs; 38926e683305SStefano Zampini } 38936e683305SStefano Zampini } 389474e2c79eSStefano Zampini } 38956e683305SStefano Zampini 38966e683305SStefano Zampini /* 38976e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 38986e683305SStefano Zampini - we have not exceeded the number of levels requested 38996e683305SStefano Zampini - we can actually subassemble the active processes 39006e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 39016e683305SStefano Zampini */ 39026e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 39036e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 39046e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 39056e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 39066e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 3907f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 39082b510759SStefano Zampini } else { 3909f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 3910c8587f34SStefano Zampini } 3911c8587f34SStefano Zampini } 39126e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 39136e683305SStefano Zampini if (multilevel_allowed) { 39146e683305SStefano Zampini ncoarse = ncoarse_ml; 39156e683305SStefano Zampini csin = csin_ml; 39166e683305SStefano Zampini } else { 39176e683305SStefano Zampini ncoarse = ncoarse_ds; 39186e683305SStefano Zampini csin = csin_ds; 39196e683305SStefano Zampini } 3920e7931f94SStefano Zampini 3921abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 3922abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 3923abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 3924abbbba34SStefano Zampini 3925abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 392622bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 392722bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 392822bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 392922bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 3930b9b85e73SStefano Zampini #if 0 3931b9b85e73SStefano Zampini { 3932b9b85e73SStefano Zampini PetscViewer viewer; 3933b9b85e73SStefano Zampini char filename[256]; 3934b9b85e73SStefano Zampini sprintf(filename,"local_coarse_mat%d.m",PetscGlobalRank); 3935b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 3936b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3937b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 3938b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3939b9b85e73SStefano Zampini } 3940b9b85e73SStefano Zampini #endif 39416e683305SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)pc),1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_islg,&t_coarse_mat_is);CHKERRQ(ierr); 39426e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 39436e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 39446e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3945abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 3946abbbba34SStefano Zampini 39476e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 39486e683305SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal) ) { /* protects from unneded computations */ 39496e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 39506e683305SStefano Zampini const PetscInt *idxs; 39516e683305SStefano Zampini ISLocalToGlobalMapping tmap; 39526e683305SStefano Zampini 39536e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 39540be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 39556e683305SStefano Zampini /* allocate space for temporary storage */ 3956854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 3957854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 39586e683305SStefano Zampini /* allocate for IS array */ 39596e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 39606e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 39616e683305SStefano Zampini nis = nisdofs + nisneu; 3962854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 39636e683305SStefano Zampini /* dofs splitting */ 39646e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 39656e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 39666e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 39676e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 39686e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 39696e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 39706e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 39716e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->ISForDofsLocal[i]),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 39726e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 39736e683305SStefano Zampini } 39746e683305SStefano Zampini /* neumann boundaries */ 39756e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 39766e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 39776e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 39786e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 39796e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 39806e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 39816e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 39826e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->NeumannBoundariesLocal),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 39836e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 39846e683305SStefano Zampini } 39856e683305SStefano Zampini /* free memory */ 39866e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 39876e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 39886e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 39896e683305SStefano Zampini } else { 39906e683305SStefano Zampini nis = 0; 39916e683305SStefano Zampini nisdofs = 0; 39926e683305SStefano Zampini nisneu = 0; 39936e683305SStefano Zampini isarray = NULL; 39946e683305SStefano Zampini } 39956e683305SStefano Zampini /* destroy no longer needed map */ 39966e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 39976e683305SStefano Zampini 39986e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 39996e683305SStefano Zampini coarse_mat_is = NULL; 40006e683305SStefano Zampini if (csin) { 40016e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 400274e2c79eSStefano Zampini if (redist) { 400374e2c79eSStefano Zampini PetscMPIInt rank; 400474e2c79eSStefano Zampini PetscInt spc,n_spc_p1,dest[1]; 400574e2c79eSStefano Zampini 400674e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 400774e2c79eSStefano Zampini spc = all_procs/pcbddc->redistribute_coarse; 400874e2c79eSStefano Zampini n_spc_p1 = all_procs%pcbddc->redistribute_coarse; 400974e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 401074e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 401174e2c79eSStefano Zampini } else { 401274e2c79eSStefano Zampini dest[0] = rank/(spc+1); 401374e2c79eSStefano Zampini } 401474e2c79eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),1,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 401574e2c79eSStefano Zampini } else { 40166e683305SStefano Zampini PetscInt j,tissize,*nisindices; 40176e683305SStefano Zampini PetscInt *coarse_candidates; 40186e683305SStefano Zampini const PetscInt* tisindices; 40196e683305SStefano Zampini /* get coarse candidates' ranks in pc communicator */ 4020854ce69bSBarry Smith ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 40216e683305SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 40226e683305SStefano Zampini for (i=0,j=0;i<all_procs;i++) { 40236e683305SStefano Zampini if (!coarse_candidates[i]) { 40246e683305SStefano Zampini coarse_candidates[j]=i; 40256e683305SStefano Zampini j++; 40266e683305SStefano Zampini } 40276e683305SStefano Zampini } 40286e683305SStefano Zampini if (j < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",j,ncoarse); 40296e683305SStefano Zampini /* get a suitable subassembling pattern */ 40306e683305SStefano Zampini if (csin_type_simple) { 40316e683305SStefano Zampini PetscMPIInt rank; 40326e683305SStefano Zampini PetscInt issize,isidx; 40336e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 40346e683305SStefano Zampini if (im_active) { 40356e683305SStefano Zampini issize = 1; 40366e683305SStefano Zampini isidx = (PetscInt)rank; 40376e683305SStefano Zampini } else { 40386e683305SStefano Zampini issize = 0; 40396e683305SStefano Zampini isidx = -1; 40406e683305SStefano Zampini } 40416e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 40426e683305SStefano Zampini } else { 40436e683305SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,PETSC_TRUE,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 40446e683305SStefano Zampini } 40456e683305SStefano Zampini if (pcbddc->dbg_flag) { 40466e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 40476e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 40486e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 40496e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 40506e683305SStefano Zampini for (i=0;i<j;i++) { 40516e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 40526e683305SStefano Zampini } 40536e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 40546e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 40556e683305SStefano Zampini } 40566e683305SStefano Zampini /* shift the pattern on coarse candidates */ 40576e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 40586e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 4059854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 40606e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 40616e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 40626e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 40636e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 40646e683305SStefano Zampini } 406574e2c79eSStefano Zampini } 40666e683305SStefano Zampini if (pcbddc->dbg_flag) { 40676e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 40686e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 40696e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 40706e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 40716e683305SStefano Zampini } 40726e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 40736e683305SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 40746e683305SStefano Zampini } else { 40756e683305SStefano Zampini if (pcbddc->dbg_flag) { 40766e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 40776e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 40786e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 40796e683305SStefano Zampini } 40806e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 40816e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 40826e683305SStefano Zampini } 40836e683305SStefano Zampini 40846e683305SStefano Zampini /* create local to global scatters for coarse problem */ 408568457ee5SStefano Zampini if (compute_vecs) { 40866e683305SStefano Zampini PetscInt lrows; 40876e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 40886e683305SStefano Zampini if (coarse_mat_is) { 40896e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 40906e683305SStefano Zampini } else { 40916e683305SStefano Zampini lrows = 0; 40926e683305SStefano Zampini } 40936e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 40946e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 40956e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 40966e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 40976e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 40986e683305SStefano Zampini } 40996e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 41006e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 4101c8587f34SStefano Zampini 4102f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 4103f9eb5b7dSStefano Zampini if (multilevel_allowed) { 4104f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 4105f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 4106f9eb5b7dSStefano Zampini } else { 4107f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 4108f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 4109c8587f34SStefano Zampini } 4110c8587f34SStefano Zampini 41116e683305SStefano Zampini /* print some info if requested */ 41126e683305SStefano Zampini if (pcbddc->dbg_flag) { 41136e683305SStefano Zampini if (!multilevel_allowed) { 41146e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 41156e683305SStefano Zampini if (multilevel_requested) { 41166e683305SStefano 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); 41176e683305SStefano Zampini } else if (pcbddc->max_levels) { 41186e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 41196e683305SStefano Zampini } 41206e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 41216e683305SStefano Zampini } 41226e683305SStefano Zampini } 41236e683305SStefano Zampini 4124f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 41256e683305SStefano Zampini if (coarse_mat_is) { 41266e683305SStefano Zampini MatReuse coarse_mat_reuse; 41276a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 41286e683305SStefano Zampini if (pcbddc->dbg_flag) { 41296e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 41306e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 41316e683305SStefano Zampini } 4132f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 4133312be037SStefano Zampini char prefix[256],str_level[16]; 4134e604994aSStefano Zampini size_t len; 41356e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 4136c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 4137f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 41385f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 4139c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 41406e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 4141c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 4142c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4143e604994aSStefano Zampini /* prefix */ 4144e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 4145e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4146e604994aSStefano Zampini if (!pcbddc->current_level) { 4147e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4148e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 4149c8587f34SStefano Zampini } else { 4150e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4151312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4152312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 415334d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4154312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4155e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 4156e604994aSStefano Zampini } 4157e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 4158f9eb5b7dSStefano Zampini /* allow user customization */ 4159f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 41607e0def11SStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4161312be037SStefano Zampini } 4162f9eb5b7dSStefano Zampini 4163f9eb5b7dSStefano Zampini /* get some info after set from options */ 4164f9eb5b7dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 4165f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 4166f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 41674f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 41686e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 4169f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4170f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 4171f9eb5b7dSStefano Zampini } 41724f3a063dSStefano Zampini if (isredundant) { 41734f3a063dSStefano Zampini KSP inner_ksp; 41744f3a063dSStefano Zampini PC inner_pc; 41754f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 41764f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 41774f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 41784f3a063dSStefano Zampini } 4179f9eb5b7dSStefano Zampini 41806e683305SStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 4181f9eb5b7dSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 4182f9eb5b7dSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 4183f9eb5b7dSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 41846e683305SStefano Zampini if (nisdofs) { 41856e683305SStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 41866e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 41876e683305SStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 41881035eff8SStefano Zampini } 41891035eff8SStefano Zampini } 41906e683305SStefano Zampini if (nisneu) { 41916e683305SStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 41926e683305SStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 41931035eff8SStefano Zampini } 4194fdc09c96SStefano Zampini 4195f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 4196fa7f1dd8SStefano Zampini if (coarse_reuse) { 419781d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 4198fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 41996e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 4200fa7f1dd8SStefano Zampini } else { 42016e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 4202fa7f1dd8SStefano Zampini } 4203c8587f34SStefano Zampini if (isbddc || isnn) { 420422bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 420570cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 420628143c3dSStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,PETSC_TRUE,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 420722b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 42086e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 42096e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 42106e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 42116e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 421222b6e8a2SStefano Zampini } 421370cf5478SStefano Zampini } 42146e683305SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 421570cf5478SStefano Zampini } else { 421622bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 421722bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 421822bc73bbSStefano Zampini } 421922bc73bbSStefano Zampini } else { 42202e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 4221c8587f34SStefano Zampini } 4222c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 4223c8587f34SStefano Zampini 4224c8587f34SStefano Zampini /* propagate symmetry info to coarse matrix */ 4225b9d89cd5SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pcbddc->issym);CHKERRQ(ierr); 42265a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 4227c8587f34SStefano Zampini 42286e683305SStefano Zampini /* set operators */ 42295f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 42306e683305SStefano Zampini if (pcbddc->dbg_flag) { 42316e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 42326e683305SStefano Zampini } 42336e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 42346e683305SStefano Zampini coarse_mat = 0; 42356e683305SStefano Zampini } 42366e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 4237b9b85e73SStefano Zampini #if 0 4238b9b85e73SStefano Zampini { 4239b9b85e73SStefano Zampini PetscViewer viewer; 4240b9b85e73SStefano Zampini char filename[256]; 4241b9b85e73SStefano Zampini sprintf(filename,"coarse_mat.m"); 4242b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,filename,&viewer);CHKERRQ(ierr); 4243b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4244b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 4245b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4246b9b85e73SStefano Zampini } 4247b9b85e73SStefano Zampini #endif 4248c8587f34SStefano Zampini 4249c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 4250c8587f34SStefano Zampini if (pcbddc->NullSpace) { 4251c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 425298a51de6SStefano Zampini } 425398a51de6SStefano Zampini 425498a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 425598a51de6SStefano Zampini Vec crhs,csol; 425698a51de6SStefano Zampini PetscBool ispreonly; 425798a51de6SStefano Zampini if (CoarseNullSpace) { 4258c8587f34SStefano Zampini if (isbddc) { 4259c8587f34SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 4260c8587f34SStefano Zampini } else { 4261c8587f34SStefano Zampini ierr = KSPSetNullSpace(pcbddc->coarse_ksp,CoarseNullSpace);CHKERRQ(ierr); 4262c8587f34SStefano Zampini } 4263c8587f34SStefano Zampini } 4264f9eb5b7dSStefano Zampini /* setup coarse ksp */ 4265f9eb5b7dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 4266f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 4267f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 42686e683305SStefano Zampini /* hack */ 4269f347579bSStefano Zampini if (!csol) { 42702a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 4271f9eb5b7dSStefano Zampini } 4272f347579bSStefano Zampini if (!crhs) { 42732a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 4274f347579bSStefano Zampini } 4275cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 4276cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 42776e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 4278c8587f34SStefano Zampini KSP check_ksp; 42792b510759SStefano Zampini KSPType check_ksp_type; 4280c8587f34SStefano Zampini PC check_pc; 42816e683305SStefano Zampini Vec check_vec,coarse_vec; 42826a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 42832b510759SStefano Zampini PetscInt its; 42846e683305SStefano Zampini PetscBool compute_eigs; 42856e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 42866e683305SStefano Zampini PetscInt neigs; 42878e185a42SStefano Zampini const char *prefix; 4288c8587f34SStefano Zampini 42892b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 42906e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 429123ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 4292f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 42932b510759SStefano Zampini if (ispreonly) { 42942b510759SStefano Zampini check_ksp_type = KSPPREONLY; 42956e683305SStefano Zampini compute_eigs = PETSC_FALSE; 42962b510759SStefano Zampini } else { 4297cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 42986e683305SStefano Zampini compute_eigs = PETSC_TRUE; 4299c8587f34SStefano Zampini } 4300c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 43016e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 43026e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 43036e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 4304a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 4305a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 4306a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 4307a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 4308c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 4309c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 4310c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 4311c8587f34SStefano Zampini /* create random vec */ 43126e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 43136e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 4314c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 4315c8587f34SStefano Zampini if (CoarseNullSpace) { 4316c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 4317c8587f34SStefano Zampini } 43186e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 4319c8587f34SStefano Zampini /* solve coarse problem */ 43206e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 4321c8587f34SStefano Zampini if (CoarseNullSpace) { 43226e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 4323c8587f34SStefano Zampini } 4324cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 43256e683305SStefano Zampini if (compute_eigs) { 4326854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 4327854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 43286e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 43296e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 43306e683305SStefano Zampini lambda_min = eigs_r[0]; 43316e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 43326e683305SStefano Zampini if (lambda_max>lambda_min) { 4333cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 4334cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 4335cbcc2c2aSStefano Zampini } 4336c8587f34SStefano Zampini } 4337c8587f34SStefano Zampini } 4338cbcc2c2aSStefano Zampini 4339c8587f34SStefano Zampini /* check coarse problem residual error */ 43406e683305SStefano Zampini if (pcbddc->dbg_flag) { 43416e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 43426e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 43436e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 4344c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 43456e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 43466e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 4347c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 43486e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (%d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 43496e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 43506e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 43516e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 43526e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 43536e683305SStefano Zampini if (compute_eigs) { 43546e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 4355deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 4356c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 43576e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 43586e683305SStefano 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); 43596e683305SStefano Zampini for (i=0;i<neigs;i++) { 43606e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 4361c8587f34SStefano Zampini } 43626e683305SStefano Zampini } 43636e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 43646e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 43656e683305SStefano Zampini } 4366c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 43676e683305SStefano Zampini if (compute_eigs) { 43686e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 43696e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 4370c8587f34SStefano Zampini } 43716e683305SStefano Zampini } 43726e683305SStefano Zampini } 4373cbcc2c2aSStefano Zampini /* print additional info */ 4374cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 43756e683305SStefano Zampini /* waits until all processes reaches this point */ 43766e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 4377cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 4378cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4379cbcc2c2aSStefano Zampini } 4380cbcc2c2aSStefano Zampini 43812b510759SStefano Zampini /* free memory */ 4382c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 4383fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 4384c8587f34SStefano Zampini PetscFunctionReturn(0); 4385c8587f34SStefano Zampini } 4386674ae819SStefano Zampini 4387f34684f1SStefano Zampini #undef __FUNCT__ 4388f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 4389f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 4390f34684f1SStefano Zampini { 4391f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4392f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 4393f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4394727cdba6SStefano Zampini PetscInt i,coarse_size; 4395727cdba6SStefano Zampini PetscInt *local_primal_indices; 4396f34684f1SStefano Zampini PetscErrorCode ierr; 4397f34684f1SStefano Zampini 4398f34684f1SStefano Zampini PetscFunctionBegin; 4399f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 440089c96988SStefano Zampini if (!pcbddc->primal_indices_local_idxs && pcbddc->local_primal_size) { 440189c96988SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Local primal indices have not been created"); 4402727cdba6SStefano Zampini } 4403727cdba6SStefano Zampini ierr = PCBDDCSubsetNumbering(PetscObjectComm((PetscObject)(pc->pmat)),matis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,NULL,&coarse_size,&local_primal_indices);CHKERRQ(ierr); 4404f34684f1SStefano Zampini 4405f34684f1SStefano Zampini /* check numbering */ 4406f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 4407f34684f1SStefano Zampini PetscScalar coarsesum,*array; 4408b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 4409f34684f1SStefano Zampini 4410f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4411f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4412f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 44130fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 4414f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 4415f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 4416727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 4417f34684f1SStefano Zampini } 4418f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 4419f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 4420f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4421f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4422f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4423f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4424f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4425f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4426f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 4427f34684f1SStefano Zampini if (array[i] == 1.0) { 4428b9b85e73SStefano Zampini set_error = PETSC_TRUE; 4429f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d: local index %d owned by a single process!\n",PetscGlobalRank,i);CHKERRQ(ierr); 4430f34684f1SStefano Zampini } 4431f34684f1SStefano Zampini } 4432b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4433f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4434f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 4435f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 4436f34684f1SStefano Zampini } 4437f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4438f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4439f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4440f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4441f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 4442f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 4443b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 4444f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 4445f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4446f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 4447f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 4448727cdba6SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_primal_indices[%d]=%d (%d)\n",i,local_primal_indices[i],pcbddc->primal_indices_local_idxs[i]); 4449f34684f1SStefano Zampini } 4450f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4451f34684f1SStefano Zampini } 4452f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4453b9b85e73SStefano Zampini if (set_error_reduced) { 4454b9b85e73SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 4455b9b85e73SStefano Zampini } 4456f34684f1SStefano Zampini } 4457f34684f1SStefano Zampini /* get back data */ 4458f34684f1SStefano Zampini *coarse_size_n = coarse_size; 4459f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 4460674ae819SStefano Zampini PetscFunctionReturn(0); 4461674ae819SStefano Zampini } 4462674ae819SStefano Zampini 4463e456f2a8SStefano Zampini #undef __FUNCT__ 4464e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 4465a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 4466e456f2a8SStefano Zampini { 4467e456f2a8SStefano Zampini IS localis_t; 4468a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 4469e456f2a8SStefano Zampini PetscScalar *vals; 4470e456f2a8SStefano Zampini PetscErrorCode ierr; 4471e456f2a8SStefano Zampini 4472e456f2a8SStefano Zampini PetscFunctionBegin; 4473a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 4474e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 4475854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 4476e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 4477e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 4478a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 4479a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 44801035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 4481a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 44821035eff8SStefano Zampini } 4483a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 4484e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 4485e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4486a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 4487a7dc3881SStefano Zampini /* now compute set in local ordering */ 4488a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4489a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4490a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 4491a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 4492a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 4493ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 4494e456f2a8SStefano Zampini lsize++; 4495e456f2a8SStefano Zampini } 4496e456f2a8SStefano Zampini } 4497854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 4498a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 4499ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 4500e456f2a8SStefano Zampini idxs[lsize++] = i; 4501e456f2a8SStefano Zampini } 4502e456f2a8SStefano Zampini } 4503a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 4504a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 4505e456f2a8SStefano Zampini *localis = localis_t; 4506e456f2a8SStefano Zampini PetscFunctionReturn(0); 4507e456f2a8SStefano Zampini } 4508906d46d4SStefano Zampini 4509906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 4510906d46d4SStefano Zampini #undef __FUNCT__ 4511906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 4512906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 4513906d46d4SStefano Zampini { 4514906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4515906d46d4SStefano Zampini PetscErrorCode ierr; 4516906d46d4SStefano Zampini 4517906d46d4SStefano Zampini PetscFunctionBegin; 4518906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 4519906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 4520906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 4521906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 4522906d46d4SStefano Zampini PetscFunctionReturn(0); 4523906d46d4SStefano Zampini } 4524906d46d4SStefano Zampini 4525906d46d4SStefano Zampini #undef __FUNCT__ 4526906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 4527906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 4528906d46d4SStefano Zampini { 4529906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4530906d46d4SStefano Zampini PetscErrorCode ierr; 4531906d46d4SStefano Zampini 4532906d46d4SStefano Zampini PetscFunctionBegin; 4533906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 4534906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 4535906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 4536906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 4537906d46d4SStefano Zampini PetscFunctionReturn(0); 4538906d46d4SStefano Zampini } 4539b96c3477SStefano Zampini 4540b96c3477SStefano Zampini #undef __FUNCT__ 4541b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 454208122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 4543b96c3477SStefano Zampini { 4544b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 4545b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4546b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 4547b96c3477SStefano Zampini PetscBool free_used_adj; 4548b96c3477SStefano Zampini PetscErrorCode ierr; 4549b96c3477SStefano Zampini 4550b96c3477SStefano Zampini PetscFunctionBegin; 4551b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 4552b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 455308122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 4554b96c3477SStefano Zampini used_xadj = NULL; 4555b96c3477SStefano Zampini used_adjncy = NULL; 4556b96c3477SStefano Zampini } else { 455708122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 455808122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 455908122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 456008122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 4561b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 4562b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 4563b96c3477SStefano Zampini } else { 4564b96c3477SStefano Zampini Mat mat_adj; 4565b96c3477SStefano Zampini PetscBool flg_row=PETSC_TRUE; 4566b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 4567b96c3477SStefano Zampini PetscInt nvtxs; 4568b96c3477SStefano Zampini 4569b96c3477SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 4570b96c3477SStefano Zampini ierr = MatGetRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4571b96c3477SStefano Zampini if (!flg_row) { 4572b96c3477SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 4573b96c3477SStefano Zampini } 4574b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 4575b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 4576b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 4577b96c3477SStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4578b96c3477SStefano Zampini if (!flg_row) { 4579b96c3477SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 4580b96c3477SStefano Zampini } 4581b96c3477SStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 4582b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 4583b96c3477SStefano Zampini } 4584b96c3477SStefano Zampini } 458508122e43SStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,pcbddc->adaptive_selection,pcbddc->use_deluxe_scaling,pcbddc->use_edges,pcbddc->use_faces);CHKERRQ(ierr); 4586b96c3477SStefano Zampini 4587b96c3477SStefano Zampini /* free adjacency */ 4588b96c3477SStefano Zampini if (free_used_adj) { 4589b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 4590b96c3477SStefano Zampini } 4591b96c3477SStefano Zampini PetscFunctionReturn(0); 4592b96c3477SStefano Zampini } 4593b96c3477SStefano Zampini 4594b96c3477SStefano Zampini #undef __FUNCT__ 4595b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 459608122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 4597b96c3477SStefano Zampini { 4598b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 4599b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 4600b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4601b96c3477SStefano Zampini PCBDDCGraph graph; 4602b96c3477SStefano Zampini Mat S_j; 4603b96c3477SStefano Zampini PetscErrorCode ierr; 4604b96c3477SStefano Zampini 4605b96c3477SStefano Zampini PetscFunctionBegin; 4606b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 460708122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 4608b96c3477SStefano Zampini IS verticesIS; 4609b96c3477SStefano Zampini 4610b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 4611b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 4612b96c3477SStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap);CHKERRQ(ierr); 4613b96c3477SStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticesIS);CHKERRQ(ierr); 4614b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 4615b96c3477SStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 4616b96c3477SStefano Zampini /* 4617b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 4618b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 4619b96c3477SStefano Zampini } 4620b96c3477SStefano Zampini */ 4621b96c3477SStefano Zampini } else { 4622b96c3477SStefano Zampini graph = pcbddc->mat_graph; 4623b96c3477SStefano Zampini } 4624b96c3477SStefano Zampini 4625b96c3477SStefano Zampini /* Create Schur complement matrix */ 4626b96c3477SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 4627b96c3477SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 4628b96c3477SStefano Zampini 4629b96c3477SStefano Zampini /* sub_schurs init */ 463008122e43SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcbddc->local_mat,S_j,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,pcbddc->sub_schurs_threshold);CHKERRQ(ierr); 4631b96c3477SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 4632b96c3477SStefano Zampini /* free graph struct */ 463308122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 4634b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 4635b96c3477SStefano Zampini } 4636b96c3477SStefano Zampini PetscFunctionReturn(0); 4637b96c3477SStefano Zampini } 4638