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; 82*a58a30b4SStefano Zampini eigs = NULL; 83*a58a30b4SStefano Zampini eigv = NULL; 84*a58a30b4SStefano Zampini B_iwork = NULL; 85*a58a30b4SStefano Zampini B_ifail = NULL; 8608122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 8708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 8808122e43SStefano 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)); 8908122e43SStefano Zampini #else 9008122e43SStefano 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)); 9108122e43SStefano Zampini #endif 9208122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 9308122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 9408122e43SStefano Zampini } else { 9508122e43SStefano Zampini /* TODO */ 9608122e43SStefano Zampini } 9708122e43SStefano Zampini } else { 9808122e43SStefano Zampini lwork = 0; 9908122e43SStefano Zampini } 10008122e43SStefano Zampini 10108122e43SStefano Zampini nv = 0; 10208122e43SStefano Zampini if (sub_schurs->is_Ej_com) { /* complement of subsets, each entry is a vertex */ 10308122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_Ej_com,&nv);CHKERRQ(ierr); 10408122e43SStefano Zampini } 10508122e43SStefano Zampini ierr = PetscBLASIntCast((PetscInt)lwork,&B_lwork);CHKERRQ(ierr); 10608122e43SStefano Zampini ierr = PetscMalloc7(mss*mss,&S,mss*mss,&St,mss*mss,&eigv,mss,&eigs, 10708122e43SStefano Zampini B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 10808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 10908122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 11008122e43SStefano Zampini #endif 11108122e43SStefano Zampini ierr = PetscMalloc2(mss*mss,&Smult,mss*mss,&Seigv);CHKERRQ(ierr); 11208122e43SStefano Zampini ierr = PetscMalloc4(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 11308122e43SStefano Zampini nv+cum2+1,&pcbddc->adaptive_constraints_ptrs, 11408122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 11508122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 11608122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 11708122e43SStefano Zampini 11808122e43SStefano Zampini maxneigs = 0; 11908122e43SStefano Zampini cum = cum2 = cumarray = 0; 12008122e43SStefano Zampini if (sub_schurs->is_Ej_com) { 12108122e43SStefano Zampini const PetscInt *idxs; 12208122e43SStefano Zampini 12308122e43SStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_com,&idxs);CHKERRQ(ierr); 12408122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 12508122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 12608122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 12708122e43SStefano Zampini pcbddc->adaptive_constraints_ptrs[cum] = cum; 12808122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 12908122e43SStefano Zampini } 13008122e43SStefano Zampini cum2 = cum; 13108122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_com,&idxs);CHKERRQ(ierr); 13208122e43SStefano Zampini } 13308122e43SStefano Zampini 13408122e43SStefano Zampini if (mss) { /* multilevel */ 13508122e43SStefano Zampini if (pcbddc->use_deluxe_scaling) { 13608122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 13708122e43SStefano Zampini } else { 13808122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_all,&Sarray);CHKERRQ(ierr); 13908122e43SStefano Zampini } 14008122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 14108122e43SStefano Zampini } 14208122e43SStefano Zampini 14308122e43SStefano Zampini cumsubs = 0; 14408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 14508122e43SStefano Zampini PetscInt j,subset_size; 14608122e43SStefano Zampini 14708122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 14808122e43SStefano Zampini if (PetscBTLookup(sub_schurs->computed_Stilda_subs,i)) { 14908122e43SStefano Zampini const PetscInt *idxs; 15008122e43SStefano Zampini PetscScalar one = 1.0,zero=0.0; 15108122e43SStefano Zampini PetscBLASInt B_N; 15208122e43SStefano Zampini 15308122e43SStefano Zampini /* S should be copied since we need it for deluxe scaling */ 15408122e43SStefano Zampini if (symmetric) { 15508122e43SStefano Zampini PetscInt j; 15608122e43SStefano Zampini for (j=0;j<subset_size;j++) { 15708122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 15808122e43SStefano Zampini } 15908122e43SStefano Zampini for (j=0;j<subset_size;j++) { 16008122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 16108122e43SStefano Zampini } 16208122e43SStefano Zampini } else { 16308122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 16408122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 16508122e43SStefano Zampini } 16608122e43SStefano Zampini /* is always this the right matrix? */ 16708122e43SStefano Zampini ierr = PetscMemcpy(Smult,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 16808122e43SStefano Zampini 16908122e43SStefano Zampini /* we could reuse space already allocated when building sum_S_Ej_tilda_all */ 17008122e43SStefano Zampini /* St = Starray+cumarray; */ 17108122e43SStefano Zampini 17208122e43SStefano Zampini if (symmetric) { 17308122e43SStefano Zampini PetscBLASInt B_itype = 1; 17408122e43SStefano Zampini PetscBLASInt B_IL = 1, B_IU; 17508122e43SStefano Zampini PetscScalar eps = -1.0; /* dlamch? */ 17608122e43SStefano Zampini 17708122e43SStefano Zampini /* ask for eigenvalues lower than thresh */ 17808122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] Computing for sub %d/%d.\n",PetscGlobalRank,i,sub_schurs->n_subs); 17908122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 18008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 18108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 18208122e43SStefano 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)); 18308122e43SStefano Zampini #else 18408122e43SStefano 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)); 18508122e43SStefano Zampini #endif 18608122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 18708122e43SStefano Zampini if (B_ierr) { 18808122e43SStefano Zampini if (B_ierr < 0 ) { 18908122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 19008122e43SStefano Zampini } else if (B_ierr <= B_N) { 19108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 19208122e43SStefano Zampini } else { 19308122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d principal minor not posdef",(int)B_ierr-B_N-1); 19408122e43SStefano Zampini } 19508122e43SStefano Zampini } 19608122e43SStefano Zampini 19708122e43SStefano Zampini if (B_neigs > nmax) { 19808122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] found %d eigs, more than required %d.\n",PetscGlobalRank,B_neigs,nmax); 19908122e43SStefano Zampini B_neigs = nmax; 20008122e43SStefano Zampini } 20108122e43SStefano Zampini 20208122e43SStefano Zampini if (B_neigs < nmin) { 20308122e43SStefano Zampini PetscBLASInt B_neigs2; 20408122e43SStefano Zampini 20508122e43SStefano Zampini B_IL = B_neigs + 1; 20608122e43SStefano Zampini ierr = PetscBLASIntCast(nmin,&B_IU);CHKERRQ(ierr); 20708122e43SStefano 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); 20808122e43SStefano Zampini if (symmetric) { 20908122e43SStefano Zampini PetscInt j; 21008122e43SStefano Zampini for (j=0;j<subset_size;j++) { 21108122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 21208122e43SStefano Zampini } 21308122e43SStefano Zampini for (j=0;j<subset_size;j++) { 21408122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 21508122e43SStefano Zampini } 21608122e43SStefano Zampini } else { 21708122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 21808122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 21908122e43SStefano Zampini } 22008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 22108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 22208122e43SStefano 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)); 22308122e43SStefano Zampini #else 22408122e43SStefano 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)); 22508122e43SStefano Zampini #endif 22608122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 22708122e43SStefano Zampini B_neigs += B_neigs2; 22808122e43SStefano Zampini } 22908122e43SStefano Zampini if (B_ierr) { 23008122e43SStefano Zampini if (B_ierr < 0 ) { 23108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 23208122e43SStefano Zampini } else if (B_ierr <= B_N) { 23308122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 23408122e43SStefano Zampini } else { 23508122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d principal minor not posdef",(int)B_ierr-B_N-1); 23608122e43SStefano Zampini } 23708122e43SStefano Zampini } 23808122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] -> Got %d eigs\n",PetscGlobalRank,B_neigs); 23908122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 24008122e43SStefano Zampini if (eigs[j] == 0.0) { 24108122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] Inf\n",PetscGlobalRank); 24208122e43SStefano Zampini } else { 24308122e43SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] %1.6e\n",PetscGlobalRank,1.0/eigs[j]); 24408122e43SStefano Zampini } 24508122e43SStefano Zampini } 24608122e43SStefano Zampini } else { 24708122e43SStefano Zampini /* TODO */ 24808122e43SStefano Zampini } 24908122e43SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 25008122e43SStefano Zampini pcbddc->adaptive_constraints_n[cumsubs+nv] = B_neigs; 25108122e43SStefano Zampini cumsubs++; 25208122e43SStefano Zampini 25308122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 25408122e43SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&B_N,&B_neigs,&B_N,&one,Smult,&B_N,eigv,&B_N,&zero,Seigv,&B_N)); 25508122e43SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_data+cum2,Seigv,B_neigs*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 25608122e43SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 25708122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 25808122e43SStefano Zampini #if 0 25908122e43SStefano Zampini { 26008122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 26108122e43SStefano Zampini PetscScalar norm; 26208122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 26308122e43SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+cum2,&Blas_one,pcbddc->adaptive_constraints_data+cum2,&Blas_one)); 26408122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 26508122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 26608122e43SStefano Zampini } else { 26708122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 26808122e43SStefano Zampini } 26908122e43SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+cum2,&Blas_one)); 270b1b3d7a2SStefano Zampini } 271b1b3d7a2SStefano Zampini #endif 27208122e43SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+cum2,idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 27308122e43SStefano Zampini pcbddc->adaptive_constraints_ptrs[cum++] = cum2; 27408122e43SStefano Zampini cum2 += subset_size; 27508122e43SStefano Zampini } 27608122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 27708122e43SStefano Zampini } 27808122e43SStefano Zampini /* shift for next computation */ 27908122e43SStefano Zampini cumarray += subset_size*subset_size; 28008122e43SStefano Zampini } 28108122e43SStefano Zampini pcbddc->adaptive_constraints_ptrs[cum] = cum2; 28208122e43SStefano Zampini ierr = PetscFree2(Smult,Seigv);CHKERRQ(ierr); 28308122e43SStefano Zampini 28408122e43SStefano Zampini if (mss) { 28508122e43SStefano Zampini if (pcbddc->use_deluxe_scaling) { 28608122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 28708122e43SStefano Zampini } else { 28808122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_all,&Sarray);CHKERRQ(ierr); 28908122e43SStefano Zampini } 29008122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 29108122e43SStefano Zampini } 29208122e43SStefano Zampini ierr = PetscFree7(S,St,eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 29308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 29408122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 29508122e43SStefano Zampini #endif 29608122e43SStefano Zampini if (pcbddc->dbg_flag) { 29708122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 29808122e43SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 29908122e43SStefano Zampini } 30008122e43SStefano Zampini PetscFunctionReturn(0); 30108122e43SStefano Zampini } 302b1b3d7a2SStefano Zampini 303674ae819SStefano Zampini #undef __FUNCT__ 304c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 305c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 306c8587f34SStefano Zampini { 307c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3088629588bSStefano Zampini PetscScalar *coarse_submat_vals; 309c8587f34SStefano Zampini PetscErrorCode ierr; 310c8587f34SStefano Zampini 311c8587f34SStefano Zampini PetscFunctionBegin; 312f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 3135e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 314c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 315c8587f34SStefano Zampini 316684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 3170fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 318684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 319c8587f34SStefano Zampini 320c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 321b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 322c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 323c8587f34SStefano Zampini } 324c8587f34SStefano Zampini 3258629588bSStefano Zampini /* 3268629588bSStefano Zampini Setup local correction and local part of coarse basis. 3278629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 3288629588bSStefano Zampini */ 32947f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 3308629588bSStefano Zampini 3318629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 3328629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 3338629588bSStefano Zampini 3348629588bSStefano Zampini /* free */ 3358629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 336c8587f34SStefano Zampini PetscFunctionReturn(0); 337c8587f34SStefano Zampini } 338c8587f34SStefano Zampini 339c8587f34SStefano Zampini #undef __FUNCT__ 340674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 341674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 342674ae819SStefano Zampini { 343674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 344674ae819SStefano Zampini PetscErrorCode ierr; 345674ae819SStefano Zampini 346674ae819SStefano Zampini PetscFunctionBegin; 347674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 348674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 349674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 350674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 351785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 352674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 353f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 354f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 355785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 35663602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 35763602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 358674ae819SStefano Zampini PetscFunctionReturn(0); 359674ae819SStefano Zampini } 360674ae819SStefano Zampini 361674ae819SStefano Zampini #undef __FUNCT__ 362674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 363674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 364674ae819SStefano Zampini { 365674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 366674ae819SStefano Zampini PetscErrorCode ierr; 367674ae819SStefano Zampini 368674ae819SStefano Zampini PetscFunctionBegin; 369b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 370674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 371674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 372674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 373b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 374674ae819SStefano Zampini PetscFunctionReturn(0); 375674ae819SStefano Zampini } 376674ae819SStefano Zampini 377674ae819SStefano Zampini #undef __FUNCT__ 378674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 379674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 380674ae819SStefano Zampini { 381674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 38206656605SStefano Zampini PetscScalar *array; 383674ae819SStefano Zampini PetscErrorCode ierr; 384674ae819SStefano Zampini 385674ae819SStefano Zampini PetscFunctionBegin; 386674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 387674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 38806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 38906656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 390674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 391674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 39215aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 39315aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 394674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 395674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 39606656605SStefano Zampini if (pcbddc->local_auxmat2) { 39706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 39806656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 39906656605SStefano Zampini } 400674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 40106656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 402674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 403674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 4048ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 405674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 406674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 407674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 408f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 409f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 410f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 411f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 412727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 413f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 41470cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 4156e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 416674ae819SStefano Zampini PetscFunctionReturn(0); 417674ae819SStefano Zampini } 418674ae819SStefano Zampini 419674ae819SStefano Zampini #undef __FUNCT__ 420f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 421f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 4226bfb1811SStefano Zampini { 4236bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4246bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4256bfb1811SStefano Zampini VecType impVecType; 426e9189074SStefano Zampini PetscInt n_constraints,n_R,old_size; 4276bfb1811SStefano Zampini PetscErrorCode ierr; 4286bfb1811SStefano Zampini 4296bfb1811SStefano Zampini PetscFunctionBegin; 430f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 431f4ddd8eeSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 432f4ddd8eeSStefano Zampini } 433e7b262bdSStefano Zampini /* get sizes */ 434e9189074SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->n_actual_vertices; 435e9189074SStefano Zampini n_R = pcis->n-pcbddc->n_actual_vertices; 4366bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 437e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 438e7b262bdSStefano Zampini /* R nodes */ 439e7b262bdSStefano Zampini old_size = -1; 440e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 441e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 442e7b262bdSStefano Zampini } 443e7b262bdSStefano Zampini if (n_R != old_size) { 444e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 445e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 4466bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 4476bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 4486bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 4496bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 450e7b262bdSStefano Zampini } 451e7b262bdSStefano Zampini /* local primal dofs */ 452e7b262bdSStefano Zampini old_size = -1; 453e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 454e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 455e7b262bdSStefano Zampini } 456e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 457e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 45883b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 459e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 4606bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 461e7b262bdSStefano Zampini } 462e7b262bdSStefano Zampini /* local explicit constraints */ 463e7b262bdSStefano Zampini old_size = -1; 464e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 465e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 466e7b262bdSStefano Zampini } 467e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 468e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 46983b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 47083b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 47183b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 47283b7ccabSStefano Zampini } 4736bfb1811SStefano Zampini PetscFunctionReturn(0); 4746bfb1811SStefano Zampini } 4756bfb1811SStefano Zampini 4766bfb1811SStefano Zampini #undef __FUNCT__ 47747f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 47847f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 47988ebb749SStefano Zampini { 48025084f0cSStefano Zampini PetscErrorCode ierr; 48125084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 48288ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 48388ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 48425084f0cSStefano Zampini /* submatrices of local problem */ 48588ebb749SStefano Zampini Mat A_RV,A_VR,A_VV; 48606656605SStefano Zampini /* submatrices of local coarse problem */ 48706656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 48825084f0cSStefano Zampini /* working matrices */ 48906656605SStefano Zampini Mat C_CR; 49025084f0cSStefano Zampini /* additional working stuff */ 49106656605SStefano Zampini PC pc_R; 49206656605SStefano Zampini Mat F; 49306656605SStefano Zampini PetscBool isLU,isCHOL,isILU; 49406656605SStefano Zampini 49525084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 49606656605SStefano Zampini PetscScalar *work; 49706656605SStefano Zampini PetscInt *idx_V_B; 49806656605SStefano Zampini PetscInt n,n_vertices,n_constraints; 49906656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 500b9d89cd5SStefano Zampini PetscBool unsymmetric_check; 50145a1bb75SStefano Zampini /* matrix type (vector type propagated downstream from vec1_C and local matrix type) */ 50288ebb749SStefano Zampini MatType impMatType; 50325084f0cSStefano Zampini /* some shortcuts to scalars */ 50406656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 50588ebb749SStefano Zampini 50688ebb749SStefano Zampini PetscFunctionBegin; 507e9189074SStefano Zampini /* get number of vertices (corners plus constraints with change of basis) 508e9189074SStefano Zampini pcbddc->n_actual_vertices stores the actual number of vertices, pcbddc->n_vertices the number of corners computed */ 509e9189074SStefano Zampini n_vertices = pcbddc->n_actual_vertices; 51088ebb749SStefano Zampini n_constraints = pcbddc->local_primal_size-n_vertices; 51188ebb749SStefano Zampini /* Set Non-overlapping dimensions */ 51288ebb749SStefano Zampini n_B = pcis->n_B; n_D = pcis->n - n_B; 51388ebb749SStefano Zampini n_R = pcis->n-n_vertices; 51488ebb749SStefano Zampini 51588ebb749SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 51688ebb749SStefano Zampini impMatType = MATSEQDENSE; 51788ebb749SStefano Zampini 51888ebb749SStefano Zampini /* vertices in boundary numbering */ 519785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 5205e8657edSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->primal_indices_local_idxs,&i,idx_V_B);CHKERRQ(ierr); 52188ebb749SStefano Zampini if (i != n_vertices) { 52222d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 52388ebb749SStefano Zampini } 52488ebb749SStefano Zampini 52506656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 52606656605SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 52706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 52806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 52906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 53006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 53106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 53206656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 53306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 53406656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 53506656605SStefano Zampini 53606656605SStefano Zampini unsymmetric_check = PETSC_FALSE; 53706656605SStefano Zampini /* allocate workspace */ 53806656605SStefano Zampini n = 0; 53906656605SStefano Zampini if (n_constraints) { 54006656605SStefano Zampini n += n_R*n_constraints; 54106656605SStefano Zampini } 54206656605SStefano Zampini if (n_vertices) { 54306656605SStefano Zampini n = PetscMax(2*n_R*n_vertices,n); 54406656605SStefano Zampini } 54506656605SStefano Zampini if (!pcbddc->issym) { 54606656605SStefano Zampini n = PetscMax(2*n_R*pcbddc->local_primal_size,n); 54706656605SStefano Zampini unsymmetric_check = PETSC_TRUE; 54806656605SStefano Zampini } 54906656605SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 55006656605SStefano Zampini 55106656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 55206656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 55306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 55406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 55506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 55606656605SStefano Zampini if (isLU || isILU || isCHOL) { 55706656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 55806656605SStefano Zampini } else { 55906656605SStefano Zampini F = NULL; 56006656605SStefano Zampini } 56106656605SStefano Zampini 56288ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 56388ebb749SStefano Zampini if (n_constraints) { 56406656605SStefano Zampini Mat M1,M2,M3; 56506656605SStefano Zampini IS is_aux; 566f4ddd8eeSStefano Zampini /* see if we can save some allocations */ 567f4ddd8eeSStefano Zampini if (pcbddc->local_auxmat2) { 568f4ddd8eeSStefano Zampini PetscInt on_R,on_constraints; 569f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->local_auxmat2,&on_R,&on_constraints);CHKERRQ(ierr); 570f4ddd8eeSStefano Zampini if (on_R != n_R || on_constraints != n_constraints) { 57106656605SStefano Zampini PetscScalar *marray; 57206656605SStefano Zampini 57306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&marray);CHKERRQ(ierr); 57406656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 575f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 576f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 577f4ddd8eeSStefano Zampini } 578f4ddd8eeSStefano Zampini } 57945a1bb75SStefano Zampini /* auxiliary matrices */ 580f4ddd8eeSStefano Zampini if (!pcbddc->local_auxmat2) { 58106656605SStefano Zampini PetscScalar *marray; 58206656605SStefano Zampini 58306656605SStefano Zampini ierr = PetscMalloc1(2*n_R*n_constraints,&marray);CHKERRQ(ierr); 58406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,marray,&pcbddc->local_auxmat2);CHKERRQ(ierr); 58506656605SStefano Zampini marray += n_R*n_constraints; 58606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_R,marray,&pcbddc->local_auxmat1);CHKERRQ(ierr); 587f4ddd8eeSStefano Zampini } 58888ebb749SStefano Zampini 58925084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 59025084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 5918ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 59225084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 59388ebb749SStefano Zampini 59488ebb749SStefano Zampini /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 59506656605SStefano Zampini ierr = PetscMemzero(work,n_R*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 59688ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 59706656605SStefano Zampini const PetscScalar *row_cmat_values; 59806656605SStefano Zampini const PetscInt *row_cmat_indices; 59906656605SStefano Zampini PetscInt size_of_constraint,j; 60088ebb749SStefano Zampini 60106656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 60206656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 60306656605SStefano Zampini work[row_cmat_indices[j]+i*n_R] = -row_cmat_values[j]; 60406656605SStefano Zampini } 60506656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 60606656605SStefano Zampini } 60706656605SStefano Zampini if (F) { 60806656605SStefano Zampini Mat B; 60906656605SStefano Zampini 61006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 61106656605SStefano Zampini ierr = MatMatSolve(F,B,pcbddc->local_auxmat2);CHKERRQ(ierr); 61206656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 61306656605SStefano Zampini } else { 61406656605SStefano Zampini PetscScalar *xarray; 61506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&xarray);CHKERRQ(ierr); 61606656605SStefano Zampini for (i=0;i<n_constraints;i++) { 61706656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 61806656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,xarray+i*n_R);CHKERRQ(ierr); 61906656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 62006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 62106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 62206656605SStefano Zampini } 62306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&xarray);CHKERRQ(ierr); 62406656605SStefano Zampini } 62506656605SStefano Zampini 62606656605SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 62706656605SStefano Zampini ierr = MatConvert(C_CR,impMatType,MAT_REUSE_MATRIX,&C_CR);CHKERRQ(ierr); 62825084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 62906656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 63006656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 63125084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 63206656605SStefano Zampini ierr = VecSet(pcbddc->vec1_C,m_one);CHKERRQ(ierr); 63306656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 63425084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 63525084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 63625084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 63706656605SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CR} needed by BDDC application in KSP and in preproc */ 638f4ddd8eeSStefano Zampini ierr = MatMatMult(M1,C_CR,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 63906656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 64006656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 64188ebb749SStefano Zampini } 64288ebb749SStefano Zampini 64388ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 64488ebb749SStefano Zampini if (n_vertices) { 64506656605SStefano Zampini Mat newmat; 64606656605SStefano Zampini IS is_aux; 6473a50541eSStefano Zampini PetscInt ibs,mbs; 6483a50541eSStefano Zampini PetscBool issbaij; 6493a50541eSStefano Zampini 6503a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 6519577ea80SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 6529577ea80SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 6533a50541eSStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ */ 6549577ea80SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 6559577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 6569577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 6579577ea80SStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 6589577ea80SStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 6599577ea80SStefano Zampini } else { 6603a50541eSStefano Zampini /* this is safe */ 6619577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 6623a50541eSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 6633a50541eSStefano Zampini if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 6643a50541eSStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 6653a50541eSStefano Zampini ierr = MatGetSubMatrix(newmat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 66606656605SStefano Zampini ierr = MatTranspose(A_VR,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 6673a50541eSStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 6683a50541eSStefano Zampini } else { 6699577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 6709577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 6719577ea80SStefano Zampini } 6723a50541eSStefano Zampini } 67325084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 67488ebb749SStefano Zampini } 67588ebb749SStefano Zampini 67688ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 677f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 67806656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 67906656605SStefano Zampini if (pcbddc->coarse_phi_D) { 68006656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 68106656605SStefano Zampini } 682f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 68306656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 68406656605SStefano Zampini PetscScalar *marray; 68506656605SStefano Zampini 68606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 68706656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 688f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 689f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 690f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 691f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 692f4ddd8eeSStefano Zampini } 693f4ddd8eeSStefano Zampini } 69406656605SStefano Zampini 695f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 69606656605SStefano Zampini PetscScalar *marray; 69788ebb749SStefano Zampini 69806656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 6998eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 70006656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 70188ebb749SStefano Zampini } 702b9d89cd5SStefano Zampini if (!pcbddc->issym) { 70306656605SStefano Zampini n *= 2; 704f4ddd8eeSStefano Zampini } 70506656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 70606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 70706656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 70806656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 70906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 71006656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 71188ebb749SStefano Zampini } 71206656605SStefano Zampini if (!pcbddc->issym) { 71306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 71406656605SStefano Zampini if (pcbddc->switch_static) { 71506656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 71606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 71788ebb749SStefano Zampini } 71888ebb749SStefano Zampini } else { 719c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 720c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 72106656605SStefano Zampini if (pcbddc->switch_static) { 722c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 723c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 724c0553b1fSStefano Zampini } 72588ebb749SStefano Zampini } 72606656605SStefano Zampini } 72706656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 72806656605SStefano Zampini /* vertices */ 72906656605SStefano Zampini if (n_vertices) { 73006656605SStefano Zampini Mat A_RRmA_RV,S_VVt; /* S_VVt with LDA=N */ 73106656605SStefano Zampini PetscScalar *x,*y; 73206656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 73306656605SStefano Zampini 73406656605SStefano Zampini ierr = PetscMemzero(work,2*n_R*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 73506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 73606656605SStefano Zampini ierr = MatConvert(A_RV,impMatType,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 73706656605SStefano Zampini if (F) { 73806656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 73906656605SStefano Zampini } else { 74006656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 74106656605SStefano Zampini for (i=0;i<n_vertices;i++) { 74206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*n_R);CHKERRQ(ierr); 74306656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 74406656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 74506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 74606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 74706656605SStefano Zampini } 74806656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 74906656605SStefano Zampini } 75006656605SStefano Zampini ierr = MatScale(A_RRmA_RV,m_one);CHKERRQ(ierr); 75106656605SStefano Zampini /* S_VV and S_CV are the subdomain contribution to coarse matrix. WARNING -> column major ordering */ 75206656605SStefano Zampini if (n_constraints) { 75306656605SStefano Zampini Mat B; 75406656605SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,A_RRmA_RV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 75506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 75606656605SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat2,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 75706656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 75806656605SStefano Zampini ierr = PetscBLASIntCast(n_R*n_vertices,&B_N);CHKERRQ(ierr); 75906656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+n_R*n_vertices,&B_one,work,&B_one)); 76006656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 76106656605SStefano Zampini } 76206656605SStefano Zampini ierr = MatConvert(A_VR,impMatType,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 76306656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 76406656605SStefano Zampini ierr = MatConvert(A_VV,impMatType,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 76506656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 76606656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 76706656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 76806656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 76906656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 77006656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 77106656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 77206656605SStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 77306656605SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 77406656605SStefano Zampini /* coarse basis functions */ 77506656605SStefano Zampini for (i=0;i<n_vertices;i++) { 77606656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 77706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 77806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 77906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 78006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 78106656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 78206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 78306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 78406656605SStefano Zampini 78506656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 78606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 78706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 78806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 78906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 79006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 79106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 79206656605SStefano Zampini } 79306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 79406656605SStefano Zampini } 79506656605SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 79606656605SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 79706656605SStefano Zampini } 79806656605SStefano Zampini 79906656605SStefano Zampini if (n_constraints) { 80006656605SStefano Zampini Mat B; 80106656605SStefano Zampini 80206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 80306656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 80406656605SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat2,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 80506656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 80606656605SStefano Zampini if (n_vertices) { 80706656605SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_VC);CHKERRQ(ierr); 80806656605SStefano Zampini } 80906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 81006656605SStefano Zampini /* coarse basis functions */ 81106656605SStefano Zampini for (i=0;i<n_constraints;i++) { 81206656605SStefano Zampini PetscScalar *y; 81306656605SStefano Zampini 81406656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 81506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 81606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 81706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 81806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 81906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 82006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 82106656605SStefano Zampini 82206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 82306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 82406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 82506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 82606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 82706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 82806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 82906656605SStefano Zampini } 83006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 83106656605SStefano Zampini } 83206656605SStefano Zampini } 83306656605SStefano Zampini 83406656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 83506656605SStefano Zampini if (!pcbddc->issym) { 83606656605SStefano Zampini Mat B,X; 83706656605SStefano Zampini 83806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,pcbddc->local_primal_size,work,&B);CHKERRQ(ierr); 83906656605SStefano Zampini 84006656605SStefano Zampini if (n_constraints) { 84106656605SStefano Zampini Mat S_VCT,S_CCT,B_C; 84206656605SStefano Zampini 84306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work+n_vertices*n_R,&B_C);CHKERRQ(ierr); 84406656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 84506656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_CCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 84606656605SStefano Zampini if (n_vertices) { 84706656605SStefano Zampini Mat B_V; 84806656605SStefano Zampini 84906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B_V);CHKERRQ(ierr); 85006656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 85106656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_VCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 85206656605SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 85306656605SStefano Zampini } 85406656605SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 85506656605SStefano Zampini } 85606656605SStefano Zampini if (n_vertices) { 85706656605SStefano Zampini Mat A_VRT; 85806656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 85906656605SStefano Zampini 86006656605SStefano Zampini if (!n_constraints) { /* if there are no constraints, reset work */ 86106656605SStefano Zampini ierr = PetscMemzero(work,n_R*pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 86206656605SStefano Zampini } 86306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work+pcbddc->local_primal_size*n_R,&A_VRT);CHKERRQ(ierr); 86406656605SStefano Zampini ierr = MatTranspose(A_VR,MAT_REUSE_MATRIX,&A_VRT);CHKERRQ(ierr); 86506656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_R,&B_N);CHKERRQ(ierr); 86606656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&m_one,work+pcbddc->local_primal_size*n_R,&B_one,work,&B_one)); 86706656605SStefano Zampini } 86806656605SStefano Zampini 86906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,pcbddc->local_primal_size,work+pcbddc->local_primal_size*n_R,&X);CHKERRQ(ierr); 87006656605SStefano Zampini if (F) { /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 87106656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 87206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 87306656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 87406656605SStefano Zampini ierr = MatSolveTranspose(F,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 87506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 87606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 87706656605SStefano Zampini } 87806656605SStefano Zampini } else { 87906656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 88006656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 88106656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 88206656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 88306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 88406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 88506656605SStefano Zampini } 88606656605SStefano Zampini } 88706656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 88806656605SStefano Zampini /* coarse basis functions */ 88906656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 89006656605SStefano Zampini PetscScalar *y; 89106656605SStefano Zampini 89206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*(i+pcbddc->local_primal_size));CHKERRQ(ierr); 89306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 89406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 89506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 89606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 89706656605SStefano Zampini if (i<n_vertices) { 89806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 89906656605SStefano Zampini } 90006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 90106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 90206656605SStefano Zampini 90306656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 90406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 90506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 90606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 90706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 90806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 90906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 91006656605SStefano Zampini } 91106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 91206656605SStefano Zampini } 91306656605SStefano Zampini ierr = MatDestroy(&X);CHKERRQ(ierr); 91406656605SStefano Zampini } 91506656605SStefano Zampini 91688ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 91706656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 91806656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 91906656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 92006656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 92188ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 92288ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 92388ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 92425084f0cSStefano Zampini if (pcbddc->dbg_flag) { 92588ebb749SStefano Zampini Mat coarse_sub_mat; 92625084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 92788ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 92888ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 92988ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 93088ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 93188ebb749SStefano Zampini PetscReal real_value; 93288ebb749SStefano Zampini 93388ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 93488ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 93588ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 93688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 93788ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 93888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 939c0553b1fSStefano Zampini if (unsymmetric_check) { 94088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 94188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 94288ebb749SStefano Zampini } 94388ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 94488ebb749SStefano Zampini 94525084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 94606656605SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation\n");CHKERRQ(ierr); 94725084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 948c0553b1fSStefano Zampini if (unsymmetric_check) { 94988ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 95088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 95188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 95288ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 95388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 95488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 95588ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 95688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 95788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 95888ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 95988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 96088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 96188ebb749SStefano Zampini } else { 96288ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 96388ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 96488ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 96588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 96688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 96788ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 96888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 96988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 97088ebb749SStefano Zampini } 97188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 97288ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 97388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 97488ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 97581d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 97688ebb749SStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&real_value);CHKERRQ(ierr); 97706656605SStefano Zampini 9780fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 97906656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 98025084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 98188ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 98288ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 98388ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 98488ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 98588ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 98688ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 98788ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 98888ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 98988ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 99088ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 991c0553b1fSStefano Zampini if (unsymmetric_check) { 99288ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 99388ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 99488ebb749SStefano Zampini } 99588ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 99688ebb749SStefano Zampini } 99706656605SStefano Zampini 99888ebb749SStefano Zampini /* free memory */ 99906656605SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 100088ebb749SStefano Zampini if (n_vertices) { 100188ebb749SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 100288ebb749SStefano Zampini } 100388ebb749SStefano Zampini if (n_constraints) { 100488ebb749SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 100588ebb749SStefano Zampini } 10068629588bSStefano Zampini /* get back data */ 10078629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 100888ebb749SStefano Zampini PetscFunctionReturn(0); 100988ebb749SStefano Zampini } 101088ebb749SStefano Zampini 101188ebb749SStefano Zampini #undef __FUNCT__ 1012d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 1013b96c3477SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, MatStructure reuse, Mat* B) 1014d65f70fdSStefano Zampini { 1015d65f70fdSStefano Zampini Mat *work_mat; 1016d65f70fdSStefano Zampini IS isrow_s,iscol_s; 1017d65f70fdSStefano Zampini PetscBool rsorted,csorted; 1018d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 1019d65f70fdSStefano Zampini PetscErrorCode ierr; 1020d65f70fdSStefano Zampini 1021d65f70fdSStefano Zampini PetscFunctionBegin; 1022d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 1023d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 1024d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 1025d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 1026d65f70fdSStefano Zampini 1027d65f70fdSStefano Zampini if (!rsorted) { 1028d65f70fdSStefano Zampini const PetscInt *idxs; 1029d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1030d65f70fdSStefano Zampini 1031d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 1032d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 1033d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1034d65f70fdSStefano Zampini idxs_perm_r[i] = i; 1035d65f70fdSStefano Zampini } 1036d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 1037d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 1038d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1039d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 1040d65f70fdSStefano Zampini } 1041d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 1042d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 1043d65f70fdSStefano Zampini } else { 1044d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 1045d65f70fdSStefano Zampini isrow_s = isrow; 1046d65f70fdSStefano Zampini } 1047d65f70fdSStefano Zampini 1048d65f70fdSStefano Zampini if (!csorted) { 1049d65f70fdSStefano Zampini if (isrow == iscol) { 1050d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 1051d65f70fdSStefano Zampini iscol_s = isrow_s; 1052d65f70fdSStefano Zampini } else { 1053d65f70fdSStefano Zampini const PetscInt *idxs; 1054d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1055d65f70fdSStefano Zampini 1056d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 1057d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 1058d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1059d65f70fdSStefano Zampini idxs_perm_c[i] = i; 1060d65f70fdSStefano Zampini } 1061d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 1062d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 1063d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1064d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 1065d65f70fdSStefano Zampini } 1066d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 1067d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 1068d65f70fdSStefano Zampini } 1069d65f70fdSStefano Zampini } else { 1070d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 1071d65f70fdSStefano Zampini iscol_s = iscol; 1072d65f70fdSStefano Zampini } 1073d65f70fdSStefano Zampini 1074b96c3477SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,reuse,&work_mat);CHKERRQ(ierr); 1075d65f70fdSStefano Zampini 1076d65f70fdSStefano Zampini if (!rsorted || !csorted) { 1077d65f70fdSStefano Zampini Mat new_mat; 1078d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 1079d65f70fdSStefano Zampini 1080d65f70fdSStefano Zampini if (!rsorted) { 1081d65f70fdSStefano Zampini PetscInt *idxs_r,i; 1082d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 1083d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1084d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 1085d65f70fdSStefano Zampini } 1086d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 1087d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 1088d65f70fdSStefano Zampini } else { 1089d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 1090d65f70fdSStefano Zampini } 1091d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 1092d65f70fdSStefano Zampini 1093d65f70fdSStefano Zampini if (!csorted) { 1094d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 1095d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 1096d65f70fdSStefano Zampini is_perm_c = is_perm_r; 1097d65f70fdSStefano Zampini } else { 1098d65f70fdSStefano Zampini PetscInt *idxs_c,i; 1099d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 1100d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1101d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 1102d65f70fdSStefano Zampini } 1103d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 1104d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 1105d65f70fdSStefano Zampini } 1106d65f70fdSStefano Zampini } else { 1107d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 1108d65f70fdSStefano Zampini } 1109d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 1110d65f70fdSStefano Zampini 1111d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 1112d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 1113d65f70fdSStefano Zampini work_mat[0] = new_mat; 1114d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 1115d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 1116d65f70fdSStefano Zampini } 1117d65f70fdSStefano Zampini 1118d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 1119d65f70fdSStefano Zampini *B = work_mat[0]; 1120d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 1121d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 1122d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 1123d65f70fdSStefano Zampini PetscFunctionReturn(0); 1124d65f70fdSStefano Zampini } 1125d65f70fdSStefano Zampini 1126d65f70fdSStefano Zampini #undef __FUNCT__ 11275e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 11285e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 1129aa0d41d4SStefano Zampini { 1130aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 11315e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1132d65f70fdSStefano Zampini Mat new_mat; 11335e8657edSStefano Zampini IS is_local,is_global; 1134d65f70fdSStefano Zampini PetscInt local_size; 1135d65f70fdSStefano Zampini PetscBool isseqaij; 1136aa0d41d4SStefano Zampini PetscErrorCode ierr; 1137aa0d41d4SStefano Zampini 1138aa0d41d4SStefano Zampini PetscFunctionBegin; 1139aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 11405e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 11415e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 1142906d46d4SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(matis->mapping,is_local,&is_global);CHKERRQ(ierr); 1143906d46d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 1144b96c3477SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,MAT_INITIAL_MATRIX,&new_mat);CHKERRQ(ierr); 1145906d46d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 1146906d46d4SStefano Zampini 1147906d46d4SStefano Zampini /* check */ 1148906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 1149906d46d4SStefano Zampini Vec x,x_change; 1150906d46d4SStefano Zampini PetscReal error; 1151906d46d4SStefano Zampini 11525e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 1153906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 11545e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 11555e8657edSStefano Zampini ierr = VecScatterBegin(matis->ctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11565e8657edSStefano Zampini ierr = VecScatterEnd(matis->ctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1157d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 11585e8657edSStefano Zampini ierr = VecScatterBegin(matis->ctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11595e8657edSStefano Zampini ierr = VecScatterEnd(matis->ctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1160906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 1161906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 1162906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1163906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 1164906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 1165906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 1166906d46d4SStefano Zampini } 1167906d46d4SStefano Zampini 116822d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 11699b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 117022d5777bSStefano Zampini if (isseqaij) { 1171d65f70fdSStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 1172aa0d41d4SStefano Zampini } else { 1173aa0d41d4SStefano Zampini Mat work_mat; 1174aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1175d65f70fdSStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 1176aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 1177aa0d41d4SStefano Zampini } 1178d65f70fdSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,pcbddc->issym);CHKERRQ(ierr); 117945a1bb75SStefano Zampini /* 118045a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1181d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 118245a1bb75SStefano Zampini */ 1183d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 1184aa0d41d4SStefano Zampini PetscFunctionReturn(0); 1185aa0d41d4SStefano Zampini } 1186aa0d41d4SStefano Zampini 1187aa0d41d4SStefano Zampini #undef __FUNCT__ 1188a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 11898ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 1190a64d13efSStefano Zampini { 1191a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1192a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 11938ce42a96SStefano Zampini IS is_aux1,is_aux2; 1194e9189074SStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 11953a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 11963a50541eSStefano Zampini PetscInt vbs,bs; 11974641a718SStefano Zampini PetscBT bitmask; 1198a64d13efSStefano Zampini PetscErrorCode ierr; 1199a64d13efSStefano Zampini 1200a64d13efSStefano Zampini PetscFunctionBegin; 1201b23d619eSStefano Zampini /* 1202b23d619eSStefano Zampini No need to setup local scatters if 1203b23d619eSStefano Zampini - primal space is unchanged 1204b23d619eSStefano Zampini AND 1205b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 1206b23d619eSStefano Zampini AND 1207b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 1208b23d619eSStefano Zampini */ 1209b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 1210f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 1211f4ddd8eeSStefano Zampini } 1212f4ddd8eeSStefano Zampini /* destroy old objects */ 1213f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1214f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1215f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1216a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 1217a64d13efSStefano Zampini n_B = pcis->n_B; n_D = pcis->n - n_B; 1218e9189074SStefano Zampini n_vertices = pcbddc->n_actual_vertices; 12194641a718SStefano Zampini /* create auxiliary bitmask */ 12204641a718SStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 12214641a718SStefano Zampini for (i=0;i<n_vertices;i++) { 1222e9189074SStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->primal_indices_local_idxs[i]);CHKERRQ(ierr); 12234641a718SStefano Zampini } 12243a50541eSStefano Zampini 1225a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 1226854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 1227a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 12284641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 1229a64d13efSStefano Zampini idx_R_local[n_R] = i; 1230a64d13efSStefano Zampini n_R++; 1231a64d13efSStefano Zampini } 1232a64d13efSStefano Zampini } 12333a50541eSStefano Zampini 12343a50541eSStefano Zampini /* Block code */ 12353a50541eSStefano Zampini vbs = 1; 12363a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 12373a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 12383a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 12393a50541eSStefano Zampini PetscInt *vary; 12403a50541eSStefano Zampini /* Verify if the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 1241785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 12423a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 1243e9189074SStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->primal_indices_local_idxs[i]/bs]++; 12443a50541eSStefano Zampini for (i=0; i<n_vertices; i++) { 12453a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 12463a50541eSStefano Zampini is_blocked = PETSC_FALSE; 12473a50541eSStefano Zampini break; 12483a50541eSStefano Zampini } 12493a50541eSStefano Zampini } 12503a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 12513a50541eSStefano Zampini vbs = bs; 12523a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 12533a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 12543a50541eSStefano Zampini } 12553a50541eSStefano Zampini } 12563a50541eSStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 12573a50541eSStefano Zampini } 12583a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 12593a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 1260a64d13efSStefano Zampini 1261a64d13efSStefano Zampini /* print some info if requested */ 1262a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 1263a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1264a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 12650fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1266a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 1267a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 12683a50541eSStefano 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); 1269a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"pcbddc->n_vertices = %d, pcbddc->n_constraints = %d\n",pcbddc->n_vertices,pcbddc->n_constraints);CHKERRQ(ierr); 1270a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1271a64d13efSStefano Zampini } 1272a64d13efSStefano Zampini 1273a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 12743a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1275854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 1276854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 1277a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 12784641a718SStefano Zampini for (i=0; i<n_D; i++) { 12794641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 12804641a718SStefano Zampini } 1281a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1282a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 12834641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 12844641a718SStefano Zampini aux_array1[j++] = i; 1285a64d13efSStefano Zampini } 1286a64d13efSStefano Zampini } 1287a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1288a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1289a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 12904641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 12914641a718SStefano Zampini aux_array2[j++] = i; 1292a64d13efSStefano Zampini } 1293a64d13efSStefano Zampini } 1294a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1295a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 1296a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 1297a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1298a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 1299a64d13efSStefano Zampini 13008eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1301785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 1302a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 13034641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 13044641a718SStefano Zampini aux_array1[j++] = i; 1305a64d13efSStefano Zampini } 1306a64d13efSStefano Zampini } 1307a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1308a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 1309a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1310a64d13efSStefano Zampini } 13114641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 13123a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1313a64d13efSStefano Zampini PetscFunctionReturn(0); 1314a64d13efSStefano Zampini } 1315a64d13efSStefano Zampini 1316304d26faSStefano Zampini 1317304d26faSStefano Zampini #undef __FUNCT__ 1318304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 1319684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 1320304d26faSStefano Zampini { 1321304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1322304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1323304d26faSStefano Zampini PC pc_temp; 1324304d26faSStefano Zampini Mat A_RR; 1325f4ddd8eeSStefano Zampini MatReuse reuse; 1326304d26faSStefano Zampini PetscScalar m_one = -1.0; 1327304d26faSStefano Zampini PetscReal value; 1328af732b37SStefano Zampini PetscInt n_D,n_R,ibs,mbs; 13299577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 1330304d26faSStefano Zampini PetscErrorCode ierr; 1331e604994aSStefano Zampini /* prefixes stuff */ 1332312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 1333e604994aSStefano Zampini size_t len; 1334304d26faSStefano Zampini 1335304d26faSStefano Zampini PetscFunctionBegin; 1336304d26faSStefano Zampini 1337e604994aSStefano Zampini /* compute prefixes */ 1338e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 1339e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 1340e604994aSStefano Zampini if (!pcbddc->current_level) { 1341e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1342e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1343e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1344e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1345e604994aSStefano Zampini } else { 1346e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 1347312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 1348e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 1349e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 1350312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 1351312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 135234d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 135334d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 1354e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1355e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1356e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 1357e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 1358e604994aSStefano Zampini } 1359e604994aSStefano Zampini 1360304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 1361684f6988SStefano Zampini if (dirichlet) { 1362ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 13638ce42a96SStefano Zampini ierr = ISGetSize(pcis->is_I_local,&n_D);CHKERRQ(ierr); 1364304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 1365304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 1366304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 1367304d26faSStefano Zampini /* default */ 1368304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1369e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 13709577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1371304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 13729577ea80SStefano Zampini if (issbaij) { 13739577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 13749577ea80SStefano Zampini } else { 1375304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 13769577ea80SStefano Zampini } 1377304d26faSStefano Zampini /* Allow user's customization */ 1378304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 1379304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1380304d26faSStefano Zampini } 1381d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 1382304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1383304d26faSStefano Zampini if (!n_D) { 1384304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 1385304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1386304d26faSStefano Zampini } 1387304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 1388304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 1389304d26faSStefano Zampini /* set ksp_D into pcis data */ 1390304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 1391304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 1392304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 1393684f6988SStefano Zampini } 1394304d26faSStefano Zampini 1395304d26faSStefano Zampini /* NEUMANN PROBLEM */ 1396684f6988SStefano Zampini A_RR = 0; 1397684f6988SStefano Zampini if (neumann) { 1398f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 13998ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 1400f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 1401f4ddd8eeSStefano Zampini PetscInt nn_R; 140281d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 1403f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 1404f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 1405f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 1406f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 1407f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1408f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1409f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 1410727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 1411f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1412f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1413f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 1414f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 1415f4ddd8eeSStefano Zampini } 1416f4ddd8eeSStefano Zampini } 1417f4ddd8eeSStefano Zampini /* last check */ 1418d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 1419f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1420f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1421f4ddd8eeSStefano Zampini } 1422f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 1423f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1424f4ddd8eeSStefano Zampini } 1425f4ddd8eeSStefano Zampini /* extract A_RR */ 1426af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 1427af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 14283a50541eSStefano Zampini if (ibs != mbs) { 1429af732b37SStefano Zampini Mat newmat; 1430af732b37SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INITIAL_MATRIX,&newmat);CHKERRQ(ierr); 1431f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(newmat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 1432af732b37SStefano Zampini ierr = MatDestroy(&newmat);CHKERRQ(ierr); 1433af732b37SStefano Zampini } else { 1434f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 1435af732b37SStefano Zampini } 1436f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 1437304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 1438304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 1439304d26faSStefano Zampini /* default */ 1440304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1441e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 1442304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 14439577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 14449577ea80SStefano Zampini if (issbaij) { 14459577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 14469577ea80SStefano Zampini } else { 1447304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 14489577ea80SStefano Zampini } 1449304d26faSStefano Zampini /* Allow user's customization */ 1450304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 1451304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1452304d26faSStefano Zampini } 1453d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 1454304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1455304d26faSStefano Zampini if (!n_R) { 1456304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 1457304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1458304d26faSStefano Zampini } 1459304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 1460304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1461684f6988SStefano Zampini } 1462304d26faSStefano Zampini 1463304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 14640fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 1465684f6988SStefano Zampini if (pcbddc->dbg_flag) { 1466684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1467684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1468684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1469684f6988SStefano Zampini } 1470684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 14710fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 14720fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 14730fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 14740fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 14750fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 1476304d26faSStefano Zampini /* need to be adapted? */ 1477b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 1478b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1479b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 1480304d26faSStefano Zampini /* print info */ 1481304d26faSStefano Zampini if (pcbddc->dbg_flag) { 1482e604994aSStefano 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); 1483304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1484304d26faSStefano Zampini } 1485b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 14868ce42a96SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,pcis->is_I_local);CHKERRQ(ierr); 1487304d26faSStefano Zampini } 1488684f6988SStefano Zampini } 1489684f6988SStefano Zampini if (neumann) { /* Neumann */ 14900fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 14910fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 14920fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 14930fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 14940fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 1495304d26faSStefano Zampini /* need to be adapted? */ 1496b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 1497b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1498304d26faSStefano Zampini /* print info */ 1499304d26faSStefano Zampini if (pcbddc->dbg_flag) { 1500e604994aSStefano 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); 1501304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1502304d26faSStefano Zampini } 1503b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 15048ce42a96SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,pcbddc->is_R_local);CHKERRQ(ierr); 1505304d26faSStefano Zampini } 15060fccc4e9SStefano Zampini } 1507684f6988SStefano Zampini } 1508304d26faSStefano Zampini /* free Neumann problem's matrix */ 1509304d26faSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1510304d26faSStefano Zampini PetscFunctionReturn(0); 1511304d26faSStefano Zampini } 1512304d26faSStefano Zampini 1513304d26faSStefano Zampini #undef __FUNCT__ 1514ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 151520c7b377SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec rhs, Vec sol, Vec work, PetscBool applytranspose) 1516674ae819SStefano Zampini { 1517674ae819SStefano Zampini PetscErrorCode ierr; 1518674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 1519674ae819SStefano Zampini 1520674ae819SStefano Zampini PetscFunctionBegin; 152120c7b377SStefano Zampini if (applytranspose) { 1522674ae819SStefano Zampini if (pcbddc->local_auxmat1) { 152320c7b377SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,rhs,work);CHKERRQ(ierr); 152420c7b377SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,work,rhs,rhs);CHKERRQ(ierr); 152520c7b377SStefano Zampini } 152620c7b377SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,rhs,sol);CHKERRQ(ierr); 152720c7b377SStefano Zampini } else { 152820c7b377SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,rhs,sol);CHKERRQ(ierr); 152920c7b377SStefano Zampini if (pcbddc->local_auxmat1) { 153020c7b377SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,sol,work);CHKERRQ(ierr); 153120c7b377SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,work,sol,sol);CHKERRQ(ierr); 153220c7b377SStefano Zampini } 1533674ae819SStefano Zampini } 1534674ae819SStefano Zampini PetscFunctionReturn(0); 1535674ae819SStefano Zampini } 1536674ae819SStefano Zampini 1537dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 1538674ae819SStefano Zampini #undef __FUNCT__ 1539674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 1540dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 1541674ae819SStefano Zampini { 1542674ae819SStefano Zampini PetscErrorCode ierr; 1543674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 1544674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 1545674ae819SStefano Zampini const PetscScalar zero = 0.0; 1546674ae819SStefano Zampini 1547674ae819SStefano Zampini PetscFunctionBegin; 1548dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 1549dc359a40SStefano Zampini if (applytranspose) { 1550674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 15518eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 1552dc359a40SStefano Zampini } else { 1553674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 1554674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 155515aaf578SStefano Zampini } 155612edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 155712edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 155812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 155912edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 156012edc857SStefano Zampini 15619f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 156212edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 156312edc857SStefano Zampini if (pcbddc->coarse_ksp) { 156412edc857SStefano Zampini if (applytranspose) { 156512edc857SStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,NULL,NULL);CHKERRQ(ierr); 156612edc857SStefano Zampini } else { 156712edc857SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,NULL,NULL);CHKERRQ(ierr); 156812edc857SStefano Zampini } 156912edc857SStefano Zampini } 1570674ae819SStefano Zampini 1571674ae819SStefano Zampini /* Local solution on R nodes */ 15729f00e9b4SStefano Zampini if (pcis->n) { 1573674ae819SStefano Zampini ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 1574674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1575674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 15768eeda7d8SStefano Zampini if (pcbddc->switch_static) { 1577674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1578674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1579674ae819SStefano Zampini } 158020c7b377SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcbddc->vec1_R,pcbddc->vec2_R,pcbddc->vec1_C,applytranspose);CHKERRQ(ierr); 1581674ae819SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1582674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1583674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 15848eeda7d8SStefano Zampini if (pcbddc->switch_static) { 1585674ae819SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1586674ae819SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1587674ae819SStefano Zampini } 15889f00e9b4SStefano Zampini } 1589674ae819SStefano Zampini 15909f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 15919f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 159212edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1593674ae819SStefano Zampini 1594674ae819SStefano Zampini /* Sum contributions from two levels */ 1595dc359a40SStefano Zampini if (applytranspose) { 1596dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 1597dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1598dc359a40SStefano Zampini } else { 1599674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 16008eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1601dc359a40SStefano Zampini } 1602674ae819SStefano Zampini PetscFunctionReturn(0); 1603674ae819SStefano Zampini } 1604674ae819SStefano Zampini 160512edc857SStefano Zampini /* TODO: the following two function can be optimized using VecPlaceArray whenever possible and using overlap flag */ 1606674ae819SStefano Zampini #undef __FUNCT__ 1607674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 160812edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 1609674ae819SStefano Zampini { 1610674ae819SStefano Zampini PetscErrorCode ierr; 1611674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 161212edc857SStefano Zampini PetscScalar *array,*array2; 161312edc857SStefano Zampini Vec from,to; 1614674ae819SStefano Zampini 1615674ae819SStefano Zampini PetscFunctionBegin; 161612edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 161712edc857SStefano Zampini from = pcbddc->coarse_vec; 161812edc857SStefano Zampini to = pcbddc->vec1_P; 161912edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 162012edc857SStefano Zampini Vec tvec; 162112edc857SStefano Zampini PetscInt lsize; 162212edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 162312edc857SStefano Zampini ierr = VecGetLocalSize(tvec,&lsize);CHKERRQ(ierr); 162412edc857SStefano Zampini ierr = VecGetArrayRead(tvec,(const PetscScalar**)&array);CHKERRQ(ierr); 162512edc857SStefano Zampini ierr = VecGetArray(from,&array2);CHKERRQ(ierr); 162612edc857SStefano Zampini ierr = PetscMemcpy(array2,array,lsize*sizeof(PetscScalar));CHKERRQ(ierr); 162712edc857SStefano Zampini ierr = VecRestoreArrayRead(tvec,(const PetscScalar**)&array);CHKERRQ(ierr); 162812edc857SStefano Zampini ierr = VecRestoreArray(from,&array2);CHKERRQ(ierr); 162912edc857SStefano Zampini } 163012edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 163112edc857SStefano Zampini from = pcbddc->vec1_P; 163212edc857SStefano Zampini to = pcbddc->coarse_vec; 163312edc857SStefano Zampini } 163412edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 1635674ae819SStefano Zampini PetscFunctionReturn(0); 1636674ae819SStefano Zampini } 1637674ae819SStefano Zampini 1638674ae819SStefano Zampini #undef __FUNCT__ 1639674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 164012edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 1641674ae819SStefano Zampini { 1642674ae819SStefano Zampini PetscErrorCode ierr; 1643674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 164412edc857SStefano Zampini PetscScalar *array,*array2; 164512edc857SStefano Zampini Vec from,to; 1646674ae819SStefano Zampini 1647674ae819SStefano Zampini PetscFunctionBegin; 164812edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 164912edc857SStefano Zampini from = pcbddc->coarse_vec; 165012edc857SStefano Zampini to = pcbddc->vec1_P; 165112edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 165212edc857SStefano Zampini from = pcbddc->vec1_P; 165312edc857SStefano Zampini to = pcbddc->coarse_vec; 165412edc857SStefano Zampini } 165512edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 165612edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 165712edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 165812edc857SStefano Zampini Vec tvec; 165912edc857SStefano Zampini PetscInt lsize; 166012edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 166112edc857SStefano Zampini ierr = VecGetLocalSize(tvec,&lsize);CHKERRQ(ierr); 166212edc857SStefano Zampini ierr = VecGetArrayRead(to,(const PetscScalar**)&array);CHKERRQ(ierr); 166312edc857SStefano Zampini ierr = VecGetArray(tvec,&array2);CHKERRQ(ierr); 166412edc857SStefano Zampini ierr = PetscMemcpy(array2,array,lsize*sizeof(PetscScalar));CHKERRQ(ierr); 166512edc857SStefano Zampini ierr = VecRestoreArrayRead(to,(const PetscScalar**)&array);CHKERRQ(ierr); 166612edc857SStefano Zampini ierr = VecRestoreArray(tvec,&array2);CHKERRQ(ierr); 166712edc857SStefano Zampini } 166812edc857SStefano Zampini } 1669674ae819SStefano Zampini PetscFunctionReturn(0); 1670674ae819SStefano Zampini } 1671674ae819SStefano Zampini 1672984c4197SStefano Zampini /* uncomment for testing purposes */ 1673984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 1674674ae819SStefano Zampini #undef __FUNCT__ 1675674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 1676674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 1677674ae819SStefano Zampini { 1678674ae819SStefano Zampini PetscErrorCode ierr; 1679674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1680674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1681674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 1682984c4197SStefano Zampini /* constraint and (optionally) change of basis matrix implemented as SeqAIJ */ 1683674ae819SStefano Zampini MatType impMatType=MATSEQAIJ; 1684984c4197SStefano Zampini /* one and zero */ 1685984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 1686984c4197SStefano Zampini /* space to store constraints and their local indices */ 1687984c4197SStefano Zampini PetscScalar *temp_quadrature_constraint; 1688984c4197SStefano Zampini PetscInt *temp_indices,*temp_indices_to_constraint,*temp_indices_to_constraint_B; 1689984c4197SStefano Zampini /* iterators */ 1690984c4197SStefano Zampini PetscInt i,j,k,total_counts,temp_start_ptr; 1691984c4197SStefano Zampini /* stuff to store connected components stored in pcbddc->mat_graph */ 1692984c4197SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges,*used_IS; 1693984c4197SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges; 1694984c4197SStefano Zampini /* near null space stuff */ 1695674ae819SStefano Zampini MatNullSpace nearnullsp; 1696674ae819SStefano Zampini const Vec *nearnullvecs; 1697674ae819SStefano Zampini Vec *localnearnullsp; 1698984c4197SStefano Zampini PetscBool nnsp_has_cnst; 1699984c4197SStefano Zampini PetscInt nnsp_size; 1700984c4197SStefano Zampini PetscScalar *array; 1701984c4197SStefano Zampini /* BLAS integers */ 1702e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 1703e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 1704c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 1705984c4197SStefano Zampini /* LAPACK working arrays for SVD or POD */ 1706242a89d7SStefano Zampini PetscBool skip_lapack; 1707984c4197SStefano Zampini PetscScalar *work; 1708984c4197SStefano Zampini PetscReal *singular_vals; 1709984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1710984c4197SStefano Zampini PetscReal *rwork; 1711674ae819SStefano Zampini #endif 1712984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1713e310c8b4SStefano Zampini PetscBLASInt Blas_one_2=1; 1714984c4197SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 1715b7d8b9f8SStefano Zampini #else 1716b7d8b9f8SStefano Zampini PetscBLASInt dummy_int_1=1,dummy_int_2=1; 1717b7d8b9f8SStefano Zampini PetscScalar dummy_scalar_1=0.0,dummy_scalar_2=0.0; 1718984c4197SStefano Zampini #endif 1719727cdba6SStefano Zampini /* reuse */ 1720727cdba6SStefano Zampini PetscInt olocal_primal_size; 1721727cdba6SStefano Zampini PetscInt *oprimal_indices_local_idxs; 1722984c4197SStefano Zampini /* change of basis */ 1723984c4197SStefano Zampini PetscInt *aux_primal_numbering,*aux_primal_minloc,*global_indices; 1724a717540cSStefano Zampini PetscBool boolforchange,qr_needed; 1725a717540cSStefano Zampini PetscBT touched,change_basis,qr_needed_idx; 1726984c4197SStefano Zampini /* auxiliary stuff */ 172739e2fb2aSStefano Zampini PetscInt *nnz,*is_indices,*aux_primal_numbering_B; 1728*a58a30b4SStefano Zampini PetscInt ncc,*gidxs=NULL,*permutation=NULL,*temp_indices_to_constraint_work=NULL; 1729*a58a30b4SStefano Zampini PetscScalar *temp_quadrature_constraint_work=NULL; 1730984c4197SStefano Zampini /* some quantities */ 173145a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 1732*a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 1733984c4197SStefano Zampini 1734674ae819SStefano Zampini 1735674ae819SStefano Zampini PetscFunctionBegin; 17368e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 17378e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 17388e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 173908122e43SStefano Zampini /* TODO synch with adaptive selection */ 1740674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 1741d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 1742d06fc5fdSStefano Zampini /* free unneeded index sets */ 1743d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 1744d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 1745674ae819SStefano Zampini } 1746d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 1747d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 1748d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 1749d06fc5fdSStefano Zampini } 1750d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 1751d06fc5fdSStefano Zampini n_ISForEdges = 0; 1752d06fc5fdSStefano Zampini } 1753d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 1754d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 1755d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 1756d06fc5fdSStefano Zampini } 1757d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 1758d06fc5fdSStefano Zampini n_ISForFaces = 0; 1759d06fc5fdSStefano Zampini } 1760d06fc5fdSStefano Zampini /* HACKS (the following two blocks of code) */ 1761b9b85e73SStefano Zampini if (!ISForVertices && pcbddc->NullSpace && !pcbddc->user_ChangeOfBasisMatrix) { 1762b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 1763d06fc5fdSStefano Zampini if (!ISForEdges) { 1764d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 1765d06fc5fdSStefano Zampini } 1766b8ffe317SStefano Zampini } 176798a51de6SStefano Zampini if (pcbddc->NullSpace) { 176898a51de6SStefano Zampini /* use_change_of_basis should be consistent among processors */ 1769d06fc5fdSStefano Zampini PetscBool tbool[2],gbool[2]; 1770d06fc5fdSStefano Zampini tbool [0] = pcbddc->use_change_of_basis; 1771d06fc5fdSStefano Zampini tbool [1] = pcbddc->use_change_on_faces; 1772d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1773d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 1774d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 177598a51de6SStefano Zampini } 1776984c4197SStefano Zampini /* print some info */ 1777674ae819SStefano Zampini if (pcbddc->dbg_flag) { 17780fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1779674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 1780674ae819SStefano Zampini i = 0; 1781674ae819SStefano Zampini if (ISForVertices) { 1782674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&i);CHKERRQ(ierr); 1783674ae819SStefano Zampini } 1784674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices\n",PetscGlobalRank,i);CHKERRQ(ierr); 1785674ae819SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges\n",PetscGlobalRank,n_ISForEdges);CHKERRQ(ierr); 178615aaf578SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces\n",PetscGlobalRank,n_ISForFaces);CHKERRQ(ierr); 1787674ae819SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1788674ae819SStefano Zampini } 178908122e43SStefano Zampini 179008122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 1791674ae819SStefano Zampini /* check if near null space is attached to global mat */ 1792674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 1793674ae819SStefano Zampini if (nearnullsp) { 1794674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1795f4ddd8eeSStefano Zampini /* remove any stored info */ 1796f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 1797f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1798f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 1799f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 1800f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 1801473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 1802f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1803f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 1804f4ddd8eeSStefano Zampini } 1805984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 1806984c4197SStefano Zampini nnsp_size = 0; 1807674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 1808674ae819SStefano Zampini } 1809984c4197SStefano Zampini /* get max number of constraints on a single cc */ 1810984c4197SStefano Zampini max_constraints = nnsp_size; 1811984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 1812984c4197SStefano Zampini 1813674ae819SStefano Zampini /* 1814674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 1815674ae819SStefano Zampini - temp_indices will contain start index of each constraint stored as follows 1816911cabfeSStefano 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 1817911cabfeSStefano 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 1818911cabfeSStefano Zampini - temp_quadrature_constraint [temp_indices[i],...,temp_indices[i+1]-1] will contain the scalars representing the constraint itself 1819674ae819SStefano Zampini */ 1820674ae819SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 1821984c4197SStefano Zampini total_counts *= max_constraints; 1822674ae819SStefano Zampini n_vertices = 0; 1823674ae819SStefano Zampini if (ISForVertices) { 1824674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 1825674ae819SStefano Zampini } 1826674ae819SStefano Zampini total_counts += n_vertices; 1827854ce69bSBarry Smith ierr = PetscMalloc1(total_counts+1,&temp_indices);CHKERRQ(ierr); 18284641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 1829674ae819SStefano Zampini total_counts = 0; 1830674ae819SStefano Zampini max_size_of_constraint = 0; 1831674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 1832674ae819SStefano Zampini if (i<n_ISForEdges) { 1833674ae819SStefano Zampini used_IS = &ISForEdges[i]; 1834674ae819SStefano Zampini } else { 1835674ae819SStefano Zampini used_IS = &ISForFaces[i-n_ISForEdges]; 1836674ae819SStefano Zampini } 1837674ae819SStefano Zampini ierr = ISGetSize(*used_IS,&j);CHKERRQ(ierr); 1838674ae819SStefano Zampini total_counts += j; 1839674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 1840674ae819SStefano Zampini } 1841984c4197SStefano Zampini total_counts *= max_constraints; 1842674ae819SStefano Zampini total_counts += n_vertices; 1843906d46d4SStefano Zampini ierr = PetscMalloc3(total_counts,&temp_quadrature_constraint,total_counts,&temp_indices_to_constraint,total_counts,&temp_indices_to_constraint_B);CHKERRQ(ierr); 1844984c4197SStefano Zampini /* get local part of global near null space vectors */ 1845785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 1846984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 1847984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 1848984c4197SStefano Zampini ierr = VecScatterBegin(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1849984c4197SStefano Zampini ierr = VecScatterEnd(matis->ctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1850984c4197SStefano Zampini } 1851674ae819SStefano Zampini 1852242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 1853242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 1854a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 1855242a89d7SStefano Zampini 18568f1c130eSStefano Zampini /* allocate some auxiliary stuff */ 18578f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 18588f1c130eSStefano 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); 18598f1c130eSStefano Zampini } 18608f1c130eSStefano Zampini 1861984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 1862a773dcb8SStefano Zampini if (!skip_lapack) { 1863674ae819SStefano Zampini PetscScalar temp_work; 1864911cabfeSStefano Zampini 1865674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 1866984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 1867785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 1868785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 1869785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 1870674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1871785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 1872674ae819SStefano Zampini #endif 1873674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 1874c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 1875c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 1876674ae819SStefano Zampini lwork = -1; 1877674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1878674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1879c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 1880674ae819SStefano Zampini #else 1881c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 1882674ae819SStefano Zampini #endif 1883674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1884984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 1885674ae819SStefano Zampini #else /* on missing GESVD */ 1886674ae819SStefano Zampini /* SVD */ 1887674ae819SStefano Zampini PetscInt max_n,min_n; 1888674ae819SStefano Zampini max_n = max_size_of_constraint; 1889984c4197SStefano Zampini min_n = max_constraints; 1890984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 1891674ae819SStefano Zampini min_n = max_size_of_constraint; 1892984c4197SStefano Zampini max_n = max_constraints; 1893674ae819SStefano Zampini } 1894785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 1895674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 1896785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 1897674ae819SStefano Zampini #endif 1898674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 1899674ae819SStefano Zampini lwork = -1; 1900e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 1901e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 1902b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 1903674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 1904674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 1905e310c8b4SStefano 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)); 1906674ae819SStefano Zampini #else 1907e310c8b4SStefano 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)); 1908674ae819SStefano Zampini #endif 1909674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 1910984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 1911984c4197SStefano Zampini #endif /* on missing GESVD */ 1912674ae819SStefano Zampini /* Allocate optimal workspace */ 1913674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 1914854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 1915674ae819SStefano Zampini } 1916674ae819SStefano Zampini /* Now we can loop on constraining sets */ 1917674ae819SStefano Zampini total_counts = 0; 1918674ae819SStefano Zampini temp_indices[0] = 0; 1919674ae819SStefano Zampini /* vertices */ 1920674ae819SStefano Zampini if (ISForVertices) { 1921674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1922674ae819SStefano Zampini if (nnsp_has_cnst) { /* consider all vertices */ 192339e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 1924674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 1925674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1926674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1927674ae819SStefano Zampini total_counts++; 1928674ae819SStefano Zampini } 1929674ae819SStefano Zampini } else { /* consider vertices for which exist at least a localnearnullsp which is not null there */ 1930984c4197SStefano Zampini PetscBool used_vertex; 1931674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 1932674ae819SStefano Zampini used_vertex = PETSC_FALSE; 1933674ae819SStefano Zampini k = 0; 1934674ae819SStefano Zampini while (!used_vertex && k<nnsp_size) { 1935984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 1936984c4197SStefano Zampini if (PetscAbsScalar(array[is_indices[i]])>0.0) { 1937674ae819SStefano Zampini temp_indices_to_constraint[temp_indices[total_counts]]=is_indices[i]; 1938674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]]=1.0; 1939674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+1; 1940674ae819SStefano Zampini total_counts++; 1941674ae819SStefano Zampini used_vertex = PETSC_TRUE; 1942674ae819SStefano Zampini } 1943984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 1944674ae819SStefano Zampini k++; 1945674ae819SStefano Zampini } 1946674ae819SStefano Zampini } 1947674ae819SStefano Zampini } 1948674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1949674ae819SStefano Zampini n_vertices = total_counts; 1950674ae819SStefano Zampini } 1951984c4197SStefano Zampini 1952674ae819SStefano Zampini /* edges and faces */ 1953911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 1954911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 1955911cabfeSStefano Zampini used_IS = &ISForEdges[ncc]; 1956984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 1957674ae819SStefano Zampini } else { 1958911cabfeSStefano Zampini used_IS = &ISForFaces[ncc-n_ISForEdges]; 1959984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 1960674ae819SStefano Zampini } 1961674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 1962674ae819SStefano Zampini temp_start_ptr = total_counts; /* need to know the starting index of constraints stored */ 1963674ae819SStefano Zampini ierr = ISGetSize(*used_IS,&size_of_constraint);CHKERRQ(ierr); 1964674ae819SStefano Zampini ierr = ISGetIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1965984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 1966984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 1967674ae819SStefano Zampini if (nnsp_has_cnst) { 19685b08dc53SStefano Zampini PetscScalar quad_value; 1969674ae819SStefano Zampini temp_constraints++; 1970a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 1971674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 1972a773dcb8SStefano Zampini } else { 1973a773dcb8SStefano Zampini quad_value = 1.0; 1974a773dcb8SStefano Zampini } 197539e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1976674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1977674ae819SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=quad_value; 1978674ae819SStefano Zampini } 197908122e43SStefano Zampini /* sort by global ordering if using lapack subroutines (not needed!) */ 19808f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 1981911cabfeSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,size_of_constraint,temp_indices_to_constraint+temp_indices[total_counts],gidxs);CHKERRQ(ierr); 1982911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 1983911cabfeSStefano Zampini permutation[j]=j; 1984911cabfeSStefano Zampini } 1985911cabfeSStefano Zampini ierr = PetscSortIntWithPermutation(size_of_constraint,gidxs,permutation);CHKERRQ(ierr); 1986911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 198708122e43SStefano Zampini if (permutation[j]!=j) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This should not happen"); 198808122e43SStefano Zampini } 198908122e43SStefano Zampini for (j=0;j<size_of_constraint;j++) { 1990911cabfeSStefano Zampini temp_indices_to_constraint_work[j] = temp_indices_to_constraint[temp_indices[total_counts]+permutation[j]]; 1991911cabfeSStefano Zampini temp_quadrature_constraint_work[j] = temp_quadrature_constraint[temp_indices[total_counts]+permutation[j]]; 1992911cabfeSStefano Zampini } 1993911cabfeSStefano Zampini ierr = PetscMemcpy(temp_indices_to_constraint+temp_indices[total_counts],temp_indices_to_constraint_work,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 1994911cabfeSStefano Zampini ierr = PetscMemcpy(temp_quadrature_constraint+temp_indices[total_counts],temp_quadrature_constraint_work,size_of_constraint*sizeof(PetscScalar));CHKERRQ(ierr); 1995911cabfeSStefano Zampini } 1996674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 1997674ae819SStefano Zampini total_counts++; 1998674ae819SStefano Zampini } 1999674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 2000984c4197SStefano Zampini PetscReal real_value; 2001984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 200239e2fb2aSStefano Zampini ierr = PetscMemcpy(&temp_indices_to_constraint[temp_indices[total_counts]],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 2003674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 2004984c4197SStefano Zampini temp_quadrature_constraint[temp_indices[total_counts]+j]=array[is_indices[j]]; 2005674ae819SStefano Zampini } 2006984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2007984c4197SStefano Zampini /* check if array is null on the connected component */ 2008e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2009e310c8b4SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,&temp_quadrature_constraint[temp_indices[total_counts]],&Blas_one)); 20105b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 2011911cabfeSStefano Zampini /* sort by global ordering if using lapack subroutines */ 20128f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 2013911cabfeSStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,size_of_constraint,temp_indices_to_constraint+temp_indices[total_counts],gidxs);CHKERRQ(ierr); 2014911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 2015911cabfeSStefano Zampini permutation[j]=j; 2016911cabfeSStefano Zampini } 2017911cabfeSStefano Zampini ierr = PetscSortIntWithPermutation(size_of_constraint,gidxs,permutation);CHKERRQ(ierr); 2018911cabfeSStefano Zampini for (j=0;j<size_of_constraint;j++) { 2019911cabfeSStefano Zampini temp_indices_to_constraint_work[j] = temp_indices_to_constraint[temp_indices[total_counts]+permutation[j]]; 2020911cabfeSStefano Zampini temp_quadrature_constraint_work[j] = temp_quadrature_constraint[temp_indices[total_counts]+permutation[j]]; 2021911cabfeSStefano Zampini } 2022911cabfeSStefano Zampini ierr = PetscMemcpy(temp_indices_to_constraint+temp_indices[total_counts],temp_indices_to_constraint_work,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 2023911cabfeSStefano Zampini ierr = PetscMemcpy(temp_quadrature_constraint+temp_indices[total_counts],temp_quadrature_constraint_work,size_of_constraint*sizeof(PetscScalar));CHKERRQ(ierr); 2024911cabfeSStefano Zampini } 2025674ae819SStefano Zampini temp_constraints++; 2026674ae819SStefano Zampini temp_indices[total_counts+1]=temp_indices[total_counts]+size_of_constraint; /* store new starting point */ 2027674ae819SStefano Zampini total_counts++; 2028674ae819SStefano Zampini } 2029674ae819SStefano Zampini } 2030674ae819SStefano Zampini ierr = ISRestoreIndices(*used_IS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 203145a1bb75SStefano Zampini valid_constraints = temp_constraints; 2032eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 2033a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 2034a773dcb8SStefano Zampini PetscScalar norm; 2035a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2036a773dcb8SStefano 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)); 2037a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 2038a773dcb8SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,temp_quadrature_constraint+temp_indices[temp_start_ptr],&Blas_one)); 2039a773dcb8SStefano Zampini } else { /* perform SVD */ 2040984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 2041674ae819SStefano Zampini 2042674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2043984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 2044984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 2045984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 2046984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 2047984c4197SStefano Zampini from that computed using LAPACKgesvd 2048984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 2049984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 2050984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 2051674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 2052e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2053984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2054674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 2055674ae819SStefano Zampini for (k=0;k<j+1;k++) { 2056e310c8b4SStefano 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)); 2057674ae819SStefano Zampini } 2058674ae819SStefano Zampini } 2059e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 2060e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2061e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 2062674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2063c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 2064674ae819SStefano Zampini #else 2065c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 2066674ae819SStefano Zampini #endif 2067674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2068984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 2069984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 2070674ae819SStefano Zampini j = 0; 2071984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 2072674ae819SStefano Zampini total_counts = total_counts-j; 207345a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 2074e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 2075c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2076c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2077c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 2078c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2079c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 2080c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2081674ae819SStefano Zampini if (j<temp_constraints) { 2082984c4197SStefano Zampini PetscInt ii; 2083984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k]=1.0/PetscSqrtReal(singular_vals[k]); 2084674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2085c4303822SStefano 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)); 2086674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2087984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 2088674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 2089984c4197SStefano 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]; 2090674ae819SStefano Zampini } 2091674ae819SStefano Zampini } 2092674ae819SStefano Zampini } 2093674ae819SStefano Zampini #else /* on missing GESVD */ 2094e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2095e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2096b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2097674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2098674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2099e310c8b4SStefano 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)); 2100674ae819SStefano Zampini #else 2101e310c8b4SStefano 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)); 2102674ae819SStefano Zampini #endif 2103984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 2104674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2105984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 2106e310c8b4SStefano Zampini k = temp_constraints; 2107e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 2108674ae819SStefano Zampini j = 0; 2109e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 211045a1bb75SStefano Zampini valid_constraints = k-j; 2111911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 2112984c4197SStefano Zampini #endif /* on missing GESVD */ 2113674ae819SStefano Zampini } 2114a773dcb8SStefano Zampini } 211545a1bb75SStefano Zampini /* setting change_of_basis flag is safe now */ 211645a1bb75SStefano Zampini if (boolforchange) { 211745a1bb75SStefano Zampini for (j=0;j<valid_constraints;j++) { 211845a1bb75SStefano Zampini PetscBTSet(change_basis,total_counts-j-1); 211945a1bb75SStefano Zampini } 212045a1bb75SStefano Zampini } 2121674ae819SStefano Zampini } 2122984c4197SStefano Zampini /* free workspace */ 21238f1c130eSStefano Zampini if (!skip_lapack || pcbddc->use_qr_single) { 2124911cabfeSStefano Zampini ierr = PetscFree4(gidxs,permutation,temp_indices_to_constraint_work,temp_quadrature_constraint_work);CHKERRQ(ierr); 21258f1c130eSStefano Zampini } 21268f1c130eSStefano Zampini if (!skip_lapack) { 2127984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2128984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2129984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 2130984c4197SStefano Zampini #endif 2131984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 2132984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2133984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 2134984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 2135984c4197SStefano Zampini #endif 2136984c4197SStefano Zampini } 2137984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2138984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 2139984c4197SStefano Zampini } 2140984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 214108122e43SStefano Zampini } else { 214208122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 214308122e43SStefano Zampini PetscInt cum = 0; 214408122e43SStefano Zampini 214508122e43SStefano Zampini total_counts = 0; 214608122e43SStefano Zampini n_vertices = 0; 214708122e43SStefano Zampini if (sub_schurs->is_Ej_com) { 214808122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_Ej_com,&n_vertices);CHKERRQ(ierr); 214908122e43SStefano Zampini } 215008122e43SStefano Zampini max_constraints = 0; 215108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 215208122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 215308122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 215408122e43SStefano Zampini } 215508122e43SStefano Zampini temp_indices = pcbddc->adaptive_constraints_ptrs; 215608122e43SStefano Zampini temp_indices_to_constraint = pcbddc->adaptive_constraints_idxs; 215708122e43SStefano Zampini temp_quadrature_constraint = pcbddc->adaptive_constraints_data; 215808122e43SStefano Zampini 215908122e43SStefano Zampini #if 0 216008122e43SStefano Zampini printf("Found %d totals\n",total_counts); 216108122e43SStefano Zampini for (i=0;i<total_counts;i++) { 216208122e43SStefano Zampini printf("const %d, start %d",i,temp_indices[i]); 216308122e43SStefano Zampini printf(" end %d:\n",temp_indices[i+1]); 216408122e43SStefano Zampini for (j=temp_indices[i];j<temp_indices[i+1];j++) { 216508122e43SStefano Zampini printf(" idxs %d",temp_indices_to_constraint[j]); 216608122e43SStefano Zampini printf(" data %1.2e\n",temp_quadrature_constraint[j]); 216708122e43SStefano Zampini } 216808122e43SStefano Zampini } 216908122e43SStefano Zampini #endif 217008122e43SStefano Zampini 217108122e43SStefano Zampini for (i=0;i<total_counts;i++) max_size_of_constraint = PetscMax(max_size_of_constraint,temp_indices[i+1]-temp_indices[i]); 217208122e43SStefano Zampini ierr = PetscMalloc1(temp_indices[total_counts],&temp_indices_to_constraint_B);CHKERRQ(ierr); 217308122e43SStefano Zampini /* Change of basis */ 217408122e43SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 217508122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 2176bbb9e6c6SStefano Zampini cum = n_vertices; 217708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 217808122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 2179bbb9e6c6SStefano Zampini for (j=0;j<pcbddc->adaptive_constraints_n[i+n_vertices];j++) { 218008122e43SStefano Zampini ierr = PetscBTSet(change_basis,cum+j);CHKERRQ(ierr); 218108122e43SStefano Zampini } 218208122e43SStefano Zampini } 2183bbb9e6c6SStefano Zampini cum += pcbddc->adaptive_constraints_n[i+n_vertices]; 218408122e43SStefano Zampini } 218508122e43SStefano Zampini } 218608122e43SStefano Zampini } 218708122e43SStefano Zampini 218808122e43SStefano Zampini /* free index sets of faces, edges and vertices */ 218908122e43SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 219008122e43SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 219108122e43SStefano Zampini } 219208122e43SStefano Zampini if (n_ISForFaces) { 219308122e43SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 219408122e43SStefano Zampini } 219508122e43SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 219608122e43SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 219708122e43SStefano Zampini } 219808122e43SStefano Zampini if (n_ISForEdges) { 219908122e43SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 220008122e43SStefano Zampini } 220108122e43SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 220208122e43SStefano Zampini 220308122e43SStefano Zampini /* map temp_indices_to_constraint in boundary numbering */ 220408122e43SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,temp_indices[total_counts],temp_indices_to_constraint,&i,temp_indices_to_constraint_B);CHKERRQ(ierr); 220508122e43SStefano Zampini if (i != temp_indices[total_counts]) { 220608122e43SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %d != %d\n",temp_indices[total_counts],i); 220708122e43SStefano Zampini } 2208984c4197SStefano Zampini 2209727cdba6SStefano Zampini /* set quantities in pcbddc data structure and store previous primal size */ 2210984c4197SStefano Zampini /* n_vertices defines the number of subdomain corners in the primal space */ 2211674ae819SStefano Zampini /* n_constraints defines the number of averages (they can be point primal dofs if change of basis is requested) */ 2212727cdba6SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 2213984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 2214674ae819SStefano Zampini pcbddc->n_vertices = n_vertices; 2215984c4197SStefano Zampini pcbddc->n_constraints = pcbddc->local_primal_size-pcbddc->n_vertices; 2216674ae819SStefano Zampini 2217674ae819SStefano Zampini /* Create constraint matrix */ 2218674ae819SStefano Zampini /* The constraint matrix is used to compute the l2g map of primal dofs */ 2219674ae819SStefano Zampini /* so we need to set it up properly either with or without change of basis */ 2220674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2221674ae819SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,impMatType);CHKERRQ(ierr); 2222984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 2223984c4197SStefano Zampini /* array to compute a local numbering of constraints : vertices first then constraints */ 2224785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&aux_primal_numbering);CHKERRQ(ierr); 2225984c4197SStefano Zampini /* array to select the proper local node (of minimum index with respect to global ordering) when changing the basis */ 2226984c4197SStefano 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 */ 2227785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&aux_primal_minloc);CHKERRQ(ierr); 2228984c4197SStefano Zampini /* auxiliary stuff for basis change */ 2229785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint,&global_indices);CHKERRQ(ierr); 22304641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&touched);CHKERRQ(ierr); 2231984c4197SStefano Zampini 2232984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 2233984c4197SStefano Zampini total_primal_vertices=0; 2234984c4197SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 2235674ae819SStefano Zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 2236984c4197SStefano Zampini if (size_of_constraint == 1) { 22374641a718SStefano Zampini ierr = PetscBTSet(touched,temp_indices_to_constraint_B[temp_indices[i]]);CHKERRQ(ierr); 2238984c4197SStefano Zampini aux_primal_numbering[total_primal_vertices]=temp_indices_to_constraint[temp_indices[i]]; 2239984c4197SStefano Zampini aux_primal_minloc[total_primal_vertices]=0; 2240984c4197SStefano Zampini total_primal_vertices++; 22414641a718SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { /* Same procedure used in PCBDDCGetPrimalConstraintsLocalIdx */ 2242984c4197SStefano Zampini PetscInt min_loc,min_index; 2243984c4197SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcbddc->mat_graph->l2gmap,size_of_constraint,&temp_indices_to_constraint[temp_indices[i]],global_indices);CHKERRQ(ierr); 2244984c4197SStefano Zampini /* find first untouched local node */ 2245674ae819SStefano Zampini k = 0; 22464641a718SStefano Zampini while (PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k])) k++; 2247984c4197SStefano Zampini min_index = global_indices[k]; 2248984c4197SStefano Zampini min_loc = k; 2249984c4197SStefano Zampini /* search the minimum among global nodes already untouched on the cc */ 2250984c4197SStefano Zampini for (k=1;k<size_of_constraint;k++) { 2251984c4197SStefano Zampini /* there can be more than one constraint on a single connected component */ 22524641a718SStefano Zampini if (!PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k]) && min_index > global_indices[k]) { 2253984c4197SStefano Zampini min_index = global_indices[k]; 2254984c4197SStefano Zampini min_loc = k; 2255674ae819SStefano Zampini } 2256674ae819SStefano Zampini } 22574641a718SStefano Zampini ierr = PetscBTSet(touched,temp_indices_to_constraint_B[temp_indices[i]+min_loc]);CHKERRQ(ierr); 2258984c4197SStefano Zampini aux_primal_numbering[total_primal_vertices]=temp_indices_to_constraint[temp_indices[i]+min_loc]; 2259984c4197SStefano Zampini aux_primal_minloc[total_primal_vertices]=min_loc; 2260984c4197SStefano Zampini total_primal_vertices++; 2261984c4197SStefano Zampini } 2262984c4197SStefano Zampini } 2263a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 2264a717540cSStefano Zampini qr_needed = PETSC_FALSE; 2265a717540cSStefano Zampini ierr = PetscBTCreate(pcbddc->local_primal_size,&qr_needed_idx);CHKERRQ(ierr); 2266a717540cSStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 2267a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 2268fa434743SStefano Zampini if (!pcbddc->use_qr_single) { 2269a717540cSStefano Zampini size_of_constraint = temp_indices[i+1]-temp_indices[i]; 2270a717540cSStefano Zampini j = 0; 2271a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 2272a717540cSStefano Zampini if (PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+k])) { 2273a717540cSStefano Zampini j++; 2274a717540cSStefano Zampini } 2275a717540cSStefano Zampini } 2276a717540cSStefano Zampini /* found more than one primal dof on the cc */ 2277a717540cSStefano Zampini if (j > 1) { 2278a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 2279a717540cSStefano Zampini qr_needed = PETSC_TRUE; 2280a717540cSStefano Zampini } 2281fa434743SStefano Zampini } else { 2282fa434743SStefano Zampini PetscBTSet(qr_needed_idx,i); 2283fa434743SStefano Zampini qr_needed = PETSC_TRUE; 2284fa434743SStefano Zampini } 2285a717540cSStefano Zampini } 2286a717540cSStefano Zampini } 2287984c4197SStefano Zampini /* free workspace */ 2288984c4197SStefano Zampini ierr = PetscFree(global_indices);CHKERRQ(ierr); 228945a1bb75SStefano Zampini 2290674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 2291a717540cSStefano Zampini ierr = PetscSortInt(total_primal_vertices,aux_primal_numbering);CHKERRQ(ierr); 2292984c4197SStefano Zampini 2293984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 2294785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 2295984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i]=1; 2296984c4197SStefano Zampini j=total_primal_vertices; 2297984c4197SStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 22984641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2299674ae819SStefano Zampini nnz[j]=temp_indices[i+1]-temp_indices[i]; 2300674ae819SStefano Zampini j++; 2301674ae819SStefano Zampini } 2302674ae819SStefano Zampini } 2303674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 2304674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2305674ae819SStefano Zampini /* set values in constraint matrix */ 2306984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 2307984c4197SStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,aux_primal_numbering[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 2308674ae819SStefano Zampini } 2309984c4197SStefano Zampini total_counts = total_primal_vertices; 2310984c4197SStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 23114641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2312674ae819SStefano Zampini size_of_constraint=temp_indices[i+1]-temp_indices[i]; 2313674ae819SStefano 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); 2314674ae819SStefano Zampini total_counts++; 2315674ae819SStefano Zampini } 2316674ae819SStefano Zampini } 2317674ae819SStefano Zampini /* assembling */ 2318674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2319674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2320984c4197SStefano Zampini /* 232145a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2322984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 2323984c4197SStefano Zampini */ 2324674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 2325674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 2326026de310SStefano Zampini /* dual and primal dofs on a single cc */ 2327984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 2328026de310SStefano Zampini /* iterator on aux_primal_minloc (ordered as read from nearnullspace: vertices, edges and then constraints) */ 2329026de310SStefano Zampini PetscInt primal_counter; 2330984c4197SStefano Zampini /* working stuff for GEQRF */ 233181d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 2332984c4197SStefano Zampini PetscBLASInt lqr_work; 2333984c4197SStefano Zampini /* working stuff for UNGQR */ 2334984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 2335984c4197SStefano Zampini PetscBLASInt lgqr_work; 2336984c4197SStefano Zampini /* working stuff for TRTRS */ 2337984c4197SStefano Zampini PetscScalar *trs_rhs; 23383f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 2339984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 2340984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 2341984c4197SStefano Zampini PetscScalar *start_vals; 2342984c4197SStefano Zampini /* working stuff for values insertion */ 23434641a718SStefano Zampini PetscBT is_primal; 2344906d46d4SStefano Zampini /* matrix sizes */ 2345906d46d4SStefano Zampini PetscInt global_size,local_size; 2346906d46d4SStefano Zampini /* temporary change of basis */ 2347906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 2348984c4197SStefano Zampini 2349906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 2350906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 2351906d46d4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,impMatType);CHKERRQ(ierr); 2352bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 2353906d46d4SStefano Zampini 2354906d46d4SStefano Zampini /* nonzeros for local mat */ 2355bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 2356bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 2357a717540cSStefano Zampini for (i=pcbddc->n_vertices;i<pcbddc->local_primal_size;i++) { 2358a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 2359a717540cSStefano Zampini size_of_constraint = temp_indices[i+1]-temp_indices[i]; 2360a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 2361bbb9e6c6SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[temp_indices_to_constraint[temp_indices[i]+j]] = size_of_constraint; 2362a717540cSStefano Zampini } else { 2363bbb9e6c6SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[temp_indices_to_constraint[temp_indices[i]+j]] = 2; 2364a717540cSStefano Zampini /* get local primal index on the cc */ 2365a717540cSStefano Zampini j = 0; 2366a717540cSStefano Zampini while (!PetscBTLookup(touched,temp_indices_to_constraint_B[temp_indices[i]+j])) j++; 2367bbb9e6c6SStefano Zampini nnz[temp_indices_to_constraint[temp_indices[i]+j]] = size_of_constraint; 2368a717540cSStefano Zampini } 2369a717540cSStefano Zampini } 2370a717540cSStefano Zampini } 2371906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 2372bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2373a717540cSStefano Zampini /* Set initial identity in the matrix */ 2374bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 2375906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 2376a717540cSStefano Zampini } 2377a717540cSStefano Zampini 2378a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2379a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2380a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2381a717540cSStefano Zampini } 2382a717540cSStefano Zampini 2383a717540cSStefano Zampini 2384a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 2385a717540cSStefano Zampini /* 2386a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 2387a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 2388a717540cSStefano Zampini 2389a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 2390a717540cSStefano Zampini 2391a6b551f4SStefano 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) 2392a6b551f4SStefano Zampini 2393a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 2394a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 2395a717540cSStefano Zampini | ... | 2396a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 2397a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 2398a717540cSStefano Zampini 2399a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 2400a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 2401a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 2402a6b551f4SStefano Zampini 2403a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 2404a717540cSStefano Zampini */ 2405a717540cSStefano Zampini if (qr_needed) { 2406984c4197SStefano Zampini /* space to store Q */ 2407854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 2408984c4197SStefano Zampini /* first we issue queries for optimal work */ 24093f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 24103f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 24113f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2412984c4197SStefano Zampini lqr_work = -1; 24133f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 2414984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 2415984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 2416785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 2417984c4197SStefano Zampini lgqr_work = -1; 24183f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 24193f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 24203f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 24213f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 24223f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 24233f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 2424984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 2425984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 2426785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 2427984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 2428785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 2429984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 2430785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 2431a717540cSStefano Zampini /* allocating workspace for check */ 2432a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2433785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&work);CHKERRQ(ierr); 2434a717540cSStefano Zampini } 2435a717540cSStefano Zampini } 2436984c4197SStefano Zampini /* array to store whether a node is primal or not */ 24374641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 2438473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 24395e8657edSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,aux_primal_numbering,&i,aux_primal_numbering_B);CHKERRQ(ierr); 244039e2fb2aSStefano Zampini if (i != total_primal_vertices) { 244139e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 24424641a718SStefano Zampini } 244339e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 244439e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 244539e2fb2aSStefano Zampini } 244639e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 2447984c4197SStefano Zampini 2448a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 2449026de310SStefano Zampini /* -> using implicit ordering contained in temp_indices data */ 2450026de310SStefano Zampini total_counts = pcbddc->n_vertices; 2451026de310SStefano Zampini primal_counter = total_counts; 2452026de310SStefano Zampini while (total_counts<pcbddc->local_primal_size) { 2453026de310SStefano Zampini primal_dofs = 1; 24544641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 2455026de310SStefano Zampini /* get all constraints with same support: if more then one constraint is present on the cc then surely indices are stored contiguosly */ 2456bbb9e6c6SStefano 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]]) { 2457026de310SStefano Zampini primal_dofs++; 2458674ae819SStefano Zampini } 2459984c4197SStefano Zampini /* get constraint info */ 2460026de310SStefano Zampini size_of_constraint = temp_indices[total_counts+1]-temp_indices[total_counts]; 2461984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 2462984c4197SStefano Zampini 2463984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2464a717540cSStefano 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); 2465674ae819SStefano Zampini } 2466984c4197SStefano Zampini 2467fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 2468a717540cSStefano Zampini 2469a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 2470a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2471a717540cSStefano Zampini ierr = PetscMemcpy(work,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2472a717540cSStefano Zampini } 2473984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 2474026de310SStefano Zampini ierr = PetscMemcpy(qr_basis,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2475984c4197SStefano Zampini 2476984c4197SStefano Zampini /* compute QR decomposition of constraints */ 24773f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 24783f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 24793f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2480674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 24813f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 2482984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 2483674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2484984c4197SStefano Zampini 2485984c4197SStefano Zampini /* explictly compute R^-T */ 2486984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 2487984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 24883f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 24893f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 24903f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 24913f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 2492984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 24933f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 2494984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 2495984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2496984c4197SStefano Zampini 2497a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 24983f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 24993f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 25003f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 25013f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2502984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 25033f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 2504984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 2505984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2506984c4197SStefano Zampini 2507984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 2508984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 2509984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 25103f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 25113f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 25123f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 25133f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 25143f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 25153f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2516984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2517c4303822SStefano 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)); 2518984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2519026de310SStefano Zampini ierr = PetscMemcpy(qr_basis,&temp_quadrature_constraint[temp_indices[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2520984c4197SStefano Zampini 2521984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 2522bbb9e6c6SStefano Zampini start_rows = &temp_indices_to_constraint[temp_indices[total_counts]]; 2523984c4197SStefano Zampini /* insert cols for primal dofs */ 2524984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 2525984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 2526bbb9e6c6SStefano Zampini start_cols = &temp_indices_to_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter+j]]; 2527906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 2528984c4197SStefano Zampini } 2529984c4197SStefano Zampini /* insert cols for dual dofs */ 2530984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 25314641a718SStefano Zampini if (!PetscBTLookup(is_primal,temp_indices_to_constraint_B[temp_indices[total_counts]+k])) { 2532984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 2533bbb9e6c6SStefano Zampini start_cols = &temp_indices_to_constraint[temp_indices[total_counts]+k]; 2534906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 2535984c4197SStefano Zampini j++; 2536674ae819SStefano Zampini } 2537674ae819SStefano Zampini } 2538984c4197SStefano Zampini 2539984c4197SStefano Zampini /* check change of basis */ 2540984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2541984c4197SStefano Zampini PetscInt ii,jj; 2542984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 2543c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 2544c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2545c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 2546c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2547c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 2548c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 2549984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2550c4303822SStefano 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)); 2551984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2552984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 2553984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 2554984c4197SStefano Zampini if (ii != jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 2555984c4197SStefano Zampini if (ii == jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) valid_qr = PETSC_FALSE; 2556674ae819SStefano Zampini } 2557674ae819SStefano Zampini } 2558984c4197SStefano Zampini if (!valid_qr) { 255922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 2560984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 2561984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 2562984c4197SStefano Zampini if (ii != jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 2563984c4197SStefano 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])); 2564674ae819SStefano Zampini } 2565984c4197SStefano Zampini if (ii == jj && PetscAbsScalar(work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 2566984c4197SStefano 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])); 2567984c4197SStefano Zampini } 2568984c4197SStefano Zampini } 2569984c4197SStefano Zampini } 2570674ae819SStefano Zampini } else { 257122d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 2572674ae819SStefano Zampini } 2573674ae819SStefano Zampini } 2574a717540cSStefano Zampini } else { /* simple transformation block */ 2575a717540cSStefano Zampini PetscInt row,col; 2576a6b551f4SStefano Zampini PetscScalar val,norm; 2577a6b551f4SStefano Zampini 2578a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2579a6b551f4SStefano 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)); 2580a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 2581bbb9e6c6SStefano Zampini PetscInt row_B = temp_indices_to_constraint_B[temp_indices[total_counts]+j]; 2582bbb9e6c6SStefano Zampini row = temp_indices_to_constraint[temp_indices[total_counts]+j]; 2583bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 2584bbb9e6c6SStefano Zampini col = temp_indices_to_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]; 2585906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 2586a6b551f4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,temp_quadrature_constraint[temp_indices[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 2587a717540cSStefano Zampini } else { 2588a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 2589bbb9e6c6SStefano Zampini col = temp_indices_to_constraint[temp_indices[total_counts]+k]; 2590a717540cSStefano Zampini if (row != col) { 2591a717540cSStefano Zampini val = -temp_quadrature_constraint[temp_indices[total_counts]+k]/temp_quadrature_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]; 2592a717540cSStefano Zampini } else { 2593a6b551f4SStefano Zampini val = temp_quadrature_constraint[temp_indices[total_counts]+aux_primal_minloc[primal_counter]]/norm; 2594a717540cSStefano Zampini } 2595906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 2596a717540cSStefano Zampini } 2597a717540cSStefano Zampini } 2598a717540cSStefano Zampini } 259998a51de6SStefano Zampini if (pcbddc->dbg_flag) { 260022d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 2601a717540cSStefano Zampini } 2602674ae819SStefano Zampini } 2603026de310SStefano Zampini /* increment primal counter */ 2604026de310SStefano Zampini primal_counter += primal_dofs; 2605984c4197SStefano Zampini } else { 2606984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2607026de310SStefano 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); 2608674ae819SStefano Zampini } 2609674ae819SStefano Zampini } 2610026de310SStefano Zampini /* increment constraint counter total_counts */ 2611026de310SStefano Zampini total_counts += primal_dofs; 2612674ae819SStefano Zampini } 2613a717540cSStefano Zampini 2614a717540cSStefano Zampini /* free workspace */ 2615a717540cSStefano Zampini if (qr_needed) { 2616984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2617984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2618984c4197SStefano Zampini } 2619984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 2620984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 2621984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 2622984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 2623984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 2624674ae819SStefano Zampini } 2625a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 2626906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2627906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2628906d46d4SStefano Zampini 2629906d46d4SStefano Zampini /* assembling of global change of variable */ 2630bbb9e6c6SStefano Zampini { 2631bbb9e6c6SStefano Zampini Mat tmat; 2632906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 2633906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 2634bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 2635bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 2636bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2637bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 2638906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 2639bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 2640bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2641bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2642bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2643bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 2644bbb9e6c6SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2645bbb9e6c6SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2646bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 2647bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 2648906d46d4SStefano Zampini } 2649906d46d4SStefano Zampini /* check */ 2650906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2651906d46d4SStefano Zampini PetscReal error; 2652906d46d4SStefano Zampini Vec x,x_change; 2653906d46d4SStefano Zampini 2654906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 2655906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 2656906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 2657906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 2658bbb9e6c6SStefano Zampini ierr = VecScatterBegin(matis->ctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2659bbb9e6c6SStefano Zampini ierr = VecScatterEnd(matis->ctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2660bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2661bbb9e6c6SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2662bbb9e6c6SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2663906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 2664906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2665906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2666906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2667bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 2668906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2669906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2670906d46d4SStefano Zampini } 2671b96c3477SStefano Zampini 2672b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 2673b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2674b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 2675b96c3477SStefano Zampini if (sub_schurs->n_subs_par_g) { 2676b7eb3628SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Change of basis with deluxe scaling and parallel problems still needs to be implemented"); 2677b96c3477SStefano Zampini } 2678b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 2679b96c3477SStefano Zampini Mat S_1,S_2,tmat; 2680bbb9e6c6SStefano Zampini IS is_all_N; 2681bbb9e6c6SStefano Zampini 2682bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 2683bbb9e6c6SStefano Zampini ierr = MatGetSubMatrixUnsorted(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 2684bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 2685b96c3477SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_1);CHKERRQ(ierr); 2686b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 2687b96c3477SStefano Zampini sub_schurs->S_Ej_all = S_1; 2688b96c3477SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_2);CHKERRQ(ierr); 2689b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 2690b96c3477SStefano Zampini sub_schurs->sum_S_Ej_all = S_2; 2691b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2692b96c3477SStefano Zampini } 2693b96c3477SStefano Zampini } 2694906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 2695906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 2696b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2697b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 2698b9b85e73SStefano Zampini } 2699906d46d4SStefano Zampini 2700906d46d4SStefano Zampini /* set up change of basis context */ 2701906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2702906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 2703906d46d4SStefano Zampini 2704906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 2705906d46d4SStefano Zampini PetscInt global_size,local_size; 2706906d46d4SStefano Zampini 2707906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 2708906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 2709906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 2710906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 2711906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 2712906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 2713906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 2714906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 2715906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 2716906d46d4SStefano Zampini } else { 2717906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 2718906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 2719906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 2720906d46d4SStefano Zampini } 2721906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 2722906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2723906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 2724906d46d4SStefano Zampini } else { 2725906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2726906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 2727906d46d4SStefano Zampini } 2728906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 2729906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 2730906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2731906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2732b9b85e73SStefano Zampini } 2733a717540cSStefano Zampini 2734727cdba6SStefano Zampini /* get indices in local ordering for vertices and constraints */ 2735727cdba6SStefano 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 */ 2736473ba861SJed Brown ierr = PetscMalloc1(olocal_primal_size,&oprimal_indices_local_idxs);CHKERRQ(ierr); 2737727cdba6SStefano Zampini ierr = PetscMemcpy(oprimal_indices_local_idxs,pcbddc->primal_indices_local_idxs,olocal_primal_size*sizeof(PetscInt));CHKERRQ(ierr); 2738727cdba6SStefano Zampini } 2739727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2740f347579bSStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2741473ba861SJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2742727cdba6SStefano Zampini ierr = PCBDDCGetPrimalVerticesLocalIdx(pc,&i,&aux_primal_numbering);CHKERRQ(ierr); 2743727cdba6SStefano Zampini ierr = PetscMemcpy(pcbddc->primal_indices_local_idxs,aux_primal_numbering,i*sizeof(PetscInt));CHKERRQ(ierr); 2744727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2745727cdba6SStefano Zampini ierr = PCBDDCGetPrimalConstraintsLocalIdx(pc,&j,&aux_primal_numbering);CHKERRQ(ierr); 2746727cdba6SStefano Zampini ierr = PetscMemcpy(&pcbddc->primal_indices_local_idxs[i],aux_primal_numbering,j*sizeof(PetscInt));CHKERRQ(ierr); 2747727cdba6SStefano Zampini ierr = PetscFree(aux_primal_numbering);CHKERRQ(ierr); 2748e9189074SStefano Zampini /* set quantities in PCBDDC data struct */ 2749e9189074SStefano Zampini pcbddc->n_actual_vertices = i; 2750727cdba6SStefano Zampini /* check if a new primal space has been introduced */ 2751727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 2752727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 2753727cdba6SStefano Zampini ierr = PetscMemcmp(pcbddc->primal_indices_local_idxs,oprimal_indices_local_idxs,olocal_primal_size,&pcbddc->new_primal_space_local);CHKERRQ(ierr); 2754c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 2755727cdba6SStefano Zampini ierr = PetscFree(oprimal_indices_local_idxs);CHKERRQ(ierr); 2756727cdba6SStefano Zampini } 2757727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 2758727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2759727cdba6SStefano Zampini 2760a717540cSStefano Zampini /* flush dbg viewer */ 2761b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 2762b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2763b8ffe317SStefano Zampini } 2764a717540cSStefano Zampini 2765e310c8b4SStefano Zampini /* free workspace */ 2766a717540cSStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 2767a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 2768984c4197SStefano Zampini ierr = PetscFree(aux_primal_minloc);CHKERRQ(ierr); 27694641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 277008122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 2771906d46d4SStefano Zampini ierr = PetscFree(temp_indices);CHKERRQ(ierr); 2772906d46d4SStefano Zampini ierr = PetscFree3(temp_quadrature_constraint,temp_indices_to_constraint,temp_indices_to_constraint_B);CHKERRQ(ierr); 277308122e43SStefano Zampini } else { 277408122e43SStefano Zampini ierr = PetscFree4(pcbddc->adaptive_constraints_n, 277508122e43SStefano Zampini pcbddc->adaptive_constraints_ptrs, 277608122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 277708122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 277808122e43SStefano Zampini ierr = PetscFree(temp_indices_to_constraint_B);CHKERRQ(ierr); 277908122e43SStefano Zampini } 2780674ae819SStefano Zampini PetscFunctionReturn(0); 2781674ae819SStefano Zampini } 2782674ae819SStefano Zampini 2783674ae819SStefano Zampini #undef __FUNCT__ 2784674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 2785674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 2786674ae819SStefano Zampini { 2787674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2788674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 2789674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 279063602bcaSStefano Zampini PetscInt ierr,i,vertex_size; 2791674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 2792674ae819SStefano Zampini 2793674ae819SStefano Zampini PetscFunctionBegin; 27948e61c736SStefano Zampini /* Reset previously computed graph */ 27958e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 2796674ae819SStefano Zampini /* Init local Graph struct */ 2797674ae819SStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,matis->mapping);CHKERRQ(ierr); 2798674ae819SStefano Zampini 2799575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 2800575ad6abSStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 2801575ad6abSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 2802575ad6abSStefano Zampini } 28039577ea80SStefano Zampini 2804674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 28054d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 2806674ae819SStefano Zampini Mat mat_adj; 28074d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 28084d379d7bSStefano Zampini PetscInt nvtxs; 2809674ae819SStefano Zampini PetscBool flg_row=PETSC_TRUE; 2810674ae819SStefano Zampini 2811674ae819SStefano Zampini ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 28124d379d7bSStefano Zampini ierr = MatGetRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 2813674ae819SStefano Zampini if (!flg_row) { 2814674ae819SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 2815674ae819SStefano Zampini } 28164d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 28174d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 2818b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 28194d379d7bSStefano Zampini } else { /* just compute subdomain's connected components */ 28204d379d7bSStefano Zampini IS is_dummy; 28214d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 28224d379d7bSStefano Zampini PetscInt j,sum; 28234d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 28244d379d7bSStefano Zampini const PetscInt *idxs; 28254d379d7bSStefano Zampini PCBDDCGraph graph; 28264d379d7bSStefano Zampini PetscBT is_on_boundary; 28274d379d7bSStefano Zampini 28284d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 28294d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 28304d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 28314d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 28324d379d7bSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy);CHKERRQ(ierr); 28334d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 28344d379d7bSStefano Zampini graph->xadj = xadj; 28354d379d7bSStefano Zampini graph->adjncy = adjncy; 28364d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 28374d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 28384d379d7bSStefano Zampini 28394d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 28404d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains\n",PetscGlobalRank,graph->ncc);CHKERRQ(ierr); 28414d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 28424d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 28434d379d7bSStefano Zampini } 28444d379d7bSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 28454d379d7bSStefano Zampini } 28464d379d7bSStefano Zampini 28474d379d7bSStefano Zampini ierr = PetscBTCreate(nvtxs,&is_on_boundary);CHKERRQ(ierr); 28484d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 28494d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 28504d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 28514d379d7bSStefano Zampini } 28524d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 28534d379d7bSStefano Zampini 28544d379d7bSStefano Zampini ierr = PetscCalloc1(nvtxs+1,&cxadj);CHKERRQ(ierr); 28554d379d7bSStefano Zampini sum = 0; 28564d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 28574d379d7bSStefano Zampini PetscInt sizecc = 0; 28584d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 28594d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 28604d379d7bSStefano Zampini sizecc++; 28614d379d7bSStefano Zampini } 28624d379d7bSStefano Zampini } 28634d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 28644d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 28654d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 28664d379d7bSStefano Zampini } 28674d379d7bSStefano Zampini } 28684d379d7bSStefano Zampini sum += sizecc*sizecc; 28694d379d7bSStefano Zampini } 28704d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 28714d379d7bSStefano Zampini sum = 0; 28724d379d7bSStefano Zampini for (i=0;i<nvtxs;i++) { 28734d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 28744d379d7bSStefano Zampini cxadj[i] = sum; 28754d379d7bSStefano Zampini sum += temp; 28764d379d7bSStefano Zampini } 28774d379d7bSStefano Zampini cxadj[nvtxs] = sum; 28784d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 28794d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 28804d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 28814d379d7bSStefano Zampini PetscInt k,sizecc = 0; 28824d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 28834d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 28844d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 28854d379d7bSStefano Zampini sizecc++; 28864d379d7bSStefano Zampini } 28874d379d7bSStefano Zampini } 28884d379d7bSStefano Zampini } 28894d379d7bSStefano Zampini } 28904d379d7bSStefano Zampini } 28914d379d7bSStefano Zampini if (nvtxs) { 28924d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 28934d379d7bSStefano Zampini } else { 28944d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 28954d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 28964d379d7bSStefano Zampini } 28974d379d7bSStefano Zampini graph->xadj = 0; 28984d379d7bSStefano Zampini graph->adjncy = 0; 28994d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 29004d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 29014d379d7bSStefano Zampini } 29024d379d7bSStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 2903674ae819SStefano Zampini if (!flg_row) { 2904674ae819SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 2905674ae819SStefano Zampini } 2906674ae819SStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 2907674ae819SStefano Zampini } 2908674ae819SStefano Zampini 290963602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 2910674ae819SStefano Zampini vertex_size = 1; 291163602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 291263602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 291395ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 291463602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 2915a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 291663602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 2917674ae819SStefano Zampini } 291863602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 291963602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 292063602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 2921674ae819SStefano Zampini } 292263602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 2923674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 292463602bcaSStefano Zampini } else { 292563602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 292663602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 2927854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 292863602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 292963602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 293063602bcaSStefano Zampini } 293163602bcaSStefano Zampini } 2932674ae819SStefano Zampini } 2933674ae819SStefano Zampini 2934674ae819SStefano Zampini /* Setup of Graph */ 2935785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 2936a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 2937785d1243SStefano Zampini } 2938785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 2939a7dc3881SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->ctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 2940785d1243SStefano Zampini } 294163602bcaSStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices); 2942674ae819SStefano Zampini 2943674ae819SStefano Zampini /* Graph's connected components analysis */ 2944674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 2945674ae819SStefano Zampini 2946674ae819SStefano Zampini /* print some info to stdout */ 2947674ae819SStefano Zampini if (pcbddc->dbg_flag) { 2948e49050b4SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer); 2949674ae819SStefano Zampini } 2950fb180af4SStefano Zampini 2951fb180af4SStefano Zampini /* mark topography has done */ 2952fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 2953674ae819SStefano Zampini PetscFunctionReturn(0); 2954674ae819SStefano Zampini } 2955674ae819SStefano Zampini 2956674ae819SStefano Zampini #undef __FUNCT__ 2957674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGetPrimalVerticesLocalIdx" 2958f34684f1SStefano Zampini PetscErrorCode PCBDDCGetPrimalVerticesLocalIdx(PC pc, PetscInt *n_vertices, PetscInt **vertices_idx) 2959674ae819SStefano Zampini { 2960674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2961674ae819SStefano Zampini PetscInt *vertices,*row_cmat_indices,n,i,size_of_constraint,local_primal_size; 2962674ae819SStefano Zampini PetscErrorCode ierr; 2963674ae819SStefano Zampini 2964674ae819SStefano Zampini PetscFunctionBegin; 2965674ae819SStefano Zampini n = 0; 2966674ae819SStefano Zampini vertices = 0; 2967674ae819SStefano Zampini if (pcbddc->ConstraintMatrix) { 2968674ae819SStefano Zampini ierr = MatGetSize(pcbddc->ConstraintMatrix,&local_primal_size,&i);CHKERRQ(ierr); 2969b120a5c6SStefano Zampini for (i=0;i<local_primal_size;i++) { 2970b120a5c6SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2971b120a5c6SStefano Zampini if (size_of_constraint == 1) n++; 2972b120a5c6SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 2973b120a5c6SStefano Zampini } 2974811e8ca2SStefano Zampini if (vertices_idx) { 2975785e854fSJed Brown ierr = PetscMalloc1(n,&vertices);CHKERRQ(ierr); 2976b120a5c6SStefano Zampini n = 0; 2977674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 2978674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2979674ae819SStefano Zampini if (size_of_constraint == 1) { 2980674ae819SStefano Zampini vertices[n++]=row_cmat_indices[0]; 2981674ae819SStefano Zampini } 2982674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 2983674ae819SStefano Zampini } 2984674ae819SStefano Zampini } 2985811e8ca2SStefano Zampini } 2986674ae819SStefano Zampini *n_vertices = n; 2987811e8ca2SStefano Zampini if (vertices_idx) *vertices_idx = vertices; 2988674ae819SStefano Zampini PetscFunctionReturn(0); 2989674ae819SStefano Zampini } 2990674ae819SStefano Zampini 2991674ae819SStefano Zampini #undef __FUNCT__ 2992674ae819SStefano Zampini #define __FUNCT__ "PCBDDCGetPrimalConstraintsLocalIdx" 2993f34684f1SStefano Zampini PetscErrorCode PCBDDCGetPrimalConstraintsLocalIdx(PC pc, PetscInt *n_constraints, PetscInt **constraints_idx) 2994674ae819SStefano Zampini { 2995674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2996674ae819SStefano Zampini PetscInt *constraints_index,*row_cmat_indices,*row_cmat_global_indices; 2997674ae819SStefano Zampini PetscInt n,i,j,size_of_constraint,local_primal_size,local_size,max_size_of_constraint,min_index,min_loc; 29984641a718SStefano Zampini PetscBT touched; 2999674ae819SStefano Zampini PetscErrorCode ierr; 3000674ae819SStefano Zampini 3001f34684f1SStefano Zampini /* This function assumes that the number of local constraints per connected component 3002f34684f1SStefano Zampini is not greater than the number of nodes defined for the connected component 3003f34684f1SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 3004674ae819SStefano Zampini PetscFunctionBegin; 3005674ae819SStefano Zampini n = 0; 3006674ae819SStefano Zampini constraints_index = 0; 3007674ae819SStefano Zampini if (pcbddc->ConstraintMatrix) { 3008674ae819SStefano Zampini ierr = MatGetSize(pcbddc->ConstraintMatrix,&local_primal_size,&local_size);CHKERRQ(ierr); 3009674ae819SStefano Zampini max_size_of_constraint = 0; 3010674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 3011674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 3012674ae819SStefano Zampini if (size_of_constraint > 1) { 3013674ae819SStefano Zampini n++; 3014674ae819SStefano Zampini } 3015674ae819SStefano Zampini max_size_of_constraint = PetscMax(size_of_constraint,max_size_of_constraint); 3016674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,NULL,NULL);CHKERRQ(ierr); 3017674ae819SStefano Zampini } 3018811e8ca2SStefano Zampini if (constraints_idx) { 3019785e854fSJed Brown ierr = PetscMalloc1(n,&constraints_index);CHKERRQ(ierr); 3020785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint,&row_cmat_global_indices);CHKERRQ(ierr); 30214641a718SStefano Zampini ierr = PetscBTCreate(local_size,&touched);CHKERRQ(ierr); 3022674ae819SStefano Zampini n = 0; 3023674ae819SStefano Zampini for (i=0;i<local_primal_size;i++) { 3024674ae819SStefano Zampini ierr = MatGetRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 3025674ae819SStefano Zampini if (size_of_constraint > 1) { 3026674ae819SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcbddc->mat_graph->l2gmap,size_of_constraint,row_cmat_indices,row_cmat_global_indices);CHKERRQ(ierr); 302782d3d8afSStefano Zampini /* find first untouched local node */ 302882d3d8afSStefano Zampini j = 0; 30294641a718SStefano Zampini while (PetscBTLookup(touched,row_cmat_indices[j])) j++; 303082d3d8afSStefano Zampini min_index = row_cmat_global_indices[j]; 303182d3d8afSStefano Zampini min_loc = j; 303282d3d8afSStefano Zampini /* search the minimum among nodes not yet touched on the connected component 303382d3d8afSStefano Zampini since there can be more than one constraint on a single cc */ 3034674ae819SStefano Zampini for (j=1;j<size_of_constraint;j++) { 30354641a718SStefano Zampini if (!PetscBTLookup(touched,row_cmat_indices[j]) && min_index > row_cmat_global_indices[j]) { 3036674ae819SStefano Zampini min_index = row_cmat_global_indices[j]; 3037674ae819SStefano Zampini min_loc = j; 3038674ae819SStefano Zampini } 3039674ae819SStefano Zampini } 30404641a718SStefano Zampini ierr = PetscBTSet(touched,row_cmat_indices[min_loc]);CHKERRQ(ierr); 3041674ae819SStefano Zampini constraints_index[n++] = row_cmat_indices[min_loc]; 3042674ae819SStefano Zampini } 3043674ae819SStefano Zampini ierr = MatRestoreRow(pcbddc->ConstraintMatrix,i,&size_of_constraint,(const PetscInt**)&row_cmat_indices,NULL);CHKERRQ(ierr); 3044674ae819SStefano Zampini } 30454641a718SStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 3046674ae819SStefano Zampini ierr = PetscFree(row_cmat_global_indices);CHKERRQ(ierr); 3047811e8ca2SStefano Zampini } 3048811e8ca2SStefano Zampini } 3049674ae819SStefano Zampini *n_constraints = n; 3050811e8ca2SStefano Zampini if (constraints_idx) *constraints_idx = constraints_index; 3051674ae819SStefano Zampini PetscFunctionReturn(0); 3052674ae819SStefano Zampini } 3053674ae819SStefano Zampini 3054674ae819SStefano Zampini #undef __FUNCT__ 3055674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 3056674ae819SStefano 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[]) 3057674ae819SStefano Zampini { 3058674ae819SStefano Zampini Vec local_vec,global_vec; 3059674ae819SStefano Zampini IS seqis,paris; 3060674ae819SStefano Zampini VecScatter scatter_ctx; 3061674ae819SStefano Zampini PetscScalar *array; 3062674ae819SStefano Zampini PetscInt *temp_global_dofs; 3063674ae819SStefano Zampini PetscScalar globalsum; 3064674ae819SStefano Zampini PetscInt i,j,s; 3065674ae819SStefano Zampini PetscInt nlocals,first_index,old_index,max_local; 3066674ae819SStefano Zampini PetscMPIInt rank_prec_comm,size_prec_comm,max_global; 3067674ae819SStefano Zampini PetscMPIInt *dof_sizes,*dof_displs; 3068674ae819SStefano Zampini PetscBool first_found; 3069674ae819SStefano Zampini PetscErrorCode ierr; 3070674ae819SStefano Zampini 3071674ae819SStefano Zampini PetscFunctionBegin; 3072674ae819SStefano Zampini /* mpi buffers */ 3073b9b85e73SStefano Zampini ierr = MPI_Comm_size(comm,&size_prec_comm);CHKERRQ(ierr); 3074b9b85e73SStefano Zampini ierr = MPI_Comm_rank(comm,&rank_prec_comm);CHKERRQ(ierr); 3075674ae819SStefano Zampini j = ( !rank_prec_comm ? size_prec_comm : 0); 3076785e854fSJed Brown ierr = PetscMalloc1(j,&dof_sizes);CHKERRQ(ierr); 3077785e854fSJed Brown ierr = PetscMalloc1(j,&dof_displs);CHKERRQ(ierr); 3078674ae819SStefano Zampini /* get maximum size of subset */ 3079785e854fSJed Brown ierr = PetscMalloc1(n_local_dofs,&temp_global_dofs);CHKERRQ(ierr); 3080674ae819SStefano Zampini ierr = ISLocalToGlobalMappingApply(l2gmap,n_local_dofs,local_dofs,temp_global_dofs);CHKERRQ(ierr); 3081674ae819SStefano Zampini max_local = 0; 3082b9b85e73SStefano Zampini for (i=0;i<n_local_dofs;i++) { 3083674ae819SStefano Zampini if (max_local < temp_global_dofs[i] ) { 3084674ae819SStefano Zampini max_local = temp_global_dofs[i]; 3085674ae819SStefano Zampini } 3086674ae819SStefano Zampini } 3087b9b85e73SStefano Zampini ierr = MPI_Allreduce(&max_local,&max_global,1,MPIU_INT,MPI_MAX,comm);CHKERRQ(ierr); 3088674ae819SStefano Zampini max_global++; 3089674ae819SStefano Zampini max_local = 0; 3090b9b85e73SStefano Zampini for (i=0;i<n_local_dofs;i++) { 3091674ae819SStefano Zampini if (max_local < local_dofs[i] ) { 3092674ae819SStefano Zampini max_local = local_dofs[i]; 3093674ae819SStefano Zampini } 3094674ae819SStefano Zampini } 3095674ae819SStefano Zampini max_local++; 3096674ae819SStefano Zampini /* allocate workspace */ 3097674ae819SStefano Zampini ierr = VecCreate(PETSC_COMM_SELF,&local_vec);CHKERRQ(ierr); 3098674ae819SStefano Zampini ierr = VecSetSizes(local_vec,PETSC_DECIDE,max_local);CHKERRQ(ierr); 3099674ae819SStefano Zampini ierr = VecSetType(local_vec,VECSEQ);CHKERRQ(ierr); 3100674ae819SStefano Zampini ierr = VecCreate(comm,&global_vec);CHKERRQ(ierr); 3101674ae819SStefano Zampini ierr = VecSetSizes(global_vec,PETSC_DECIDE,max_global);CHKERRQ(ierr); 3102674ae819SStefano Zampini ierr = VecSetType(global_vec,VECMPI);CHKERRQ(ierr); 3103674ae819SStefano Zampini /* create scatter */ 3104674ae819SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n_local_dofs,local_dofs,PETSC_COPY_VALUES,&seqis);CHKERRQ(ierr); 3105674ae819SStefano Zampini ierr = ISCreateGeneral(comm,n_local_dofs,temp_global_dofs,PETSC_COPY_VALUES,&paris);CHKERRQ(ierr); 3106674ae819SStefano Zampini ierr = VecScatterCreate(local_vec,seqis,global_vec,paris,&scatter_ctx);CHKERRQ(ierr); 3107674ae819SStefano Zampini ierr = ISDestroy(&seqis);CHKERRQ(ierr); 3108674ae819SStefano Zampini ierr = ISDestroy(&paris);CHKERRQ(ierr); 3109674ae819SStefano Zampini /* init array */ 3110674ae819SStefano Zampini ierr = VecSet(global_vec,0.0);CHKERRQ(ierr); 3111674ae819SStefano Zampini ierr = VecSet(local_vec,0.0);CHKERRQ(ierr); 3112674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 3113674ae819SStefano Zampini if (local_dofs_mult) { 3114674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 3115674ae819SStefano Zampini array[local_dofs[i]]=(PetscScalar)local_dofs_mult[i]; 3116674ae819SStefano Zampini } 3117674ae819SStefano Zampini } else { 3118674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 3119674ae819SStefano Zampini array[local_dofs[i]]=1.0; 3120674ae819SStefano Zampini } 3121674ae819SStefano Zampini } 3122674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 3123674ae819SStefano Zampini /* scatter into global vec and get total number of global dofs */ 3124674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,local_vec,global_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3125674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,local_vec,global_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3126674ae819SStefano Zampini ierr = VecSum(global_vec,&globalsum);CHKERRQ(ierr); 31275b08dc53SStefano Zampini *n_global_subset = (PetscInt)PetscRealPart(globalsum); 3128674ae819SStefano Zampini /* Fill global_vec with cumulative function for global numbering */ 3129674ae819SStefano Zampini ierr = VecGetArray(global_vec,&array);CHKERRQ(ierr); 3130674ae819SStefano Zampini ierr = VecGetLocalSize(global_vec,&s);CHKERRQ(ierr); 3131674ae819SStefano Zampini nlocals = 0; 3132674ae819SStefano Zampini first_index = -1; 3133674ae819SStefano Zampini first_found = PETSC_FALSE; 3134674ae819SStefano Zampini for (i=0;i<s;i++) { 3135b9b85e73SStefano Zampini if (!first_found && PetscRealPart(array[i]) > 0.1) { 3136674ae819SStefano Zampini first_found = PETSC_TRUE; 3137674ae819SStefano Zampini first_index = i; 3138674ae819SStefano Zampini } 31395b08dc53SStefano Zampini nlocals += (PetscInt)PetscRealPart(array[i]); 3140674ae819SStefano Zampini } 3141674ae819SStefano Zampini ierr = MPI_Gather(&nlocals,1,MPIU_INT,dof_sizes,1,MPIU_INT,0,comm);CHKERRQ(ierr); 3142674ae819SStefano Zampini if (!rank_prec_comm) { 3143674ae819SStefano Zampini dof_displs[0]=0; 3144674ae819SStefano Zampini for (i=1;i<size_prec_comm;i++) { 3145674ae819SStefano Zampini dof_displs[i] = dof_displs[i-1]+dof_sizes[i-1]; 3146674ae819SStefano Zampini } 3147674ae819SStefano Zampini } 3148674ae819SStefano Zampini ierr = MPI_Scatter(dof_displs,1,MPIU_INT,&nlocals,1,MPIU_INT,0,comm);CHKERRQ(ierr); 3149674ae819SStefano Zampini if (first_found) { 3150674ae819SStefano Zampini array[first_index] += (PetscScalar)nlocals; 3151674ae819SStefano Zampini old_index = first_index; 3152674ae819SStefano Zampini for (i=first_index+1;i<s;i++) { 3153b9b85e73SStefano Zampini if (PetscRealPart(array[i]) > 0.1) { 3154674ae819SStefano Zampini array[i] += array[old_index]; 3155674ae819SStefano Zampini old_index = i; 3156674ae819SStefano Zampini } 3157674ae819SStefano Zampini } 3158674ae819SStefano Zampini } 3159674ae819SStefano Zampini ierr = VecRestoreArray(global_vec,&array);CHKERRQ(ierr); 3160674ae819SStefano Zampini ierr = VecSet(local_vec,0.0);CHKERRQ(ierr); 3161674ae819SStefano Zampini ierr = VecScatterBegin(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3162674ae819SStefano Zampini ierr = VecScatterEnd(scatter_ctx,global_vec,local_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3163674ae819SStefano Zampini /* get global ordering of local dofs */ 3164674ae819SStefano Zampini ierr = VecGetArray(local_vec,&array);CHKERRQ(ierr); 3165674ae819SStefano Zampini if (local_dofs_mult) { 3166674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 31675b08dc53SStefano Zampini temp_global_dofs[i] = (PetscInt)PetscRealPart(array[local_dofs[i]])-local_dofs_mult[i]; 3168674ae819SStefano Zampini } 3169674ae819SStefano Zampini } else { 3170674ae819SStefano Zampini for (i=0;i<n_local_dofs;i++) { 31715b08dc53SStefano Zampini temp_global_dofs[i] = (PetscInt)PetscRealPart(array[local_dofs[i]])-1; 3172674ae819SStefano Zampini } 3173674ae819SStefano Zampini } 3174674ae819SStefano Zampini ierr = VecRestoreArray(local_vec,&array);CHKERRQ(ierr); 3175674ae819SStefano Zampini /* free workspace */ 3176674ae819SStefano Zampini ierr = VecScatterDestroy(&scatter_ctx);CHKERRQ(ierr); 3177674ae819SStefano Zampini ierr = VecDestroy(&local_vec);CHKERRQ(ierr); 3178674ae819SStefano Zampini ierr = VecDestroy(&global_vec);CHKERRQ(ierr); 3179674ae819SStefano Zampini ierr = PetscFree(dof_sizes);CHKERRQ(ierr); 3180674ae819SStefano Zampini ierr = PetscFree(dof_displs);CHKERRQ(ierr); 3181674ae819SStefano Zampini /* return pointer to global ordering of local dofs */ 3182674ae819SStefano Zampini *global_numbering_subset = temp_global_dofs; 3183674ae819SStefano Zampini PetscFunctionReturn(0); 3184674ae819SStefano Zampini } 31859a7d3425SStefano Zampini 31869a7d3425SStefano Zampini #undef __FUNCT__ 31879a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 31889a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 31899a7d3425SStefano Zampini { 31909a7d3425SStefano Zampini PetscInt i,j; 31919a7d3425SStefano Zampini PetscScalar *alphas; 31929a7d3425SStefano Zampini PetscErrorCode ierr; 31939a7d3425SStefano Zampini 31949a7d3425SStefano Zampini PetscFunctionBegin; 31959a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 3196785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 31979a7d3425SStefano Zampini for (i=0;i<n;i++) { 31989a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 31999a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 32009a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 32019a7d3425SStefano Zampini } 32029a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 32039a7d3425SStefano Zampini PetscFunctionReturn(0); 32049a7d3425SStefano Zampini } 32059a7d3425SStefano Zampini 3206e7931f94SStefano Zampini #undef __FUNCT__ 320770cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 320828143c3dSStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscBool contiguous, IS* is_sends) 3209e7931f94SStefano Zampini { 3210e7931f94SStefano Zampini Mat subdomain_adj; 3211e7931f94SStefano Zampini IS new_ranks,ranks_send_to; 3212e7931f94SStefano Zampini MatPartitioning partitioner; 3213e7931f94SStefano Zampini Mat_IS *matis; 3214e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 3215e7931f94SStefano Zampini PetscInt prank; 3216e7931f94SStefano Zampini PetscMPIInt size,rank,color; 3217e7931f94SStefano Zampini PetscInt *xadj,*adjncy,*oldranks; 3218e7931f94SStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*is_indices,*ranks_send_to_idx; 32193837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 3220e7931f94SStefano Zampini PetscErrorCode ierr; 32212b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 3222e7931f94SStefano Zampini PetscSubcomm subcomm; 3223a57a6d2fSStefano Zampini 3224e7931f94SStefano Zampini PetscFunctionBegin; 32252b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 32262b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 32272b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 3228e7931f94SStefano Zampini 3229e7931f94SStefano Zampini /* Get info on mapping */ 3230e7931f94SStefano Zampini matis = (Mat_IS*)(mat->data); 3231e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->mapping,&local_size);CHKERRQ(ierr); 3232e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(matis->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3233e7931f94SStefano Zampini 3234e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 3235785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 3236e7931f94SStefano Zampini xadj[0] = 0; 3237e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 3238785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 3239785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 3240e7931f94SStefano Zampini 32412b510759SStefano Zampini if (threshold) { 3242d023bfaeSStefano Zampini PetscInt xadj_count = 0; 32432b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 3244d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 3245d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 3246d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 3247d023bfaeSStefano Zampini xadj_count++; 3248e7931f94SStefano Zampini } 3249e7931f94SStefano Zampini } 3250d023bfaeSStefano Zampini xadj[1] = xadj_count; 3251c8587f34SStefano Zampini } else { 3252e7931f94SStefano Zampini if (xadj[1]) { 3253e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 3254e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 3255c8587f34SStefano Zampini } 3256e7931f94SStefano Zampini } 3257e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(matis->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3258e7931f94SStefano Zampini if (use_square) { 3259e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3260e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 3261e7931f94SStefano Zampini } 3262e7931f94SStefano Zampini } 3263e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3264e7931f94SStefano Zampini 32653837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 3266e7931f94SStefano Zampini 3267e7931f94SStefano Zampini /* 3268e7931f94SStefano Zampini Restrict work on active processes only. 3269e7931f94SStefano Zampini */ 3270e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 3271e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 3272e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 32732b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 3274d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 3275e7931f94SStefano Zampini if (color) { 3276e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 3277e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 3278e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3279c8587f34SStefano Zampini } else { 328028143c3dSStefano Zampini PetscInt coarsening_ratio; 3281e7931f94SStefano Zampini ierr = MPI_Comm_size(subcomm->comm,&size);CHKERRQ(ierr); 3282785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 3283e7931f94SStefano Zampini prank = rank; 3284e7931f94SStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm->comm);CHKERRQ(ierr); 32858002ef2cSStefano Zampini /* 3286e7931f94SStefano Zampini for (i=0;i<size;i++) { 3287e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 3288c8587f34SStefano Zampini } 32898002ef2cSStefano Zampini */ 3290e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3291e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 3292c8587f34SStefano Zampini } 3293e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3294e7931f94SStefano Zampini ierr = MatCreateMPIAdj(subcomm->comm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 329522b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 3296e7931f94SStefano Zampini 3297e7931f94SStefano Zampini /* Partition */ 3298e7931f94SStefano Zampini ierr = MatPartitioningCreate(subcomm->comm,&partitioner);CHKERRQ(ierr); 3299e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 3300e7931f94SStefano Zampini if (use_vwgt) { 33013837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 3302e7931f94SStefano Zampini v_wgt[0] = local_size; 3303e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 3304c8587f34SStefano Zampini } 330528143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 330628143c3dSStefano Zampini coarsening_ratio = size/n_subdomains; 330728143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 3308e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 3309e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 331022b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 3311e7931f94SStefano Zampini 3312e7931f94SStefano Zampini ierr = ISGetIndices(new_ranks,(const PetscInt**)&is_indices);CHKERRQ(ierr); 331328143c3dSStefano Zampini if (contiguous) { 331428143c3dSStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; /* contiguos set of processes */ 331528143c3dSStefano Zampini } else { 331684ba6060SStefano Zampini ranks_send_to_idx[0] = coarsening_ratio*oldranks[is_indices[0]]; /* scattered set of processes */ 331728143c3dSStefano Zampini } 3318e7931f94SStefano Zampini ierr = ISRestoreIndices(new_ranks,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3319e7931f94SStefano Zampini /* clean up */ 3320e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 3321e7931f94SStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 3322e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 3323e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 3324e7931f94SStefano Zampini } 3325e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 3326e7931f94SStefano Zampini 3327e7931f94SStefano Zampini /* assemble parallel IS for sends */ 3328e7931f94SStefano Zampini i = 1; 3329e7931f94SStefano Zampini if (color) i=0; 3330e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 3331e7931f94SStefano Zampini 3332e7931f94SStefano Zampini /* get back IS */ 3333e7931f94SStefano Zampini *is_sends = ranks_send_to; 3334e7931f94SStefano Zampini PetscFunctionReturn(0); 3335e7931f94SStefano Zampini } 3336e7931f94SStefano Zampini 3337e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 3338e7931f94SStefano Zampini 3339e7931f94SStefano Zampini #undef __FUNCT__ 3340e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 334128143c3dSStefano Zampini PetscErrorCode MatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, MatReuse reuse, Mat *mat_n, PetscInt nis, IS isarray[]) 3342e7931f94SStefano Zampini { 334370cf5478SStefano Zampini Mat local_mat; 3344e7931f94SStefano Zampini Mat_IS *matis; 3345e7931f94SStefano Zampini IS is_sends_internal; 33469d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 334728143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 33489d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 3349e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 3350e7931f94SStefano Zampini PetscInt* l2gmap_indices; 3351e7931f94SStefano Zampini const PetscInt* is_indices; 3352e7931f94SStefano Zampini MatType new_local_type; 3353e7931f94SStefano Zampini /* buffers */ 3354e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 335528143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 33569d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 3357e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 3358e7931f94SStefano Zampini /* MPI */ 335928143c3dSStefano Zampini MPI_Comm comm,comm_n; 336028143c3dSStefano Zampini PetscSubcomm subcomm; 3361e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 336228143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 336328143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 336428143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 336528143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 336628143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 3367e7931f94SStefano Zampini PetscErrorCode ierr; 3368e7931f94SStefano Zampini 3369e7931f94SStefano Zampini PetscFunctionBegin; 337028143c3dSStefano Zampini /* TODO: add missing checks */ 337128143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 337228143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 337328143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 337428143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 3375e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 337628143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 3377e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3378e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 3379e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 3380e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 3381e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 338228143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 338370cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 338470cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 338528143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 338670cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 338770cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 338870cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 338970cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 339070cf5478SStefano Zampini } 3391e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 3392e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 3393e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 3394e7931f94SStefano Zampini if (!is_sends) { 339528143c3dSStefano Zampini PetscBool pcontig = PETSC_TRUE; 339628143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 339728143c3dSStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,pcontig,&is_sends_internal);CHKERRQ(ierr); 3398c8587f34SStefano Zampini } else { 3399e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 3400e7931f94SStefano Zampini is_sends_internal = is_sends; 3401c8587f34SStefano Zampini } 3402e7931f94SStefano Zampini 3403e7931f94SStefano Zampini /* get pointer of MATIS data */ 3404e7931f94SStefano Zampini matis = (Mat_IS*)mat->data; 3405e7931f94SStefano Zampini 3406e7931f94SStefano Zampini /* get comm */ 3407a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 3408e7931f94SStefano Zampini 3409e7931f94SStefano Zampini /* compute number of sends */ 3410e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 3411e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 3412e7931f94SStefano Zampini 3413e7931f94SStefano Zampini /* compute number of receives */ 3414e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 3415785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 3416e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 3417e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3418e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 3419e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 3420e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 3421e7931f94SStefano Zampini 342228143c3dSStefano Zampini /* restrict comm if requested */ 342328143c3dSStefano Zampini subcomm = 0; 342428143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 342528143c3dSStefano Zampini if (restrict_comm) { 342628143c3dSStefano Zampini PetscMPIInt color,rank,subcommsize; 342728143c3dSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 342828143c3dSStefano Zampini color = 0; 342928143c3dSStefano Zampini if (n_sends && !n_recvs) color = 1; /* sending only processes will not partecipate in new comm */ 343028143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 343128143c3dSStefano Zampini subcommsize = commsize - subcommsize; 343228143c3dSStefano Zampini /* check if reuse has been requested */ 343328143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 343428143c3dSStefano Zampini if (*mat_n) { 343528143c3dSStefano Zampini PetscMPIInt subcommsize2; 343628143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 343728143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 343828143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 343928143c3dSStefano Zampini } else { 344028143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 344128143c3dSStefano Zampini } 344228143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 344328143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 344428143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 344528143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 344628143c3dSStefano Zampini comm_n = subcomm->comm; 344728143c3dSStefano Zampini } 344828143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 344928143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 345028143c3dSStefano Zampini } else { 345128143c3dSStefano Zampini comm_n = comm; 345228143c3dSStefano Zampini } 345328143c3dSStefano Zampini 3454e7931f94SStefano Zampini /* prepare send/receive buffers */ 3455785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 3456e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 3457785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 3458e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 345928143c3dSStefano Zampini if (nis) { 3460854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 346128143c3dSStefano Zampini } 3462e7931f94SStefano Zampini 346328143c3dSStefano Zampini /* Get data from local matrices */ 3464e7931f94SStefano Zampini if (!isdense) { 3465a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 3466e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 3467e7931f94SStefano Zampini /* 3468e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 3469e7931f94SStefano Zampini send_buffer_idxs should contain: 3470e7931f94SStefano Zampini - MatType_PRIVATE type 3471e7931f94SStefano Zampini - PetscInt size_of_l2gmap 3472e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 3473e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 3474e7931f94SStefano Zampini */ 3475e7931f94SStefano Zampini } else { 3476e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 3477e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(matis->mapping,&i);CHKERRQ(ierr); 3478854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 3479e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 3480e7931f94SStefano Zampini send_buffer_idxs[1] = i; 3481e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(matis->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 3482e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 3483e7931f94SStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(matis->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 3484e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 3485e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 3486e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 3487e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 3488c8587f34SStefano Zampini } 3489c8587f34SStefano Zampini } 3490e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 349128143c3dSStefano Zampini /* additional is (if any) */ 349228143c3dSStefano Zampini if (nis) { 349328143c3dSStefano Zampini PetscMPIInt psum; 349428143c3dSStefano Zampini PetscInt j; 349528143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 349628143c3dSStefano Zampini PetscInt plen; 349728143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 349828143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 349928143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 350028143c3dSStefano Zampini } 3501854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 350228143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 350328143c3dSStefano Zampini PetscInt plen; 350428143c3dSStefano Zampini const PetscInt *is_array_idxs; 350528143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 350628143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 350728143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 350828143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 350928143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 351028143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 351128143c3dSStefano Zampini } 351228143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 351328143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 351428143c3dSStefano Zampini } 351528143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 351628143c3dSStefano Zampini } 351728143c3dSStefano Zampini 3518e7931f94SStefano Zampini buf_size_idxs = 0; 3519e7931f94SStefano Zampini buf_size_vals = 0; 352028143c3dSStefano Zampini buf_size_idxs_is = 0; 3521e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3522e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 3523e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 352428143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 3525e7931f94SStefano Zampini } 3526785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 3527785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 352895ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 3529e7931f94SStefano Zampini 3530e7931f94SStefano Zampini /* get new tags for clean communications */ 3531e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 3532e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 353328143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 3534e7931f94SStefano Zampini 3535e7931f94SStefano Zampini /* allocate for requests */ 3536785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 3537785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 353895ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 3539785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 3540785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 354195ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 3542e7931f94SStefano Zampini 3543e7931f94SStefano Zampini /* communications */ 3544e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 3545e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 354628143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 3547e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3548e7931f94SStefano Zampini source_dest = onodes[i]; 3549e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 3550e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 3551e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3552e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 355328143c3dSStefano Zampini if (nis) { 355428143c3dSStefano 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); 355528143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 355628143c3dSStefano Zampini } 3557e7931f94SStefano Zampini } 3558e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 3559e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 3560e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 3561e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 356228143c3dSStefano Zampini if (nis) { 356328143c3dSStefano 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); 356428143c3dSStefano Zampini } 3565e7931f94SStefano Zampini } 3566e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3567e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 3568e7931f94SStefano Zampini 3569e7931f94SStefano Zampini /* assemble new l2g map */ 3570e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3571e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 35729d30be91SStefano Zampini new_local_rows = 0; 3573e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 35749d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 3575e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3576e7931f94SStefano Zampini } 35779d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 3578e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 35799d30be91SStefano Zampini new_local_rows = 0; 3580e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 35819d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 35829d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 3583e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3584e7931f94SStefano Zampini } 35859d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 35869d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 3587e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 3588e7931f94SStefano Zampini 3589e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 3590e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 3591e7931f94SStefano 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) */ 3592e7931f94SStefano Zampini if (n_recvs) { 359328143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 3594e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 3595e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3596e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 3597e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 3598e7931f94SStefano Zampini break; 3599e7931f94SStefano Zampini } 3600e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3601e7931f94SStefano Zampini } 3602e7931f94SStefano Zampini switch (new_local_type_private) { 360328143c3dSStefano Zampini case MATDENSE_PRIVATE: 360428143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 3605e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 3606e7931f94SStefano Zampini bs = 1; 360728143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 360828143c3dSStefano Zampini new_local_type = MATSEQDENSE; 360928143c3dSStefano Zampini bs = 1; 361028143c3dSStefano Zampini } 3611e7931f94SStefano Zampini break; 3612e7931f94SStefano Zampini case MATAIJ_PRIVATE: 3613e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 3614e7931f94SStefano Zampini bs = 1; 3615e7931f94SStefano Zampini break; 3616e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 3617e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 3618e7931f94SStefano Zampini break; 3619e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 3620e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 3621e7931f94SStefano Zampini break; 3622e7931f94SStefano Zampini default: 36239d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 3624e7931f94SStefano Zampini break; 3625e7931f94SStefano Zampini } 362628143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 362728143c3dSStefano Zampini new_local_type = MATSEQDENSE; 362828143c3dSStefano Zampini bs = 1; 3629e7931f94SStefano Zampini } 3630e7931f94SStefano Zampini 363170cf5478SStefano Zampini /* create MATIS object if needed */ 363270cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 3633e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 363428143c3dSStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,mat_n);CHKERRQ(ierr); 363570cf5478SStefano Zampini } else { 363670cf5478SStefano Zampini /* it also destroys the local matrices */ 363770cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 363870cf5478SStefano Zampini } 363970cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 3640e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 36419d30be91SStefano Zampini 36429d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 36439d30be91SStefano Zampini 36449d30be91SStefano Zampini /* Global to local map of received indices */ 36459d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 36469d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 36479d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 36489d30be91SStefano Zampini 36499d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 36509d30be91SStefano Zampini buf_size_idxs = 0; 36519d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 36529d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 36539d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 36549d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 36559d30be91SStefano Zampini } 36569d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 36579d30be91SStefano Zampini 36589d30be91SStefano Zampini /* set preallocation */ 36599d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 36609d30be91SStefano Zampini if (!newisdense) { 36619d30be91SStefano Zampini PetscInt *new_local_nnz=0; 36629d30be91SStefano Zampini 36639d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 36649d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 36659d30be91SStefano Zampini if (n_recvs) { 36669d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 36679d30be91SStefano Zampini } 36689d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 36699d30be91SStefano Zampini PetscInt j; 36709d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 36719d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 36729d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 36739d30be91SStefano Zampini } 36749d30be91SStefano Zampini } else { 36759d30be91SStefano Zampini /* TODO */ 36769d30be91SStefano Zampini } 36779d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 36789d30be91SStefano Zampini } 36799d30be91SStefano Zampini if (new_local_nnz) { 36809d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 36819d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 36829d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 36839d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 36849d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 36859d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 36869d30be91SStefano Zampini } else { 36879d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 36889d30be91SStefano Zampini } 36899d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 36909d30be91SStefano Zampini } else { 36919d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 36929d30be91SStefano Zampini } 3693e7931f94SStefano Zampini 3694e7931f94SStefano Zampini /* set values */ 3695e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 36969d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 3697e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3698e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 3699e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 37009d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 3701e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 3702e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 3703e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 370428143c3dSStefano Zampini } else { 370528143c3dSStefano Zampini /* TODO */ 3706e7931f94SStefano Zampini } 3707e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3708e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 3709e7931f94SStefano Zampini } 3710e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3711e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 371270cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 371370cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 37149d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 37159d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 3716e7931f94SStefano Zampini 3717dfd14d43SStefano Zampini #if 0 371828143c3dSStefano Zampini if (!restrict_comm) { /* check */ 3719e7931f94SStefano Zampini Vec lvec,rvec; 3720e7931f94SStefano Zampini PetscReal infty_error; 3721e7931f94SStefano Zampini 37222a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 3723e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 3724e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 3725e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 372670cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 3727e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 3728e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 3729e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 3730e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 3731e7931f94SStefano Zampini } 373228143c3dSStefano Zampini #endif 3733e7931f94SStefano Zampini 373428143c3dSStefano Zampini /* assemble new additional is (if any) */ 373528143c3dSStefano Zampini if (nis) { 373628143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 373728143c3dSStefano Zampini 373828143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3739854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 374028143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 374128143c3dSStefano Zampini psum = 0; 374228143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 374328143c3dSStefano Zampini for (j=0;j<nis;j++) { 374428143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 374528143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 374628143c3dSStefano Zampini psum += plen; 374728143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 374828143c3dSStefano Zampini } 374928143c3dSStefano Zampini } 3750854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 3751854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 375228143c3dSStefano Zampini for (i=1;i<nis;i++) { 375328143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 375428143c3dSStefano Zampini } 375528143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 375628143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 375728143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 375828143c3dSStefano Zampini for (j=0;j<nis;j++) { 375928143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 376028143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 376128143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 376228143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 376328143c3dSStefano Zampini } 376428143c3dSStefano Zampini } 376528143c3dSStefano Zampini for (i=0;i<nis;i++) { 376628143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 376728143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 376828143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 376928143c3dSStefano Zampini } 377028143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 377128143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 377228143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 377328143c3dSStefano Zampini } 3774e7931f94SStefano Zampini /* free workspace */ 377528143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 3776e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3777e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 3778e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3779e7931f94SStefano Zampini if (isdense) { 3780e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3781e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 3782e7931f94SStefano Zampini } else { 3783e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 3784e7931f94SStefano Zampini } 378528143c3dSStefano Zampini if (nis) { 378628143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 378728143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 378828143c3dSStefano Zampini } 3789e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 3790e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 379128143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 3792e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 3793e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 379428143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 3795e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 3796e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 3797e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 3798e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 3799e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 380028143c3dSStefano Zampini if (nis) { 380128143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 380228143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 380328143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 380428143c3dSStefano Zampini } 380528143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 380628143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 380728143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 380828143c3dSStefano Zampini for (i=0;i<nis;i++) { 380928143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 381028143c3dSStefano Zampini } 381128143c3dSStefano Zampini } 3812e7931f94SStefano Zampini PetscFunctionReturn(0); 3813e7931f94SStefano Zampini } 3814a57a6d2fSStefano Zampini 381512edc857SStefano Zampini /* temporary hack into ksp private data structure */ 381612edc857SStefano Zampini #include <petsc-private/kspimpl.h> 381712edc857SStefano Zampini 3818c8587f34SStefano Zampini #undef __FUNCT__ 3819c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 3820c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 3821c8587f34SStefano Zampini { 3822c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3823c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 382420a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 38259881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 382620a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 38276e683305SStefano Zampini IS coarse_is,*isarray; 38286e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 38296e683305SStefano Zampini PetscInt nis,nisdofs,nisneu; 3830f9eb5b7dSStefano Zampini PC pc_temp; 3831c8587f34SStefano Zampini PCType coarse_pc_type; 3832c8587f34SStefano Zampini KSPType coarse_ksp_type; 3833f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 38344f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 38356e683305SStefano Zampini Mat t_coarse_mat_is; 38366e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 38376e683305SStefano Zampini PetscMPIInt all_procs; 383874e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 383968457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 384022bc73bbSStefano Zampini PetscScalar *array; 38419881197aSStefano Zampini PetscErrorCode ierr; 3842fdc09c96SStefano Zampini 3843c8587f34SStefano Zampini PetscFunctionBegin; 3844c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 384568457ee5SStefano 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 */ 384668457ee5SStefano Zampini compute_vecs = PETSC_TRUE; 3847fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 3848fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 3849f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 3850f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 3851f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 3852fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 3853fa7f1dd8SStefano Zampini if (ocoarse_size != pcbddc->coarse_size) { /* ...but with different size, so reset it and set reuse flag to false */ 3854727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3855fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 3856fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 3857fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 3858f4ddd8eeSStefano Zampini } 3859fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 3860fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 3861f4ddd8eeSStefano Zampini } 386270cf5478SStefano Zampini /* reset any subassembling information */ 386370cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 38646e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 38656e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 3866fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 3867f4ddd8eeSStefano Zampini } 3868c8587f34SStefano Zampini 38696e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 38702b510759SStefano Zampini im_active = !!(pcis->n); 38712b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 38726e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 38736e683305SStefano Zampini void_procs = all_procs-active_procs; 38746e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 387574e2c79eSStefano Zampini redist = PETSC_FALSE; 387622bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 38776e683305SStefano Zampini csin_ml = PETSC_TRUE; 38786e683305SStefano Zampini ncoarse_ml = void_procs; 38796e683305SStefano Zampini csin_ds = PETSC_TRUE; 38806e683305SStefano Zampini ncoarse_ds = void_procs; 38816e683305SStefano Zampini } else { 38826e683305SStefano Zampini csin_ml = PETSC_FALSE; 38836e683305SStefano Zampini ncoarse_ml = all_procs; 38846e683305SStefano Zampini if (void_procs) { 38856e683305SStefano Zampini csin_ds = PETSC_TRUE; 38866e683305SStefano Zampini ncoarse_ds = void_procs; 38876e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 38886e683305SStefano Zampini } else { 388974e2c79eSStefano Zampini if (pcbddc->redistribute_coarse && pcbddc->redistribute_coarse < all_procs) { 389074e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 389174e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 389274e2c79eSStefano Zampini redist = PETSC_TRUE; 389374e2c79eSStefano Zampini } else { 38946e683305SStefano Zampini csin_ds = PETSC_FALSE; 38956e683305SStefano Zampini ncoarse_ds = all_procs; 38966e683305SStefano Zampini } 38976e683305SStefano Zampini } 389874e2c79eSStefano Zampini } 38996e683305SStefano Zampini 39006e683305SStefano Zampini /* 39016e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 39026e683305SStefano Zampini - we have not exceeded the number of levels requested 39036e683305SStefano Zampini - we can actually subassemble the active processes 39046e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 39056e683305SStefano Zampini */ 39066e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 39076e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 39086e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 39096e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 39106e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 3911f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 39122b510759SStefano Zampini } else { 3913f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 3914c8587f34SStefano Zampini } 3915c8587f34SStefano Zampini } 39166e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 39176e683305SStefano Zampini if (multilevel_allowed) { 39186e683305SStefano Zampini ncoarse = ncoarse_ml; 39196e683305SStefano Zampini csin = csin_ml; 39206e683305SStefano Zampini } else { 39216e683305SStefano Zampini ncoarse = ncoarse_ds; 39226e683305SStefano Zampini csin = csin_ds; 39236e683305SStefano Zampini } 3924e7931f94SStefano Zampini 3925abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 3926abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 3927abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 3928abbbba34SStefano Zampini 3929abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 393022bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 393122bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 393222bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 393322bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 3934b9b85e73SStefano Zampini #if 0 3935b9b85e73SStefano Zampini { 3936b9b85e73SStefano Zampini PetscViewer viewer; 3937b9b85e73SStefano Zampini char filename[256]; 3938b9b85e73SStefano Zampini sprintf(filename,"local_coarse_mat%d.m",PetscGlobalRank); 3939b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 3940b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 3941b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 3942b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3943b9b85e73SStefano Zampini } 3944b9b85e73SStefano Zampini #endif 39456e683305SStefano 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); 39466e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 39476e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 39486e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3949abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 3950abbbba34SStefano Zampini 39516e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 39526e683305SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal) ) { /* protects from unneded computations */ 39536e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 39546e683305SStefano Zampini const PetscInt *idxs; 39556e683305SStefano Zampini ISLocalToGlobalMapping tmap; 39566e683305SStefano Zampini 39576e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 39580be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 39596e683305SStefano Zampini /* allocate space for temporary storage */ 3960854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 3961854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 39626e683305SStefano Zampini /* allocate for IS array */ 39636e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 39646e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 39656e683305SStefano Zampini nis = nisdofs + nisneu; 3966854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 39676e683305SStefano Zampini /* dofs splitting */ 39686e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 39696e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 39706e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 39716e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 39726e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 39736e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 39746e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 39756e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->ISForDofsLocal[i]),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 39766e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 39776e683305SStefano Zampini } 39786e683305SStefano Zampini /* neumann boundaries */ 39796e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 39806e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 39816e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 39826e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 39836e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 39846e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 39856e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 39866e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->NeumannBoundariesLocal),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 39876e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 39886e683305SStefano Zampini } 39896e683305SStefano Zampini /* free memory */ 39906e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 39916e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 39926e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 39936e683305SStefano Zampini } else { 39946e683305SStefano Zampini nis = 0; 39956e683305SStefano Zampini nisdofs = 0; 39966e683305SStefano Zampini nisneu = 0; 39976e683305SStefano Zampini isarray = NULL; 39986e683305SStefano Zampini } 39996e683305SStefano Zampini /* destroy no longer needed map */ 40006e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 40016e683305SStefano Zampini 40026e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 40036e683305SStefano Zampini coarse_mat_is = NULL; 40046e683305SStefano Zampini if (csin) { 40056e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 400674e2c79eSStefano Zampini if (redist) { 400774e2c79eSStefano Zampini PetscMPIInt rank; 400874e2c79eSStefano Zampini PetscInt spc,n_spc_p1,dest[1]; 400974e2c79eSStefano Zampini 401074e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 401174e2c79eSStefano Zampini spc = all_procs/pcbddc->redistribute_coarse; 401274e2c79eSStefano Zampini n_spc_p1 = all_procs%pcbddc->redistribute_coarse; 401374e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 401474e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 401574e2c79eSStefano Zampini } else { 401674e2c79eSStefano Zampini dest[0] = rank/(spc+1); 401774e2c79eSStefano Zampini } 401874e2c79eSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),1,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 401974e2c79eSStefano Zampini } else { 40206e683305SStefano Zampini PetscInt j,tissize,*nisindices; 40216e683305SStefano Zampini PetscInt *coarse_candidates; 40226e683305SStefano Zampini const PetscInt* tisindices; 40236e683305SStefano Zampini /* get coarse candidates' ranks in pc communicator */ 4024854ce69bSBarry Smith ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 40256e683305SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 40266e683305SStefano Zampini for (i=0,j=0;i<all_procs;i++) { 40276e683305SStefano Zampini if (!coarse_candidates[i]) { 40286e683305SStefano Zampini coarse_candidates[j]=i; 40296e683305SStefano Zampini j++; 40306e683305SStefano Zampini } 40316e683305SStefano Zampini } 40326e683305SStefano Zampini if (j < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",j,ncoarse); 40336e683305SStefano Zampini /* get a suitable subassembling pattern */ 40346e683305SStefano Zampini if (csin_type_simple) { 40356e683305SStefano Zampini PetscMPIInt rank; 40366e683305SStefano Zampini PetscInt issize,isidx; 40376e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 40386e683305SStefano Zampini if (im_active) { 40396e683305SStefano Zampini issize = 1; 40406e683305SStefano Zampini isidx = (PetscInt)rank; 40416e683305SStefano Zampini } else { 40426e683305SStefano Zampini issize = 0; 40436e683305SStefano Zampini isidx = -1; 40446e683305SStefano Zampini } 40456e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 40466e683305SStefano Zampini } else { 40476e683305SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,PETSC_TRUE,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 40486e683305SStefano Zampini } 40496e683305SStefano Zampini if (pcbddc->dbg_flag) { 40506e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 40516e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 40526e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 40536e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 40546e683305SStefano Zampini for (i=0;i<j;i++) { 40556e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 40566e683305SStefano Zampini } 40576e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 40586e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 40596e683305SStefano Zampini } 40606e683305SStefano Zampini /* shift the pattern on coarse candidates */ 40616e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 40626e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 4063854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 40646e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 40656e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 40666e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 40676e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 40686e683305SStefano Zampini } 406974e2c79eSStefano Zampini } 40706e683305SStefano Zampini if (pcbddc->dbg_flag) { 40716e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 40726e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 40736e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 40746e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 40756e683305SStefano Zampini } 40766e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 40776e683305SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 40786e683305SStefano Zampini } else { 40796e683305SStefano Zampini if (pcbddc->dbg_flag) { 40806e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 40816e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 40826e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 40836e683305SStefano Zampini } 40846e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 40856e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 40866e683305SStefano Zampini } 40876e683305SStefano Zampini 40886e683305SStefano Zampini /* create local to global scatters for coarse problem */ 408968457ee5SStefano Zampini if (compute_vecs) { 40906e683305SStefano Zampini PetscInt lrows; 40916e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 40926e683305SStefano Zampini if (coarse_mat_is) { 40936e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 40946e683305SStefano Zampini } else { 40956e683305SStefano Zampini lrows = 0; 40966e683305SStefano Zampini } 40976e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 40986e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 40996e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 41006e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 41016e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 41026e683305SStefano Zampini } 41036e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 41046e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 4105c8587f34SStefano Zampini 4106f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 4107f9eb5b7dSStefano Zampini if (multilevel_allowed) { 4108f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 4109f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 4110f9eb5b7dSStefano Zampini } else { 4111f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 4112f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 4113c8587f34SStefano Zampini } 4114c8587f34SStefano Zampini 41156e683305SStefano Zampini /* print some info if requested */ 41166e683305SStefano Zampini if (pcbddc->dbg_flag) { 41176e683305SStefano Zampini if (!multilevel_allowed) { 41186e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 41196e683305SStefano Zampini if (multilevel_requested) { 41206e683305SStefano 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); 41216e683305SStefano Zampini } else if (pcbddc->max_levels) { 41226e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 41236e683305SStefano Zampini } 41246e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 41256e683305SStefano Zampini } 41266e683305SStefano Zampini } 41276e683305SStefano Zampini 4128f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 41296e683305SStefano Zampini if (coarse_mat_is) { 41306e683305SStefano Zampini MatReuse coarse_mat_reuse; 41316a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 41326e683305SStefano Zampini if (pcbddc->dbg_flag) { 41336e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 41346e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 41356e683305SStefano Zampini } 4136f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 4137312be037SStefano Zampini char prefix[256],str_level[16]; 4138e604994aSStefano Zampini size_t len; 41396e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 4140c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 4141f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 41425f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 4143c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 41446e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 4145c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 4146c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4147e604994aSStefano Zampini /* prefix */ 4148e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 4149e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4150e604994aSStefano Zampini if (!pcbddc->current_level) { 4151e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4152e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 4153c8587f34SStefano Zampini } else { 4154e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4155312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4156312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 415734d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4158312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4159e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 4160e604994aSStefano Zampini } 4161e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 4162f9eb5b7dSStefano Zampini /* allow user customization */ 4163f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 41647e0def11SStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4165312be037SStefano Zampini } 4166f9eb5b7dSStefano Zampini 4167f9eb5b7dSStefano Zampini /* get some info after set from options */ 4168f9eb5b7dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 4169f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 4170f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 41714f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 41726e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 4173f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4174f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 4175f9eb5b7dSStefano Zampini } 41764f3a063dSStefano Zampini if (isredundant) { 41774f3a063dSStefano Zampini KSP inner_ksp; 41784f3a063dSStefano Zampini PC inner_pc; 41794f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 41804f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 41814f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 41824f3a063dSStefano Zampini } 4183f9eb5b7dSStefano Zampini 41846e683305SStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 4185f9eb5b7dSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 4186f9eb5b7dSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 4187f9eb5b7dSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 41886e683305SStefano Zampini if (nisdofs) { 41896e683305SStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 41906e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 41916e683305SStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 41921035eff8SStefano Zampini } 41931035eff8SStefano Zampini } 41946e683305SStefano Zampini if (nisneu) { 41956e683305SStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 41966e683305SStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 41971035eff8SStefano Zampini } 4198fdc09c96SStefano Zampini 4199f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 4200fa7f1dd8SStefano Zampini if (coarse_reuse) { 420181d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 4202fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 42036e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 4204fa7f1dd8SStefano Zampini } else { 42056e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 4206fa7f1dd8SStefano Zampini } 4207c8587f34SStefano Zampini if (isbddc || isnn) { 420822bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 420970cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 421028143c3dSStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,PETSC_TRUE,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 421122b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 42126e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 42136e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 42146e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 42156e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 421622b6e8a2SStefano Zampini } 421770cf5478SStefano Zampini } 42186e683305SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 421970cf5478SStefano Zampini } else { 422022bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 422122bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 422222bc73bbSStefano Zampini } 422322bc73bbSStefano Zampini } else { 42242e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 4225c8587f34SStefano Zampini } 4226c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 4227c8587f34SStefano Zampini 4228c8587f34SStefano Zampini /* propagate symmetry info to coarse matrix */ 4229b9d89cd5SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pcbddc->issym);CHKERRQ(ierr); 42305a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 4231c8587f34SStefano Zampini 42326e683305SStefano Zampini /* set operators */ 42335f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 42346e683305SStefano Zampini if (pcbddc->dbg_flag) { 42356e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 42366e683305SStefano Zampini } 42376e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 42386e683305SStefano Zampini coarse_mat = 0; 42396e683305SStefano Zampini } 42406e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 4241b9b85e73SStefano Zampini #if 0 4242b9b85e73SStefano Zampini { 4243b9b85e73SStefano Zampini PetscViewer viewer; 4244b9b85e73SStefano Zampini char filename[256]; 4245b9b85e73SStefano Zampini sprintf(filename,"coarse_mat.m"); 4246b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,filename,&viewer);CHKERRQ(ierr); 4247b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4248b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 4249b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4250b9b85e73SStefano Zampini } 4251b9b85e73SStefano Zampini #endif 4252c8587f34SStefano Zampini 4253c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 4254c8587f34SStefano Zampini if (pcbddc->NullSpace) { 4255c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 425698a51de6SStefano Zampini } 425798a51de6SStefano Zampini 425898a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 425998a51de6SStefano Zampini Vec crhs,csol; 426098a51de6SStefano Zampini PetscBool ispreonly; 426198a51de6SStefano Zampini if (CoarseNullSpace) { 4262c8587f34SStefano Zampini if (isbddc) { 4263c8587f34SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 4264c8587f34SStefano Zampini } else { 4265c8587f34SStefano Zampini ierr = KSPSetNullSpace(pcbddc->coarse_ksp,CoarseNullSpace);CHKERRQ(ierr); 4266c8587f34SStefano Zampini } 4267c8587f34SStefano Zampini } 4268f9eb5b7dSStefano Zampini /* setup coarse ksp */ 4269f9eb5b7dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 4270f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 4271f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 42726e683305SStefano Zampini /* hack */ 4273f347579bSStefano Zampini if (!csol) { 42742a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 4275f9eb5b7dSStefano Zampini } 4276f347579bSStefano Zampini if (!crhs) { 42772a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 4278f347579bSStefano Zampini } 4279cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 4280cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 42816e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 4282c8587f34SStefano Zampini KSP check_ksp; 42832b510759SStefano Zampini KSPType check_ksp_type; 4284c8587f34SStefano Zampini PC check_pc; 42856e683305SStefano Zampini Vec check_vec,coarse_vec; 42866a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 42872b510759SStefano Zampini PetscInt its; 42886e683305SStefano Zampini PetscBool compute_eigs; 42896e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 42906e683305SStefano Zampini PetscInt neigs; 42918e185a42SStefano Zampini const char *prefix; 4292c8587f34SStefano Zampini 42932b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 42946e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 429523ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 4296f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 42972b510759SStefano Zampini if (ispreonly) { 42982b510759SStefano Zampini check_ksp_type = KSPPREONLY; 42996e683305SStefano Zampini compute_eigs = PETSC_FALSE; 43002b510759SStefano Zampini } else { 4301cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 43026e683305SStefano Zampini compute_eigs = PETSC_TRUE; 4303c8587f34SStefano Zampini } 4304c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 43056e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 43066e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 43076e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 4308a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 4309a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 4310a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 4311a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 4312c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 4313c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 4314c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 4315c8587f34SStefano Zampini /* create random vec */ 43166e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 43176e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 4318c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 4319c8587f34SStefano Zampini if (CoarseNullSpace) { 4320c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 4321c8587f34SStefano Zampini } 43226e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 4323c8587f34SStefano Zampini /* solve coarse problem */ 43246e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 4325c8587f34SStefano Zampini if (CoarseNullSpace) { 43266e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 4327c8587f34SStefano Zampini } 4328cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 43296e683305SStefano Zampini if (compute_eigs) { 4330854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 4331854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 43326e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 43336e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 43346e683305SStefano Zampini lambda_min = eigs_r[0]; 43356e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 43366e683305SStefano Zampini if (lambda_max>lambda_min) { 4337cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 4338cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 4339cbcc2c2aSStefano Zampini } 4340c8587f34SStefano Zampini } 4341c8587f34SStefano Zampini } 4342cbcc2c2aSStefano Zampini 4343c8587f34SStefano Zampini /* check coarse problem residual error */ 43446e683305SStefano Zampini if (pcbddc->dbg_flag) { 43456e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 43466e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 43476e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 4348c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 43496e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 43506e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 4351c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 43526e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (%d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 43536e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 43546e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 43556e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 43566e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 43576e683305SStefano Zampini if (compute_eigs) { 43586e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 4359deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 4360c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 43616e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 43626e683305SStefano 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); 43636e683305SStefano Zampini for (i=0;i<neigs;i++) { 43646e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 4365c8587f34SStefano Zampini } 43666e683305SStefano Zampini } 43676e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 43686e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 43696e683305SStefano Zampini } 4370c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 43716e683305SStefano Zampini if (compute_eigs) { 43726e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 43736e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 4374c8587f34SStefano Zampini } 43756e683305SStefano Zampini } 43766e683305SStefano Zampini } 4377cbcc2c2aSStefano Zampini /* print additional info */ 4378cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 43796e683305SStefano Zampini /* waits until all processes reaches this point */ 43806e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 4381cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 4382cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4383cbcc2c2aSStefano Zampini } 4384cbcc2c2aSStefano Zampini 43852b510759SStefano Zampini /* free memory */ 4386c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 4387fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 4388c8587f34SStefano Zampini PetscFunctionReturn(0); 4389c8587f34SStefano Zampini } 4390674ae819SStefano Zampini 4391f34684f1SStefano Zampini #undef __FUNCT__ 4392f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 4393f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 4394f34684f1SStefano Zampini { 4395f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4396f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 4397f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4398727cdba6SStefano Zampini PetscInt i,coarse_size; 4399727cdba6SStefano Zampini PetscInt *local_primal_indices; 4400f34684f1SStefano Zampini PetscErrorCode ierr; 4401f34684f1SStefano Zampini 4402f34684f1SStefano Zampini PetscFunctionBegin; 4403f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 440489c96988SStefano Zampini if (!pcbddc->primal_indices_local_idxs && pcbddc->local_primal_size) { 440589c96988SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Local primal indices have not been created"); 4406727cdba6SStefano Zampini } 4407727cdba6SStefano 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); 4408f34684f1SStefano Zampini 4409f34684f1SStefano Zampini /* check numbering */ 4410f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 4411f34684f1SStefano Zampini PetscScalar coarsesum,*array; 4412b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 4413f34684f1SStefano Zampini 4414f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4415f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4416f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 44170fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 4418f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 4419f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 4420727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 4421f34684f1SStefano Zampini } 4422f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 4423f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 4424f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4425f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4426f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4427f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4428f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4429f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4430f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 4431f34684f1SStefano Zampini if (array[i] == 1.0) { 4432b9b85e73SStefano Zampini set_error = PETSC_TRUE; 4433f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d: local index %d owned by a single process!\n",PetscGlobalRank,i);CHKERRQ(ierr); 4434f34684f1SStefano Zampini } 4435f34684f1SStefano Zampini } 4436b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4437f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4438f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 4439f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 4440f34684f1SStefano Zampini } 4441f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4442f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4443f34684f1SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4444f34684f1SStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4445f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 4446f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 4447b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 4448f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 4449f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4450f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 4451f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 4452727cdba6SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_primal_indices[%d]=%d (%d)\n",i,local_primal_indices[i],pcbddc->primal_indices_local_idxs[i]); 4453f34684f1SStefano Zampini } 4454f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4455f34684f1SStefano Zampini } 4456f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4457b9b85e73SStefano Zampini if (set_error_reduced) { 4458b9b85e73SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 4459b9b85e73SStefano Zampini } 4460f34684f1SStefano Zampini } 4461f34684f1SStefano Zampini /* get back data */ 4462f34684f1SStefano Zampini *coarse_size_n = coarse_size; 4463f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 4464674ae819SStefano Zampini PetscFunctionReturn(0); 4465674ae819SStefano Zampini } 4466674ae819SStefano Zampini 4467e456f2a8SStefano Zampini #undef __FUNCT__ 4468e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 4469a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 4470e456f2a8SStefano Zampini { 4471e456f2a8SStefano Zampini IS localis_t; 4472a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 4473e456f2a8SStefano Zampini PetscScalar *vals; 4474e456f2a8SStefano Zampini PetscErrorCode ierr; 4475e456f2a8SStefano Zampini 4476e456f2a8SStefano Zampini PetscFunctionBegin; 4477a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 4478e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 4479854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 4480e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 4481e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 4482a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 4483a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 44841035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 4485a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 44861035eff8SStefano Zampini } 4487a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 4488e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 4489e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4490a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 4491a7dc3881SStefano Zampini /* now compute set in local ordering */ 4492a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4493a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4494a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 4495a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 4496a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 4497ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 4498e456f2a8SStefano Zampini lsize++; 4499e456f2a8SStefano Zampini } 4500e456f2a8SStefano Zampini } 4501854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 4502a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 4503ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 4504e456f2a8SStefano Zampini idxs[lsize++] = i; 4505e456f2a8SStefano Zampini } 4506e456f2a8SStefano Zampini } 4507a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 4508a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 4509e456f2a8SStefano Zampini *localis = localis_t; 4510e456f2a8SStefano Zampini PetscFunctionReturn(0); 4511e456f2a8SStefano Zampini } 4512906d46d4SStefano Zampini 4513906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 4514906d46d4SStefano Zampini #undef __FUNCT__ 4515906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 4516906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 4517906d46d4SStefano Zampini { 4518906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4519906d46d4SStefano Zampini PetscErrorCode ierr; 4520906d46d4SStefano Zampini 4521906d46d4SStefano Zampini PetscFunctionBegin; 4522906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 4523906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 4524906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 4525906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 4526906d46d4SStefano Zampini PetscFunctionReturn(0); 4527906d46d4SStefano Zampini } 4528906d46d4SStefano Zampini 4529906d46d4SStefano Zampini #undef __FUNCT__ 4530906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 4531906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 4532906d46d4SStefano Zampini { 4533906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4534906d46d4SStefano Zampini PetscErrorCode ierr; 4535906d46d4SStefano Zampini 4536906d46d4SStefano Zampini PetscFunctionBegin; 4537906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 4538906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 4539906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 4540906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 4541906d46d4SStefano Zampini PetscFunctionReturn(0); 4542906d46d4SStefano Zampini } 4543b96c3477SStefano Zampini 4544b96c3477SStefano Zampini #undef __FUNCT__ 4545b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 454608122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 4547b96c3477SStefano Zampini { 4548b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 4549b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4550b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 4551b96c3477SStefano Zampini PetscBool free_used_adj; 4552b96c3477SStefano Zampini PetscErrorCode ierr; 4553b96c3477SStefano Zampini 4554b96c3477SStefano Zampini PetscFunctionBegin; 4555b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 4556b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 455708122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 4558b96c3477SStefano Zampini used_xadj = NULL; 4559b96c3477SStefano Zampini used_adjncy = NULL; 4560b96c3477SStefano Zampini } else { 456108122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 456208122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 456308122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 456408122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 4565b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 4566b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 4567b96c3477SStefano Zampini } else { 4568b96c3477SStefano Zampini Mat mat_adj; 4569b96c3477SStefano Zampini PetscBool flg_row=PETSC_TRUE; 4570b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 4571b96c3477SStefano Zampini PetscInt nvtxs; 4572b96c3477SStefano Zampini 4573b96c3477SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 4574b96c3477SStefano Zampini ierr = MatGetRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4575b96c3477SStefano Zampini if (!flg_row) { 4576b96c3477SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called in %s\n",__FUNCT__); 4577b96c3477SStefano Zampini } 4578b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 4579b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 4580b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 4581b96c3477SStefano Zampini ierr = MatRestoreRowIJ(mat_adj,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4582b96c3477SStefano Zampini if (!flg_row) { 4583b96c3477SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called in %s\n",__FUNCT__); 4584b96c3477SStefano Zampini } 4585b96c3477SStefano Zampini ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 4586b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 4587b96c3477SStefano Zampini } 4588b96c3477SStefano Zampini } 458908122e43SStefano 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); 4590b96c3477SStefano Zampini 4591b96c3477SStefano Zampini /* free adjacency */ 4592b96c3477SStefano Zampini if (free_used_adj) { 4593b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 4594b96c3477SStefano Zampini } 4595b96c3477SStefano Zampini PetscFunctionReturn(0); 4596b96c3477SStefano Zampini } 4597b96c3477SStefano Zampini 4598b96c3477SStefano Zampini #undef __FUNCT__ 4599b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 460008122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 4601b96c3477SStefano Zampini { 4602b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 4603b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 4604b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4605b96c3477SStefano Zampini PCBDDCGraph graph; 4606b96c3477SStefano Zampini Mat S_j; 4607b96c3477SStefano Zampini PetscErrorCode ierr; 4608b96c3477SStefano Zampini 4609b96c3477SStefano Zampini PetscFunctionBegin; 4610b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 461108122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 4612b96c3477SStefano Zampini IS verticesIS; 4613b96c3477SStefano Zampini 4614b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 4615b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 4616b96c3477SStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap);CHKERRQ(ierr); 4617b96c3477SStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticesIS);CHKERRQ(ierr); 4618b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 4619b96c3477SStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 4620b96c3477SStefano Zampini /* 4621b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 4622b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 4623b96c3477SStefano Zampini } 4624b96c3477SStefano Zampini */ 4625b96c3477SStefano Zampini } else { 4626b96c3477SStefano Zampini graph = pcbddc->mat_graph; 4627b96c3477SStefano Zampini } 4628b96c3477SStefano Zampini 4629b96c3477SStefano Zampini /* Create Schur complement matrix */ 4630b96c3477SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 4631b96c3477SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 4632b96c3477SStefano Zampini 4633b96c3477SStefano Zampini /* sub_schurs init */ 463408122e43SStefano 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); 4635b96c3477SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 4636b96c3477SStefano Zampini /* free graph struct */ 463708122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 4638b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 4639b96c3477SStefano Zampini } 4640b96c3477SStefano Zampini PetscFunctionReturn(0); 4641b96c3477SStefano Zampini } 4642