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 8674ae819SStefano Zampini #undef __FUNCT__ 9c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 10c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 11c263805aSStefano Zampini { 12c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 13c263805aSStefano Zampini const PetscInt *idxs; 14c263805aSStefano Zampini PetscInt nz = 0; 15c263805aSStefano Zampini PetscErrorCode ierr; 16c263805aSStefano Zampini 17c263805aSStefano Zampini PetscFunctionBegin; 18c263805aSStefano Zampini if (!pcbddc->zerodiag) { 19c263805aSStefano Zampini PetscFunctionReturn(0); 20c263805aSStefano Zampini } else { 21c263805aSStefano Zampini ierr = ISGetLocalSize(pcbddc->zerodiag,&nz);CHKERRQ(ierr); 22c263805aSStefano Zampini if (!nz) PetscFunctionReturn(0); 23c263805aSStefano Zampini } 24c263805aSStefano Zampini ierr = ISGetIndices(pcbddc->zerodiag,&idxs);CHKERRQ(ierr); 25c263805aSStefano Zampini /* TODO: add error checking 26c263805aSStefano Zampini - avoid nested pop (or push) calls. 27c263805aSStefano Zampini - cannot push before pop. 28c263805aSStefano Zampini */ 29c263805aSStefano Zampini if (pop) { 30c263805aSStefano Zampini const PetscInt *cB0_cols; 31c263805aSStefano Zampini PetscInt cB0_ncol; 32c263805aSStefano Zampini const PetscScalar *cB0_vals; 33c263805aSStefano Zampini 34c263805aSStefano Zampini /* extract B_0 */ 35c263805aSStefano Zampini ierr = MatGetRow(pcbddc->local_mat,idxs[nz-1],&cB0_ncol,&cB0_cols,&cB0_vals);CHKERRQ(ierr); 36c263805aSStefano Zampini pcbddc->B0_ncol = cB0_ncol; 37c263805aSStefano Zampini ierr = PetscFree2(pcbddc->B0_cols,pcbddc->B0_vals);CHKERRQ(ierr); 38c263805aSStefano Zampini ierr = PetscMalloc2(cB0_ncol,&pcbddc->B0_cols,cB0_ncol,&pcbddc->B0_vals);CHKERRQ(ierr); 39c263805aSStefano Zampini ierr = PetscMemcpy(pcbddc->B0_cols,cB0_cols,cB0_ncol*sizeof(PetscInt));CHKERRQ(ierr); 40c263805aSStefano Zampini ierr = PetscMemcpy(pcbddc->B0_vals,cB0_vals,cB0_ncol*sizeof(PetscScalar));CHKERRQ(ierr); 41c263805aSStefano Zampini ierr = MatRestoreRow(pcbddc->local_mat,idxs[nz-1],&cB0_ncol,&cB0_cols,&cB0_vals);CHKERRQ(ierr); 42c263805aSStefano Zampini /* remove rows and cols from local problem */ 43c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 44c263805aSStefano Zampini ierr = MatZeroRowsColumns(pcbddc->local_mat,1,idxs+nz-1,1.,NULL,NULL);CHKERRQ(ierr); 45c263805aSStefano Zampini } else { /* push */ 46c263805aSStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,&idxs[nz-1],pcbddc->B0_ncol,pcbddc->B0_cols,pcbddc->B0_vals,INSERT_VALUES);CHKERRQ(ierr); 47c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 48c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 49c263805aSStefano Zampini } 50c263805aSStefano Zampini PetscFunctionReturn(0); 51c263805aSStefano Zampini } 52c263805aSStefano Zampini 53c263805aSStefano Zampini #undef __FUNCT__ 54b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 5508122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 56b1b3d7a2SStefano Zampini { 57b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5808122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5908122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 6008122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 6108122e43SStefano Zampini PetscScalar *work,lwork; 6208122e43SStefano Zampini PetscScalar *St,*S,*eigv; 6308122e43SStefano Zampini PetscScalar *Sarray,*Starray; 6408122e43SStefano Zampini PetscReal *eigs,thresh; 651b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 66f6f667cfSStefano Zampini PetscBool allocated_S_St; 6708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6808122e43SStefano Zampini PetscReal *rwork; 6908122e43SStefano Zampini #endif 70b1b3d7a2SStefano Zampini PetscErrorCode ierr; 71b1b3d7a2SStefano Zampini 72b1b3d7a2SStefano Zampini PetscFunctionBegin; 7308122e43SStefano Zampini if (!sub_schurs->use_mumps) { 7408122e43SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS"); 7508122e43SStefano Zampini } 7608122e43SStefano Zampini 77*06a4e24aSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) { 78*06a4e24aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adaptive selection not yet implemented for general matrix pencils (herm %d, posdef %d)\n",sub_schurs->is_hermitian,sub_schurs->is_posdef); 79*06a4e24aSStefano Zampini } 80*06a4e24aSStefano Zampini 81fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 82fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 83fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 84fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 85fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 86fd14bc51SStefano Zampini } 87fd14bc51SStefano Zampini 88e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 89e496cd5dSStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d cc %d (%d,%d).\n",PetscGlobalRank,sub_schurs->n_subs,sub_schurs->is_hermitian,sub_schurs->is_posdef); 90e496cd5dSStefano Zampini } 91e496cd5dSStefano Zampini 9208122e43SStefano Zampini /* max size of subsets */ 9308122e43SStefano Zampini mss = 0; 9408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 9508122e43SStefano Zampini PetscInt subset_size; 96862806e4SStefano Zampini 9708122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 9808122e43SStefano Zampini mss = PetscMax(mss,subset_size); 9908122e43SStefano Zampini } 10008122e43SStefano Zampini 10108122e43SStefano Zampini /* min/max and threshold */ 10208122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 103f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 10408122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 105f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 106f6f667cfSStefano Zampini if (nmin) { 107f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 108f6f667cfSStefano Zampini } 10908122e43SStefano Zampini 11008122e43SStefano Zampini /* allocate lapack workspace */ 11108122e43SStefano Zampini cum = cum2 = 0; 11208122e43SStefano Zampini maxneigs = 0; 11308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 11408122e43SStefano Zampini PetscInt n,subset_size; 115f6f667cfSStefano Zampini 11608122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 11708122e43SStefano Zampini n = PetscMin(subset_size,nmax); 1189162d606SStefano Zampini cum += subset_size; 1199162d606SStefano Zampini cum2 += subset_size*n; 12008122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 12108122e43SStefano Zampini } 12208122e43SStefano Zampini if (mss) { 1239ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 12408122e43SStefano Zampini PetscBLASInt B_itype = 1; 12508122e43SStefano Zampini PetscBLASInt B_N = mss; 1264c6709b3SStefano Zampini PetscReal zero = 0.0; 1274c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 12808122e43SStefano Zampini 12908122e43SStefano Zampini B_lwork = -1; 13008122e43SStefano Zampini S = NULL; 13108122e43SStefano Zampini St = NULL; 132a58a30b4SStefano Zampini eigs = NULL; 133a58a30b4SStefano Zampini eigv = NULL; 134a58a30b4SStefano Zampini B_iwork = NULL; 135a58a30b4SStefano Zampini B_ifail = NULL; 136d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 137d1710679SStefano Zampini rwork = NULL; 138d1710679SStefano Zampini #endif 1398bec7fa6SStefano Zampini thresh = 1.0; 14008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 14108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 14208122e43SStefano 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)); 14308122e43SStefano Zampini #else 14408122e43SStefano 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)); 14508122e43SStefano Zampini #endif 14608122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 14708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 14808122e43SStefano Zampini } else { 14908122e43SStefano Zampini /* TODO */ 15008122e43SStefano Zampini } 15108122e43SStefano Zampini } else { 15208122e43SStefano Zampini lwork = 0; 15308122e43SStefano Zampini } 15408122e43SStefano Zampini 15508122e43SStefano Zampini nv = 0; 156d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { /* complement set of active subsets, each entry is a vertex (boundary made by active subsets, vertices and dirichlet dofs) */ 157d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 15808122e43SStefano Zampini } 1594c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 160f6f667cfSStefano Zampini if (allocated_S_St) { 161f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 162f6f667cfSStefano Zampini } 163f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 16408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 16508122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 16608122e43SStefano Zampini #endif 1679162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 1689162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 1699162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 17008122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 1719162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 17208122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 17308122e43SStefano Zampini 17408122e43SStefano Zampini maxneigs = 0; 17508122e43SStefano Zampini cum = cum2 = cumarray = 0; 1769162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 1779162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 178d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 17908122e43SStefano Zampini const PetscInt *idxs; 18008122e43SStefano Zampini 181d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 18208122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 18308122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 18408122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 18508122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 1869162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 1879162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 18808122e43SStefano Zampini } 18908122e43SStefano Zampini cum2 = cum; 190d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 19108122e43SStefano Zampini } 19208122e43SStefano Zampini 19308122e43SStefano Zampini if (mss) { /* multilevel */ 19408122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 19508122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 19608122e43SStefano Zampini } 19708122e43SStefano Zampini 19808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 19908122e43SStefano Zampini 20008122e43SStefano Zampini const PetscInt *idxs; 201f6f667cfSStefano Zampini PetscReal infty = PETSC_MAX_REAL; 202862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 20308122e43SStefano Zampini PetscBLASInt B_N; 204aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 20508122e43SStefano Zampini 206862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 207f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 208f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 2099ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 210aff50787SStefano Zampini PetscInt j,k; 211aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 212aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 213aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 21408122e43SStefano Zampini } 21508122e43SStefano Zampini for (j=0;j<subset_size;j++) { 216aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 217aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 218aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 219aff50787SStefano Zampini } 22008122e43SStefano Zampini } 22108122e43SStefano Zampini } else { 22208122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 22308122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 22408122e43SStefano Zampini } 2258bec7fa6SStefano Zampini } else { 226f6f667cfSStefano Zampini S = Sarray + cumarray; 227f6f667cfSStefano Zampini St = Starray + cumarray; 2288bec7fa6SStefano Zampini } 22908122e43SStefano Zampini 230f6f667cfSStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 231aff50787SStefano Zampini /* see if we can save some work */ 232aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { 233aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 234aff50787SStefano Zampini } 235aff50787SStefano Zampini 236aff50787SStefano Zampini if (same_data) { /* there's no need of constraints here, deluxe scaling is enough */ 237aff50787SStefano Zampini B_neigs = 0; 238aff50787SStefano Zampini } else { 239aff50787SStefano Zampini /* Threshold: this is an heuristic for edges */ 240f6f667cfSStefano Zampini thresh = pcbddc->mat_graph->count[idxs[0]]*pcbddc->adaptive_threshold; 241f6f667cfSStefano Zampini 2429ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 24308122e43SStefano Zampini PetscBLASInt B_itype = 1; 244f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 2454c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 2469552c7c7SStefano Zampini PetscInt nmin_s; 24708122e43SStefano Zampini 248f6f667cfSStefano Zampini /* ask for eigenvalues larger than thresh */ 249fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2508bec7fa6SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %d/%d %d %d.\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]); 251fd14bc51SStefano Zampini } 25208122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 25308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 254f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 25508122e43SStefano Zampini #else 256f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 25708122e43SStefano Zampini #endif 25808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 25908122e43SStefano Zampini if (B_ierr) { 26008122e43SStefano Zampini if (B_ierr < 0 ) { 26108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 26208122e43SStefano Zampini } else if (B_ierr <= B_N) { 26308122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 26408122e43SStefano Zampini } else { 2659552c7c7SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: leading minor of order %d is not positive definite",(int)B_ierr-B_N-1); 26608122e43SStefano Zampini } 26708122e43SStefano Zampini } 26808122e43SStefano Zampini 26908122e43SStefano Zampini if (B_neigs > nmax) { 270fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 271fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 272fd14bc51SStefano Zampini } 273f6f667cfSStefano Zampini eigs_start = B_neigs -nmax; 27408122e43SStefano Zampini B_neigs = nmax; 27508122e43SStefano Zampini } 27608122e43SStefano Zampini 2779552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 2789552c7c7SStefano Zampini if (B_neigs < nmin_s) { 27908122e43SStefano Zampini PetscBLASInt B_neigs2; 28008122e43SStefano Zampini 281f6f667cfSStefano Zampini B_IU = B_N - B_neigs; 282f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 283fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 284fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, less than minimum required %d. Asking for %d to %d incl (fortran like)\n",B_neigs,nmin,B_IL,B_IU); 285fd14bc51SStefano Zampini } 2869ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 28708122e43SStefano Zampini PetscInt j; 28808122e43SStefano Zampini for (j=0;j<subset_size;j++) { 28908122e43SStefano Zampini ierr = PetscMemcpy(S+j*(subset_size+1),Sarray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 29008122e43SStefano Zampini } 29108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 29208122e43SStefano Zampini ierr = PetscMemcpy(St+j*(subset_size+1),Starray+cumarray+j*(subset_size+1),(subset_size-j)*sizeof(PetscScalar));CHKERRQ(ierr); 29308122e43SStefano Zampini } 29408122e43SStefano Zampini } else { 29508122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 29608122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 29708122e43SStefano Zampini } 29808122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 29908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 300f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*subset_size,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 30108122e43SStefano Zampini #else 302f6f667cfSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&thresh,&infty,&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*subset_size,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 30308122e43SStefano Zampini #endif 30408122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 30508122e43SStefano Zampini B_neigs += B_neigs2; 30608122e43SStefano Zampini } 30708122e43SStefano Zampini if (B_ierr) { 30808122e43SStefano Zampini if (B_ierr < 0 ) { 30908122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 31008122e43SStefano Zampini } else if (B_ierr <= B_N) { 31108122e43SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 31208122e43SStefano Zampini } else { 3139552c7c7SStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: leading minor of order %d is not positive definite",(int)B_ierr-B_N-1); 31408122e43SStefano Zampini } 31508122e43SStefano Zampini } 316fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 317ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 31808122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 31908122e43SStefano Zampini if (eigs[j] == 0.0) { 320ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 32108122e43SStefano Zampini } else { 322ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 323fd14bc51SStefano Zampini } 32408122e43SStefano Zampini } 32508122e43SStefano Zampini } 32608122e43SStefano Zampini } else { 32708122e43SStefano Zampini /* TODO */ 32808122e43SStefano Zampini } 329aff50787SStefano Zampini } 3308bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 3318bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 3329162d606SStefano Zampini if (B_neigs) { 3339162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum],eigv+eigs_start*subset_size,B_neigs*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 334fd14bc51SStefano Zampini 335fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 3369552c7c7SStefano Zampini PetscInt ii; 3379552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 338ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 3399552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 340ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 341ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 342ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 343ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 344ac47001eSStefano Zampini #else 345ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]);CHKERRQ(ierr); 346ac47001eSStefano Zampini #endif 3479552c7c7SStefano Zampini } 3489552c7c7SStefano Zampini } 349fd14bc51SStefano Zampini } 35008122e43SStefano Zampini #if 0 3519162d606SStefano Zampini for (j=0;j<B_neigs;j++) { 35208122e43SStefano Zampini PetscBLASInt Blas_N,Blas_one = 1.0; 35308122e43SStefano Zampini PetscScalar norm; 35408122e43SStefano Zampini ierr = PetscBLASIntCast(subset_size,&Blas_N);CHKERRQ(ierr); 3559162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size, 3569162d606SStefano Zampini &Blas_one,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 35708122e43SStefano Zampini if (pcbddc->adaptive_constraints_data[cum2] > 0.0) { 35808122e43SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 35908122e43SStefano Zampini } else { 36008122e43SStefano Zampini norm = -1.0/PetscSqrtReal(PetscRealPart(norm)); 36108122e43SStefano Zampini } 3629162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum]+j*subset_size,&Blas_one)); 363b1b3d7a2SStefano Zampini } 364b1b3d7a2SStefano Zampini #endif 3659162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 3669162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 3679162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 3689162d606SStefano Zampini cum++; 36908122e43SStefano Zampini } 37008122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 37108122e43SStefano Zampini /* shift for next computation */ 37208122e43SStefano Zampini cumarray += subset_size*subset_size; 37308122e43SStefano Zampini } 374fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 375fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 376fd14bc51SStefano Zampini } 37708122e43SStefano Zampini 37808122e43SStefano Zampini if (mss) { 37908122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 38008122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 381f6f667cfSStefano Zampini /* destroy matrices (junk) */ 382f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 383f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 38408122e43SStefano Zampini } 385f6f667cfSStefano Zampini if (allocated_S_St) { 386f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 387f6f667cfSStefano Zampini } 388f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 38908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 39008122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 39108122e43SStefano Zampini #endif 39208122e43SStefano Zampini if (pcbddc->dbg_flag) { 3931b968477SStefano Zampini PetscInt maxneigs_r; 39408122e43SStefano Zampini ierr = MPI_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3959b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 39608122e43SStefano Zampini } 39708122e43SStefano Zampini PetscFunctionReturn(0); 39808122e43SStefano Zampini } 399b1b3d7a2SStefano Zampini 400674ae819SStefano Zampini #undef __FUNCT__ 401c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 402c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 403c8587f34SStefano Zampini { 404c8587f34SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4058629588bSStefano Zampini PetscScalar *coarse_submat_vals; 406c8587f34SStefano Zampini PetscErrorCode ierr; 407c8587f34SStefano Zampini 408c8587f34SStefano Zampini PetscFunctionBegin; 409f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 4105e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 411c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 412c8587f34SStefano Zampini 413684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 4140fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 415684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 416c8587f34SStefano Zampini 417c8587f34SStefano Zampini /* Change global null space passed in by the user if change of basis has been requested */ 418b9b85e73SStefano Zampini if (pcbddc->NullSpace && pcbddc->ChangeOfBasisMatrix) { 419c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAdaptGlobal(pc);CHKERRQ(ierr); 420c8587f34SStefano Zampini } 421c8587f34SStefano Zampini 4228629588bSStefano Zampini /* 4238629588bSStefano Zampini Setup local correction and local part of coarse basis. 4248629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 4258629588bSStefano Zampini */ 42647f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 4278629588bSStefano Zampini 4288629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 4298629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 4308629588bSStefano Zampini 4318629588bSStefano Zampini /* free */ 4328629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 433c8587f34SStefano Zampini PetscFunctionReturn(0); 434c8587f34SStefano Zampini } 435c8587f34SStefano Zampini 436c8587f34SStefano Zampini #undef __FUNCT__ 437674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 438674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 439674ae819SStefano Zampini { 440674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 441674ae819SStefano Zampini PetscErrorCode ierr; 442674ae819SStefano Zampini 443674ae819SStefano Zampini PetscFunctionBegin; 444674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 445674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 446674ae819SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 447674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 448785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 449674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 450f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 451f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 452785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 45363602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 45463602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 455674ae819SStefano Zampini PetscFunctionReturn(0); 456674ae819SStefano Zampini } 457674ae819SStefano Zampini 458674ae819SStefano Zampini #undef __FUNCT__ 459674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 460674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 461674ae819SStefano Zampini { 462674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 463674ae819SStefano Zampini PetscErrorCode ierr; 464674ae819SStefano Zampini 465674ae819SStefano Zampini PetscFunctionBegin; 466b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 467674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 468674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 469674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 470b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 471674ae819SStefano Zampini PetscFunctionReturn(0); 472674ae819SStefano Zampini } 473674ae819SStefano Zampini 474674ae819SStefano Zampini #undef __FUNCT__ 475674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 476674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 477674ae819SStefano Zampini { 478674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 47906656605SStefano Zampini PetscScalar *array; 480674ae819SStefano Zampini PetscErrorCode ierr; 481674ae819SStefano Zampini 482674ae819SStefano Zampini PetscFunctionBegin; 483674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 48458da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 48506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 48606656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 48758da7f69SStefano Zampini } 488674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 489674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 49015aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 49115aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 492674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 493674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 494674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 49506656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 496674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 497674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 4988ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 499674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 500674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 501674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 502f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 503f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 504f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 505f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 506727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5070e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 508f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 50970cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 5106e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 511f5fd1fbfSStefano Zampini ierr = ISDestroy(&pcbddc->zerodiag);CHKERRQ(ierr); 51281d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 51381d14e9dSStefano Zampini ierr = PetscFree2(pcbddc->B0_cols,pcbddc->B0_vals);CHKERRQ(ierr); 514674ae819SStefano Zampini PetscFunctionReturn(0); 515674ae819SStefano Zampini } 516674ae819SStefano Zampini 517674ae819SStefano Zampini #undef __FUNCT__ 518f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 519f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 5206bfb1811SStefano Zampini { 5216bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5226bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 5236bfb1811SStefano Zampini VecType impVecType; 524e9189074SStefano Zampini PetscInt n_constraints,n_R,old_size; 5256bfb1811SStefano Zampini PetscErrorCode ierr; 5266bfb1811SStefano Zampini 5276bfb1811SStefano Zampini PetscFunctionBegin; 528f4ddd8eeSStefano Zampini if (!pcbddc->ConstraintMatrix) { 529f4ddd8eeSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 530f4ddd8eeSStefano Zampini } 531e7b262bdSStefano Zampini /* get sizes */ 532b371cd4fSStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->n_vertices; 533b371cd4fSStefano Zampini n_R = pcis->n-pcbddc->n_vertices; 5346bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 535e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 536e7b262bdSStefano Zampini /* R nodes */ 537e7b262bdSStefano Zampini old_size = -1; 538e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 539e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 540e7b262bdSStefano Zampini } 541e7b262bdSStefano Zampini if (n_R != old_size) { 542e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 543e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 5446bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 5456bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 5466bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 5476bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 548e7b262bdSStefano Zampini } 549e7b262bdSStefano Zampini /* local primal dofs */ 550e7b262bdSStefano Zampini old_size = -1; 551e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 552e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 553e7b262bdSStefano Zampini } 554e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 555e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 55683b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 557e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 5586bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 559e7b262bdSStefano Zampini } 560e7b262bdSStefano Zampini /* local explicit constraints */ 561e7b262bdSStefano Zampini old_size = -1; 562e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 563e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 564e7b262bdSStefano Zampini } 565e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 566e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 56783b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 56883b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 56983b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 57083b7ccabSStefano Zampini } 5716bfb1811SStefano Zampini PetscFunctionReturn(0); 5726bfb1811SStefano Zampini } 5736bfb1811SStefano Zampini 5746bfb1811SStefano Zampini #undef __FUNCT__ 57547f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 57647f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 57788ebb749SStefano Zampini { 57825084f0cSStefano Zampini PetscErrorCode ierr; 57925084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 58088ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 58188ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 582d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 58325084f0cSStefano Zampini /* submatrices of local problem */ 58480677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 58506656605SStefano Zampini /* submatrices of local coarse problem */ 58606656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 58725084f0cSStefano Zampini /* working matrices */ 58806656605SStefano Zampini Mat C_CR; 58925084f0cSStefano Zampini /* additional working stuff */ 59006656605SStefano Zampini PC pc_R; 59106656605SStefano Zampini Mat F; 59206656605SStefano Zampini PetscBool isLU,isCHOL,isILU; 59306656605SStefano Zampini 59425084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 59506656605SStefano Zampini PetscScalar *work; 59606656605SStefano Zampini PetscInt *idx_V_B; 59706656605SStefano Zampini PetscInt n,n_vertices,n_constraints; 59806656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 599b9d89cd5SStefano Zampini PetscBool unsymmetric_check; 60045a1bb75SStefano Zampini /* matrix type (vector type propagated downstream from vec1_C and local matrix type) */ 60188ebb749SStefano Zampini MatType impMatType; 60225084f0cSStefano Zampini /* some shortcuts to scalars */ 60306656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 60488ebb749SStefano Zampini 60588ebb749SStefano Zampini PetscFunctionBegin; 606b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 60788ebb749SStefano Zampini n_constraints = pcbddc->local_primal_size-n_vertices; 60888ebb749SStefano Zampini /* Set Non-overlapping dimensions */ 609b371cd4fSStefano Zampini n_B = pcis->n_B; 610b371cd4fSStefano Zampini n_D = pcis->n - n_B; 61188ebb749SStefano Zampini n_R = pcis->n - n_vertices; 61288ebb749SStefano Zampini 61388ebb749SStefano Zampini /* Set types for local objects needed by BDDC precondtioner */ 61488ebb749SStefano Zampini impMatType = MATSEQDENSE; 61588ebb749SStefano Zampini 61688ebb749SStefano Zampini /* vertices in boundary numbering */ 617785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 6180e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 61988ebb749SStefano Zampini if (i != n_vertices) { 62022d5777bSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %d != %d\n",n_vertices,i); 62188ebb749SStefano Zampini } 62288ebb749SStefano Zampini 62306656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 62406656605SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 62506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 62606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 62706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 62806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 62906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 63006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 63106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 63206656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 63306656605SStefano Zampini 63406656605SStefano Zampini unsymmetric_check = PETSC_FALSE; 63506656605SStefano Zampini /* allocate workspace */ 63606656605SStefano Zampini n = 0; 63706656605SStefano Zampini if (n_constraints) { 63806656605SStefano Zampini n += n_R*n_constraints; 63906656605SStefano Zampini } 64006656605SStefano Zampini if (n_vertices) { 64106656605SStefano Zampini n = PetscMax(2*n_R*n_vertices,n); 64280677318SStefano Zampini n = PetscMax((n_R+n_B)*n_vertices,n); 64306656605SStefano Zampini } 6443301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 64506656605SStefano Zampini n = PetscMax(2*n_R*pcbddc->local_primal_size,n); 64606656605SStefano Zampini unsymmetric_check = PETSC_TRUE; 64706656605SStefano Zampini } 64806656605SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 64906656605SStefano Zampini 65006656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 65106656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 65206656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 65306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 65406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 65506656605SStefano Zampini if (isLU || isILU || isCHOL) { 65606656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 657d62866d3SStefano Zampini } else if (sub_schurs->reuse_mumps) { 658d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 659d62866d3SStefano Zampini MatFactorType type; 660d62866d3SStefano Zampini 6616816873aSStefano Zampini F = reuse_mumps->F; 6626816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 663d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 66406656605SStefano Zampini } else { 66506656605SStefano Zampini F = NULL; 66606656605SStefano Zampini } 66706656605SStefano Zampini 66888ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 66988ebb749SStefano Zampini if (n_constraints) { 67006656605SStefano Zampini Mat M1,M2,M3; 67180677318SStefano Zampini Mat auxmat; 67206656605SStefano Zampini IS is_aux; 67380677318SStefano Zampini PetscScalar *array,*array2; 67406656605SStefano Zampini 675f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 67680677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 67788ebb749SStefano Zampini 67825084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 67925084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 6808ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 68180677318SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&auxmat);CHKERRQ(ierr); 68288ebb749SStefano Zampini 68380677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 68480677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 68506656605SStefano Zampini ierr = PetscMemzero(work,n_R*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 68688ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 68706656605SStefano Zampini const PetscScalar *row_cmat_values; 68806656605SStefano Zampini const PetscInt *row_cmat_indices; 68906656605SStefano Zampini PetscInt size_of_constraint,j; 69088ebb749SStefano Zampini 69106656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 69206656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 69306656605SStefano Zampini work[row_cmat_indices[j]+i*n_R] = -row_cmat_values[j]; 69406656605SStefano Zampini } 69506656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 69606656605SStefano Zampini } 69780677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 69806656605SStefano Zampini if (F) { 69906656605SStefano Zampini Mat B; 70006656605SStefano Zampini 70106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 70280677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 70306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 70406656605SStefano Zampini } else { 70580677318SStefano Zampini PetscScalar *marr; 70680677318SStefano Zampini 70780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 70806656605SStefano Zampini for (i=0;i<n_constraints;i++) { 70906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 71080677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*n_R);CHKERRQ(ierr); 71106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 71206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 71306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 71406656605SStefano Zampini } 71580677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 71606656605SStefano Zampini } 71780677318SStefano Zampini if (!pcbddc->switch_static) { 71880677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 71980677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 72080677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 72180677318SStefano Zampini for (i=0;i<n_constraints;i++) { 72280677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*n_R);CHKERRQ(ierr); 72380677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 72480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 72580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 72680677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 72780677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 72880677318SStefano Zampini } 72980677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 73080677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 73180677318SStefano Zampini ierr = MatMatMult(auxmat,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 73280677318SStefano Zampini } else { 73380677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 73480677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 73525084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 73680677318SStefano Zampini } 73780677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 73880677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 73980677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 74006656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 74106656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 74280677318SStefano Zampini if (isCHOL) { 74380677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 74480677318SStefano Zampini } else { 74525084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 74680677318SStefano Zampini } 74780677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 74806656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 74925084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 75025084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 75125084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 75280677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 75380677318SStefano Zampini ierr = MatMatMult(M1,auxmat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 75480677318SStefano Zampini ierr = MatDestroy(&auxmat);CHKERRQ(ierr); 75506656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 75606656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 757f4ddd8eeSStefano Zampini } 75888ebb749SStefano Zampini /* Get submatrices from subdomain matrix */ 75988ebb749SStefano Zampini if (n_vertices) { 76006656605SStefano Zampini IS is_aux; 7613a50541eSStefano Zampini 7626816873aSStefano Zampini if (sub_schurs->reuse_mumps) { /* is_R_local is not sorted, ISComplement doesn't like it */ 7636816873aSStefano Zampini IS tis; 7646816873aSStefano Zampini 7656816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 7666816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 7676816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 7686816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 7696816873aSStefano Zampini } else { 7703a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 7716816873aSStefano Zampini } 7729577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 7739577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 77404708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 77525084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 77688ebb749SStefano Zampini } 77788ebb749SStefano Zampini 77888ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 779f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 78006656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 78106656605SStefano Zampini if (pcbddc->coarse_phi_D) { 78206656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 78306656605SStefano Zampini } 784f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 78506656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 78606656605SStefano Zampini PetscScalar *marray; 78706656605SStefano Zampini 78806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 78906656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 790f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 791f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 792f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 793f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 794f4ddd8eeSStefano Zampini } 795f4ddd8eeSStefano Zampini } 79606656605SStefano Zampini 797f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 79806656605SStefano Zampini PetscScalar *marray; 79988ebb749SStefano Zampini 80006656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 8018eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 80206656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 80388ebb749SStefano Zampini } 8043301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 80506656605SStefano Zampini n *= 2; 80688ebb749SStefano Zampini } 80706656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 80806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 80906656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 8108eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 81106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 81206656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 81388ebb749SStefano Zampini } 8143301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 81506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 8168eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 81706656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 81806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 81988ebb749SStefano Zampini } 82088ebb749SStefano Zampini } else { 821c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 822c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 8231b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 824c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 825c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 826c0553b1fSStefano Zampini } 82788ebb749SStefano Zampini } 82806656605SStefano Zampini } 82906656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 83006656605SStefano Zampini /* vertices */ 83106656605SStefano Zampini if (n_vertices) { 83216f15bc4SStefano Zampini 83304708bb6SStefano Zampini ierr = MatConvert(A_VV,impMatType,MAT_REUSE_MATRIX,&A_VV);CHKERRQ(ierr); 83404708bb6SStefano Zampini 83516f15bc4SStefano Zampini if (n_R) { 83606656605SStefano Zampini Mat A_RRmA_RV,S_VVt; /* S_VVt with LDA=N */ 83706656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 83816f15bc4SStefano Zampini PetscScalar *x,*y; 83904708bb6SStefano Zampini PetscBool isseqaij; 84006656605SStefano Zampini 84121eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 84206656605SStefano Zampini ierr = MatConvert(A_RV,impMatType,MAT_REUSE_MATRIX,&A_RV);CHKERRQ(ierr); 84304708bb6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 8446816873aSStefano Zampini if (F) { /* TODO could be optimized for symmetric problems */ 84506656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 84606656605SStefano Zampini } else { 84706656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 84806656605SStefano Zampini for (i=0;i<n_vertices;i++) { 84906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*n_R);CHKERRQ(ierr); 85006656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 85106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 85206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 85306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 85406656605SStefano Zampini } 85506656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 85606656605SStefano Zampini } 85780677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 85806656605SStefano Zampini /* S_VV and S_CV are the subdomain contribution to coarse matrix. WARNING -> column major ordering */ 85906656605SStefano Zampini if (n_constraints) { 86006656605SStefano Zampini Mat B; 86180677318SStefano Zampini 862b3d85658SStefano Zampini ierr = PetscMemzero(work+n_R*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 86380677318SStefano Zampini for (i=0;i<n_vertices;i++) { 86480677318SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 86580677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+n_R*n_vertices+i*n_B);CHKERRQ(ierr); 86680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 86780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 86880677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 86980677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 87080677318SStefano Zampini } 87180677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 87280677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 87380677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 87406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work+n_R*n_vertices,&B);CHKERRQ(ierr); 87580677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 87606656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 87706656605SStefano Zampini ierr = PetscBLASIntCast(n_R*n_vertices,&B_N);CHKERRQ(ierr); 87806656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+n_R*n_vertices,&B_one,work,&B_one)); 87906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 88006656605SStefano Zampini } 88104708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 88204708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 88304708bb6SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_REUSE_MATRIX,&A_VR);CHKERRQ(ierr); 88404708bb6SStefano Zampini } 88506656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 88680677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 88706656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 88806656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 88906656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 89006656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 89106656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 89206656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 89306656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 89406656605SStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 89516f15bc4SStefano Zampini } else { 89616f15bc4SStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 89716f15bc4SStefano Zampini } 89821eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 89906656605SStefano Zampini /* coarse basis functions */ 90006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 90116f15bc4SStefano Zampini PetscScalar *y; 90216f15bc4SStefano Zampini 90306656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 90406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 90506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 90606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 90706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 90806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 90906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 91006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 91106656605SStefano Zampini 91206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 91306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 91406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 91506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 91606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 91706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 91806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 91906656605SStefano Zampini } 92006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 92106656605SStefano Zampini } 92204708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 92304708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 92406656605SStefano Zampini } 92506656605SStefano Zampini 92606656605SStefano Zampini if (n_constraints) { 92706656605SStefano Zampini Mat B; 92806656605SStefano Zampini 92906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 93006656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 93180677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 93206656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 93306656605SStefano Zampini if (n_vertices) { 93480677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 93580677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 93680677318SStefano Zampini } else { 93780677318SStefano Zampini Mat S_VCt; 93880677318SStefano Zampini 93980677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 94080677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 94180677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 94280677318SStefano Zampini } 94306656605SStefano Zampini } 94406656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 94506656605SStefano Zampini /* coarse basis functions */ 94606656605SStefano Zampini for (i=0;i<n_constraints;i++) { 94706656605SStefano Zampini PetscScalar *y; 94806656605SStefano Zampini 94906656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*i);CHKERRQ(ierr); 95006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 95106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 95206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 95306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 95406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 95506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 95606656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 95706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 95806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 95906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 96006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 96106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 96206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 96306656605SStefano Zampini } 96406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 96506656605SStefano Zampini } 96606656605SStefano Zampini } 96780677318SStefano Zampini if (n_constraints) { 96880677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 96980677318SStefano Zampini } 97006656605SStefano Zampini 97106656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 9723301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 97306656605SStefano Zampini 97406656605SStefano Zampini if (n_constraints) { 97516f15bc4SStefano Zampini Mat S_CCT,B_C; 97606656605SStefano Zampini 97780677318SStefano Zampini /* this is a lazy thing */ 97880677318SStefano Zampini ierr = MatConvert(C_CR,impMatType,MAT_REUSE_MATRIX,&C_CR);CHKERRQ(ierr); 97906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work+n_vertices*n_R,&B_C);CHKERRQ(ierr); 98006656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 98106656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_CCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 98216f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 98306656605SStefano Zampini if (n_vertices) { 98416f15bc4SStefano Zampini Mat B_V,S_VCT; 98506656605SStefano Zampini 98606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&B_V);CHKERRQ(ierr); 98706656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 98806656605SStefano Zampini ierr = MatTransposeMatMult(C_CR,S_VCT,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 98906656605SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 99016f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 99106656605SStefano Zampini } 99206656605SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 99380677318SStefano Zampini } else { /* if there are no constraints, reset work */ 99480677318SStefano Zampini ierr = PetscMemzero(work,n_R*pcbddc->local_primal_size*sizeof(PetscScalar));CHKERRQ(ierr); 99506656605SStefano Zampini } 99616f15bc4SStefano Zampini if (n_vertices && n_R) { 99706656605SStefano Zampini Mat A_VRT; 99880677318SStefano Zampini PetscScalar *marray; 99906656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 100006656605SStefano Zampini 100180677318SStefano Zampini ierr = MatTranspose(A_VR,MAT_INITIAL_MATRIX,&A_VRT);CHKERRQ(ierr); 100280677318SStefano Zampini ierr = MatConvert(A_VRT,impMatType,MAT_REUSE_MATRIX,&A_VRT);CHKERRQ(ierr); 100380677318SStefano Zampini ierr = MatDenseGetArray(A_VRT,&marray);CHKERRQ(ierr); 100406656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_R,&B_N);CHKERRQ(ierr); 100580677318SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&m_one,marray,&B_one,work,&B_one)); 100680677318SStefano Zampini ierr = MatDenseRestoreArray(A_VRT,&marray);CHKERRQ(ierr); 100716f15bc4SStefano Zampini ierr = MatDestroy(&A_VRT);CHKERRQ(ierr); 100806656605SStefano Zampini } 100906656605SStefano Zampini 101006656605SStefano Zampini if (F) { /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 101106656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 101206656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 101306656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 101406656605SStefano Zampini ierr = MatSolveTranspose(F,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 101506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 101606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 101706656605SStefano Zampini } 101806656605SStefano Zampini } else { 101906656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 102006656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 102106656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+(i+pcbddc->local_primal_size)*n_R);CHKERRQ(ierr); 102206656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 102306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 102406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 102506656605SStefano Zampini } 102606656605SStefano Zampini } 102706656605SStefano Zampini /* coarse basis functions */ 102806656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 102906656605SStefano Zampini PetscScalar *y; 103006656605SStefano Zampini 103106656605SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+n_R*(i+pcbddc->local_primal_size));CHKERRQ(ierr); 103206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 103306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 103406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 103506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 103606656605SStefano Zampini if (i<n_vertices) { 103706656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 103806656605SStefano Zampini } 103906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 104006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 104106656605SStefano Zampini 104206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 104306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 104406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 104506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 104606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 104706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 104806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 104906656605SStefano Zampini } 105006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 105106656605SStefano Zampini } 105206656605SStefano Zampini } 1053d62866d3SStefano Zampini /* free memory */ 105488ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 105506656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 105606656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 105706656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 105806656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 1059d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 1060d62866d3SStefano Zampini if (n_vertices) { 1061d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 1062d62866d3SStefano Zampini } 1063d62866d3SStefano Zampini if (n_constraints) { 1064d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 1065d62866d3SStefano Zampini } 106688ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 106788ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 106888ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 106925084f0cSStefano Zampini if (pcbddc->dbg_flag) { 107088ebb749SStefano Zampini Mat coarse_sub_mat; 107125084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 107288ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 107388ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 107488ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 10758bec7fa6SStefano Zampini Mat C_B,CPHI; 10768bec7fa6SStefano Zampini IS is_dummy; 10778bec7fa6SStefano Zampini Vec mones; 107888ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 107988ebb749SStefano Zampini PetscReal real_value; 108088ebb749SStefano Zampini 108188ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 108288ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 108388ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 108488ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 108588ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 108688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1087c0553b1fSStefano Zampini if (unsymmetric_check) { 108888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 108988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 109088ebb749SStefano Zampini } 109188ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 109288ebb749SStefano Zampini 109325084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 10943301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 109525084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1096c0553b1fSStefano Zampini if (unsymmetric_check) { 109788ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 109888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 109988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 110088ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 110188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 110288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 110388ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 110488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 110588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 110688ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 110788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 110888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 110988ebb749SStefano Zampini } else { 111088ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 111188ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 111288ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 111388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 111488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 111588ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 111688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 111788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 111888ebb749SStefano Zampini } 111988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 112088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 112188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 112288ebb749SStefano Zampini ierr = MatConvert(TM1,MATSEQDENSE,MAT_REUSE_MATRIX,&TM1);CHKERRQ(ierr); 112381d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 11248bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 11250fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 112606656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 11278bec7fa6SStefano Zampini 11288bec7fa6SStefano Zampini /* check constraints */ 11298bec7fa6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&is_dummy);CHKERRQ(ierr); 11308bec7fa6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B); 11318bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 11328bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 11338bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 11348bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 11358bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1136bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 1137c0553b1fSStefano Zampini if (unsymmetric_check) { 1138bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 1139bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 1140bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 1141bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 1142bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 114388ebb749SStefano Zampini } 11448bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 11458bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 11468bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 11478bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 11488bec7fa6SStefano Zampini 114925084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 115088ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 115188ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 115288ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 115388ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 115488ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 115588ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 115688ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 115788ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 115888ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 115988ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 1160c0553b1fSStefano Zampini if (unsymmetric_check) { 116188ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 116288ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 116388ebb749SStefano Zampini } 116488ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 116588ebb749SStefano Zampini } 11668629588bSStefano Zampini /* get back data */ 11678629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 116888ebb749SStefano Zampini PetscFunctionReturn(0); 116988ebb749SStefano Zampini } 117088ebb749SStefano Zampini 117188ebb749SStefano Zampini #undef __FUNCT__ 1172d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 1173d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 1174aa0d41d4SStefano Zampini { 1175d65f70fdSStefano Zampini Mat *work_mat; 1176d65f70fdSStefano Zampini IS isrow_s,iscol_s; 1177d65f70fdSStefano Zampini PetscBool rsorted,csorted; 1178d65f70fdSStefano Zampini PetscInt rsize,*idxs_perm_r,csize,*idxs_perm_c; 1179aa0d41d4SStefano Zampini PetscErrorCode ierr; 1180aa0d41d4SStefano Zampini 1181aa0d41d4SStefano Zampini PetscFunctionBegin; 1182d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 1183d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 1184d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 1185d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 1186aa0d41d4SStefano Zampini 1187d65f70fdSStefano Zampini if (!rsorted) { 1188906d46d4SStefano Zampini const PetscInt *idxs; 1189906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 1190aa0d41d4SStefano Zampini 1191d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 1192d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 1193d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1194d65f70fdSStefano Zampini idxs_perm_r[i] = i; 1195aa0d41d4SStefano Zampini } 1196d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 1197d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 1198d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1199d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 1200aa0d41d4SStefano Zampini } 1201d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 1202d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 1203d65f70fdSStefano Zampini } else { 1204d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 1205d65f70fdSStefano Zampini isrow_s = isrow; 1206aa0d41d4SStefano Zampini } 1207906d46d4SStefano Zampini 1208d65f70fdSStefano Zampini if (!csorted) { 1209d65f70fdSStefano Zampini if (isrow == iscol) { 1210d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 1211d65f70fdSStefano Zampini iscol_s = isrow_s; 1212d65f70fdSStefano Zampini } else { 1213d65f70fdSStefano Zampini const PetscInt *idxs; 1214d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 1215906d46d4SStefano Zampini 1216d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 1217d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 1218d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1219d65f70fdSStefano Zampini idxs_perm_c[i] = i; 1220d65f70fdSStefano Zampini } 1221d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 1222d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 1223d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1224d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 1225d65f70fdSStefano Zampini } 1226d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 1227d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 1228d65f70fdSStefano Zampini } 1229d65f70fdSStefano Zampini } else { 1230d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 1231d65f70fdSStefano Zampini iscol_s = iscol; 1232d65f70fdSStefano Zampini } 1233d65f70fdSStefano Zampini 1234d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1235d65f70fdSStefano Zampini 1236d65f70fdSStefano Zampini if (!rsorted || !csorted) { 1237906d46d4SStefano Zampini Mat new_mat; 1238d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 1239906d46d4SStefano Zampini 1240d65f70fdSStefano Zampini if (!rsorted) { 1241d65f70fdSStefano Zampini PetscInt *idxs_r,i; 1242d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 1243d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 1244d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 1245906d46d4SStefano Zampini } 1246d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 1247d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 1248d65f70fdSStefano Zampini } else { 1249d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 1250906d46d4SStefano Zampini } 1251d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 1252d65f70fdSStefano Zampini 1253d65f70fdSStefano Zampini if (!csorted) { 1254d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 1255d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 1256d65f70fdSStefano Zampini is_perm_c = is_perm_r; 1257d65f70fdSStefano Zampini } else { 1258d65f70fdSStefano Zampini PetscInt *idxs_c,i; 1259d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 1260d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 1261d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 1262d65f70fdSStefano Zampini } 1263d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 1264d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 1265d65f70fdSStefano Zampini } 1266d65f70fdSStefano Zampini } else { 1267d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 1268d65f70fdSStefano Zampini } 1269d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 1270d65f70fdSStefano Zampini 1271d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 1272d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 1273d65f70fdSStefano Zampini work_mat[0] = new_mat; 1274d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 1275d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 1276d65f70fdSStefano Zampini } 1277d65f70fdSStefano Zampini 1278d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 1279d65f70fdSStefano Zampini *B = work_mat[0]; 1280d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 1281d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 1282d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 1283d65f70fdSStefano Zampini PetscFunctionReturn(0); 1284d65f70fdSStefano Zampini } 1285d65f70fdSStefano Zampini 1286d65f70fdSStefano Zampini #undef __FUNCT__ 12875e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 12885e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 1289aa0d41d4SStefano Zampini { 1290aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 12913bbff08aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 12925e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1293d65f70fdSStefano Zampini Mat new_mat; 12945e8657edSStefano Zampini IS is_local,is_global; 1295d65f70fdSStefano Zampini PetscInt local_size; 1296d65f70fdSStefano Zampini PetscBool isseqaij; 1297aa0d41d4SStefano Zampini PetscErrorCode ierr; 1298aa0d41d4SStefano Zampini 1299aa0d41d4SStefano Zampini PetscFunctionBegin; 1300aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 13015e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 13025e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 13033bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,is_local,&is_global);CHKERRQ(ierr); 1304aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 1305d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 1306aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 1307906d46d4SStefano Zampini 1308906d46d4SStefano Zampini /* check */ 1309906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 1310906d46d4SStefano Zampini Vec x,x_change; 1311906d46d4SStefano Zampini PetscReal error; 1312906d46d4SStefano Zampini 13135e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 1314906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 13155e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 1316e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1317e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1318d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 1319e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1320e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1321906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 1322906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 1323906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1324906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 1325906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 1326906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 1327906d46d4SStefano Zampini } 1328906d46d4SStefano Zampini 132922d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 13309b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 133122d5777bSStefano Zampini if (isseqaij) { 1332d65f70fdSStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 1333aa0d41d4SStefano Zampini } else { 1334aa0d41d4SStefano Zampini Mat work_mat; 1335aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 1336d65f70fdSStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 1337aa0d41d4SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 1338aa0d41d4SStefano Zampini } 13393301b35fSStefano Zampini if (matis->A->symmetric_set) { 13403301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 1341e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 13423301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 1343e496cd5dSStefano Zampini #endif 13443301b35fSStefano Zampini } 134545a1bb75SStefano Zampini /* 134645a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1347d65f70fdSStefano Zampini ierr = MatView(new_mat,(PetscViewer)0);CHKERRQ(ierr); 134845a1bb75SStefano Zampini */ 1349d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 1350aa0d41d4SStefano Zampini PetscFunctionReturn(0); 1351aa0d41d4SStefano Zampini } 1352aa0d41d4SStefano Zampini 1353aa0d41d4SStefano Zampini #undef __FUNCT__ 1354a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 13558ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 1356a64d13efSStefano Zampini { 1357a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1358a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1359d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 136053892102SStefano Zampini PetscInt *idx_R_local=NULL; 13613a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 13623a50541eSStefano Zampini PetscInt vbs,bs; 13636816873aSStefano Zampini PetscBT bitmask=NULL; 1364a64d13efSStefano Zampini PetscErrorCode ierr; 1365a64d13efSStefano Zampini 1366a64d13efSStefano Zampini PetscFunctionBegin; 1367b23d619eSStefano Zampini /* 1368b23d619eSStefano Zampini No need to setup local scatters if 1369b23d619eSStefano Zampini - primal space is unchanged 1370b23d619eSStefano Zampini AND 1371b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 1372b23d619eSStefano Zampini AND 1373b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 1374b23d619eSStefano Zampini */ 1375b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 1376f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 1377f4ddd8eeSStefano Zampini } 1378f4ddd8eeSStefano Zampini /* destroy old objects */ 1379f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 1380f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 1381f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 1382a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 1383b371cd4fSStefano Zampini n_B = pcis->n_B; 1384b371cd4fSStefano Zampini n_D = pcis->n - n_B; 1385b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 13863a50541eSStefano Zampini 1387a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 13886816873aSStefano Zampini 138953892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 13906816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 1391854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 1392a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 1393a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 13940e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 1395a64d13efSStefano Zampini } 1396a64d13efSStefano Zampini 1397a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 13984641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 13996816873aSStefano Zampini idx_R_local[n_R++] = i; 1400a64d13efSStefano Zampini } 1401a64d13efSStefano Zampini } 140253892102SStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing MUMPS Schur solver */ 14036816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 14046816873aSStefano Zampini 140553892102SStefano Zampini ierr = ISGetIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 140653892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_R,&n_R);CHKERRQ(ierr); 14076816873aSStefano Zampini } 14083a50541eSStefano Zampini 14093a50541eSStefano Zampini /* Block code */ 14103a50541eSStefano Zampini vbs = 1; 14113a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 14123a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 14133a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 14143a50541eSStefano Zampini PetscInt *vary; 1415d3df7717SStefano Zampini if (!sub_schurs->reuse_mumps) { 1416785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 14173a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 1418d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 1419d3df7717SStefano Zampini /* it is ok to check this way since local_primal_ref_node are always sorted by local numbering and idx_R_local is obtained as a complement */ 14200e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 1421d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 14223a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 14233a50541eSStefano Zampini is_blocked = PETSC_FALSE; 14243a50541eSStefano Zampini break; 14253a50541eSStefano Zampini } 14263a50541eSStefano Zampini } 1427d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 1428d3df7717SStefano Zampini } else { 1429d3df7717SStefano Zampini /* Verify directly the R set */ 1430d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 1431d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 1432d3df7717SStefano Zampini for (j=1; j<bs; j++) { 1433d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 1434d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 1435d3df7717SStefano Zampini break; 1436d3df7717SStefano Zampini } 1437d3df7717SStefano Zampini } 1438d3df7717SStefano Zampini } 1439d3df7717SStefano Zampini } 14403a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 14413a50541eSStefano Zampini vbs = bs; 14423a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 14433a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 14443a50541eSStefano Zampini } 14453a50541eSStefano Zampini } 14463a50541eSStefano Zampini } 14473a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 144853892102SStefano Zampini if (sub_schurs->reuse_mumps) { 144953892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 145053892102SStefano Zampini 145153892102SStefano Zampini ierr = ISRestoreIndices(reuse_mumps->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 145253892102SStefano Zampini ierr = ISDestroy(&reuse_mumps->is_R);CHKERRQ(ierr); 145353892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 145453892102SStefano Zampini reuse_mumps->is_R = pcbddc->is_R_local; 145553892102SStefano Zampini } else { 14563a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 145753892102SStefano Zampini } 1458a64d13efSStefano Zampini 1459a64d13efSStefano Zampini /* print some info if requested */ 1460a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 1461a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1462a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 14630fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1464a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 1465a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 14663a50541eSStefano 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); 1467a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1468a64d13efSStefano Zampini } 1469a64d13efSStefano Zampini 1470a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 14716816873aSStefano Zampini if (!sub_schurs->reuse_mumps) { 14726816873aSStefano Zampini IS is_aux1,is_aux2; 14736816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 14746816873aSStefano Zampini 14753a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1476854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 1477854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 1478a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 14794641a718SStefano Zampini for (i=0; i<n_D; i++) { 14804641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 14814641a718SStefano Zampini } 1482a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1483a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 14844641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 14854641a718SStefano Zampini aux_array1[j++] = i; 1486a64d13efSStefano Zampini } 1487a64d13efSStefano Zampini } 1488a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1489a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1490a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 14914641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 14924641a718SStefano Zampini aux_array2[j++] = i; 1493a64d13efSStefano Zampini } 1494a64d13efSStefano Zampini } 1495a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 1496a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 1497a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 1498a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1499a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 1500a64d13efSStefano Zampini 15018eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 1502785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 1503a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 15044641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 15054641a718SStefano Zampini aux_array1[j++] = i; 1506a64d13efSStefano Zampini } 1507a64d13efSStefano Zampini } 1508a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 1509a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 1510a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 1511a64d13efSStefano Zampini } 15124641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 15133a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 1514d62866d3SStefano Zampini } else { 151553892102SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 15166816873aSStefano Zampini IS tis; 15176816873aSStefano Zampini PetscInt schur_size; 15186816873aSStefano Zampini 151953892102SStefano Zampini ierr = ISGetLocalSize(reuse_mumps->is_B,&schur_size);CHKERRQ(ierr); 15206816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 152153892102SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_mumps->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 15226816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 15236816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 15246816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 15256816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 15266816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 1527d62866d3SStefano Zampini } 1528d62866d3SStefano Zampini } 1529a64d13efSStefano Zampini PetscFunctionReturn(0); 1530a64d13efSStefano Zampini } 1531a64d13efSStefano Zampini 1532304d26faSStefano Zampini 1533304d26faSStefano Zampini #undef __FUNCT__ 1534304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 1535684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 1536304d26faSStefano Zampini { 1537304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1538304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1539304d26faSStefano Zampini PC pc_temp; 1540304d26faSStefano Zampini Mat A_RR; 1541f4ddd8eeSStefano Zampini MatReuse reuse; 1542304d26faSStefano Zampini PetscScalar m_one = -1.0; 1543304d26faSStefano Zampini PetscReal value; 154404708bb6SStefano Zampini PetscInt n_D,n_R; 15459577ea80SStefano Zampini PetscBool use_exact,use_exact_reduced,issbaij; 1546304d26faSStefano Zampini PetscErrorCode ierr; 1547e604994aSStefano Zampini /* prefixes stuff */ 1548312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 1549e604994aSStefano Zampini size_t len; 1550304d26faSStefano Zampini 1551304d26faSStefano Zampini PetscFunctionBegin; 1552304d26faSStefano Zampini 1553e604994aSStefano Zampini /* compute prefixes */ 1554e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 1555e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 1556e604994aSStefano Zampini if (!pcbddc->current_level) { 1557e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1558e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 1559e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1560e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1561e604994aSStefano Zampini } else { 1562e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 1563312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 1564e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 1565e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 1566312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 1567312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 156834d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 156934d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 1570e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 1571e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 1572e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 1573e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 1574e604994aSStefano Zampini } 1575e604994aSStefano Zampini 1576304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 1577684f6988SStefano Zampini if (dirichlet) { 1578d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 15793301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 15803301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 1581964fefecSStefano Zampini } 1582ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 1583964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 1584304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 1585304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 1586304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 1587304d26faSStefano Zampini /* default */ 1588304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 1589e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 15909577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 1591304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 15929577ea80SStefano Zampini if (issbaij) { 15939577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 15949577ea80SStefano Zampini } else { 1595304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 15969577ea80SStefano Zampini } 1597304d26faSStefano Zampini /* Allow user's customization */ 1598304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 1599304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1600304d26faSStefano Zampini } 1601d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 1602d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 1603d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1604d62866d3SStefano Zampini 1605d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_mumps->interior_solver);CHKERRQ(ierr); 1606d5574798SStefano Zampini } 1607304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1608304d26faSStefano Zampini if (!n_D) { 1609304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 1610304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1611304d26faSStefano Zampini } 1612304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 1613304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 1614304d26faSStefano Zampini /* set ksp_D into pcis data */ 1615304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 1616304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 1617304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 1618684f6988SStefano Zampini } 1619304d26faSStefano Zampini 1620304d26faSStefano Zampini /* NEUMANN PROBLEM */ 1621684f6988SStefano Zampini A_RR = 0; 1622684f6988SStefano Zampini if (neumann) { 1623d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 162404708bb6SStefano Zampini PetscInt ibs,mbs; 162504708bb6SStefano Zampini PetscBool issbaij; 162604708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 1627f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 16288ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 1629f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 1630f4ddd8eeSStefano Zampini PetscInt nn_R; 163181d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 1632f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 1633f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 1634f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 1635f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 1636f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1637f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1638f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 1639727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 1640f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1641f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1642f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 1643f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 1644f4ddd8eeSStefano Zampini } 1645f4ddd8eeSStefano Zampini } 1646f4ddd8eeSStefano Zampini /* last check */ 1647d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 1648f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1649f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1650f4ddd8eeSStefano Zampini } 1651f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 1652f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 1653f4ddd8eeSStefano Zampini } 1654f4ddd8eeSStefano Zampini /* extract A_RR */ 1655af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 1656af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 165704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 165804708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 165904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 166004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 166104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 1662af732b37SStefano Zampini } else { 166304708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 16646816873aSStefano Zampini } 166504708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 166604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 166704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 166804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 166904708bb6SStefano Zampini } else { 167004708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 167104708bb6SStefano Zampini } 167204708bb6SStefano Zampini } 167304708bb6SStefano Zampini if (!sub_schurs->reuse_mumps) { 1674f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 16753301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 16763301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 16776816873aSStefano Zampini } 16786816873aSStefano Zampini } else { 16796816873aSStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 16806816873aSStefano Zampini 16816816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 16826816873aSStefano Zampini ierr = PCGetOperators(reuse_mumps->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 16836816873aSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 1684af732b37SStefano Zampini } 1685f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 1686304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 1687304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 1688304d26faSStefano Zampini /* default */ 1689304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 1690e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 1691304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 16929577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 16939577ea80SStefano Zampini if (issbaij) { 16949577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 16959577ea80SStefano Zampini } else { 1696304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 16979577ea80SStefano Zampini } 1698304d26faSStefano Zampini /* Allow user's customization */ 1699304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 1700304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 1701304d26faSStefano Zampini } 1702d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 1703304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 1704304d26faSStefano Zampini if (!n_R) { 1705304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 1706304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 1707304d26faSStefano Zampini } 1708d62866d3SStefano Zampini /* Reuse MUMPS solver if it is present */ 1709d62866d3SStefano Zampini if (sub_schurs->reuse_mumps) { 1710d62866d3SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1711d62866d3SStefano Zampini 1712d62866d3SStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_mumps->correction_solver);CHKERRQ(ierr); 1713d62866d3SStefano Zampini } 1714304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 1715304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 1716684f6988SStefano Zampini } 17176816873aSStefano Zampini /* free Neumann problem's matrix */ 17186816873aSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 1719304d26faSStefano Zampini 1720304d26faSStefano Zampini /* check Dirichlet and Neumann solvers and adapt them if a nullspace correction is needed */ 17210fccc4e9SStefano Zampini if (pcbddc->NullSpace || pcbddc->dbg_flag) { 1722684f6988SStefano Zampini if (pcbddc->dbg_flag) { 1723684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1724684f6988SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 1725684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1726684f6988SStefano Zampini } 1727684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 17280fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 17290fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 17300fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 17310fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 17320fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 1733304d26faSStefano Zampini /* need to be adapted? */ 1734b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 1735b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1736b8ffe317SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,use_exact_reduced);CHKERRQ(ierr); 1737304d26faSStefano Zampini /* print info */ 1738304d26faSStefano Zampini if (pcbddc->dbg_flag) { 1739e604994aSStefano 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); 1740304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1741304d26faSStefano Zampini } 1742b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced && !pcbddc->switch_static) { 1743298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcis->is_I_local);CHKERRQ(ierr); 1744304d26faSStefano Zampini } 1745684f6988SStefano Zampini } 1746684f6988SStefano Zampini if (neumann) { /* Neumann */ 17476816873aSStefano Zampini ierr = KSPGetOperators(pcbddc->ksp_R,&A_RR,NULL);CHKERRQ(ierr); 17480fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 17490fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 17500fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 17510fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 17520fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 1753304d26faSStefano Zampini /* need to be adapted? */ 1754b8ffe317SStefano Zampini use_exact = (PetscAbsReal(value) > 1.e-4 ? PETSC_FALSE : PETSC_TRUE); 1755b8ffe317SStefano Zampini ierr = MPI_Allreduce(&use_exact,&use_exact_reduced,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 1756304d26faSStefano Zampini /* print info */ 1757304d26faSStefano Zampini if (pcbddc->dbg_flag) { 1758e604994aSStefano 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); 1759304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 1760304d26faSStefano Zampini } 1761b8ffe317SStefano Zampini if (pcbddc->NullSpace && !use_exact_reduced) { /* is it the right logic? */ 1762298c0119SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->is_R_local);CHKERRQ(ierr); 1763304d26faSStefano Zampini } 17640fccc4e9SStefano Zampini } 1765684f6988SStefano Zampini } 1766304d26faSStefano Zampini PetscFunctionReturn(0); 1767304d26faSStefano Zampini } 1768304d26faSStefano Zampini 1769304d26faSStefano Zampini #undef __FUNCT__ 1770ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 177180677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 1772674ae819SStefano Zampini { 1773674ae819SStefano Zampini PetscErrorCode ierr; 1774674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 1775be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 1776674ae819SStefano Zampini 1777674ae819SStefano Zampini PetscFunctionBegin; 1778be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 177980677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 178020c7b377SStefano Zampini } 178180677318SStefano Zampini if (!pcbddc->switch_static) { 178280677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 178380677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 178480677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 178520c7b377SStefano Zampini } 1786be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 178780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 178880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 178920c7b377SStefano Zampini } else { 1790be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1791be83ff47SStefano Zampini 179253892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 179353892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,inout_B,reuse_mumps->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 179420c7b377SStefano Zampini } 1795be83ff47SStefano Zampini } else { 179680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 179780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 179880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 179980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 180080677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 180180677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 180280677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 180380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 180480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1805674ae819SStefano Zampini } 1806674ae819SStefano Zampini } 1807be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 180880677318SStefano Zampini if (applytranspose) { 180980677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 181080677318SStefano Zampini } else { 181180677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 181280677318SStefano Zampini } 181353892102SStefano Zampini #if defined(PETSC_HAVE_MUMPS) 1814be83ff47SStefano Zampini } else { 1815be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1816be83ff47SStefano Zampini 1817be83ff47SStefano Zampini if (applytranspose) { 181853892102SStefano Zampini ierr = MatMumpsSolveSchurComplementTranspose(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 1819be83ff47SStefano Zampini } else { 182053892102SStefano Zampini ierr = MatMumpsSolveSchurComplement(reuse_mumps->F,reuse_mumps->rhs_B,reuse_mumps->sol_B);CHKERRQ(ierr); 1821be83ff47SStefano Zampini } 182253892102SStefano Zampini #endif 1823be83ff47SStefano Zampini } 182480677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 182580677318SStefano Zampini if (!pcbddc->switch_static) { 1826be83ff47SStefano Zampini if (!sub_schurs->reuse_mumps) { 182780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 182880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1829be83ff47SStefano Zampini } else { 1830be83ff47SStefano Zampini PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 1831be83ff47SStefano Zampini 183253892102SStefano Zampini ierr = VecScatterBegin(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 183353892102SStefano Zampini ierr = VecScatterEnd(reuse_mumps->correction_scatter_B,reuse_mumps->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1834be83ff47SStefano Zampini } 183580677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 183680677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 183780677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 183880677318SStefano Zampini } 183980677318SStefano Zampini } else { 184080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 184180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 184280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 184380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 184480677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 184580677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 184680677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 184780677318SStefano Zampini } 184880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 184980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 185180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1852674ae819SStefano Zampini } 1853674ae819SStefano Zampini PetscFunctionReturn(0); 1854674ae819SStefano Zampini } 1855674ae819SStefano Zampini 1856dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 1857674ae819SStefano Zampini #undef __FUNCT__ 1858674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 1859dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 1860674ae819SStefano Zampini { 1861674ae819SStefano Zampini PetscErrorCode ierr; 1862674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 1863674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 1864674ae819SStefano Zampini const PetscScalar zero = 0.0; 1865674ae819SStefano Zampini 1866674ae819SStefano Zampini PetscFunctionBegin; 1867dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 1868dc359a40SStefano Zampini if (applytranspose) { 1869674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 18708eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 1871dc359a40SStefano Zampini } else { 1872674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 1873674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 187415aaf578SStefano Zampini } 187512edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 187612edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 187712edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 187912edc857SStefano Zampini 18809f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 188112edc857SStefano Zampini /* TODO remove null space when doing multilevel */ 188212edc857SStefano Zampini if (pcbddc->coarse_ksp) { 1883964fefecSStefano Zampini Vec rhs,sol; 1884964fefecSStefano Zampini 1885964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 1886964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 188712edc857SStefano Zampini if (applytranspose) { 1888964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 188912edc857SStefano Zampini } else { 1890964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 189112edc857SStefano Zampini } 189212edc857SStefano Zampini } 1893674ae819SStefano Zampini 1894674ae819SStefano Zampini /* Local solution on R nodes */ 189580677318SStefano Zampini if (pcis->n) { /* in/out pcbddc->vec1_B,pcbddc->vec1_D */ 189680677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 18979f00e9b4SStefano Zampini } 1898674ae819SStefano Zampini 18999f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 19009f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 190112edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1902674ae819SStefano Zampini 1903674ae819SStefano Zampini /* Sum contributions from two levels */ 1904dc359a40SStefano Zampini if (applytranspose) { 1905dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 1906dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1907dc359a40SStefano Zampini } else { 1908674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 19098eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1910dc359a40SStefano Zampini } 1911674ae819SStefano Zampini PetscFunctionReturn(0); 1912674ae819SStefano Zampini } 1913674ae819SStefano Zampini 1914674ae819SStefano Zampini #undef __FUNCT__ 1915674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 191612edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 1917674ae819SStefano Zampini { 1918674ae819SStefano Zampini PetscErrorCode ierr; 1919674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 192058da7f69SStefano Zampini PetscScalar *array; 192112edc857SStefano Zampini Vec from,to; 1922674ae819SStefano Zampini 1923674ae819SStefano Zampini PetscFunctionBegin; 192412edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 192512edc857SStefano Zampini from = pcbddc->coarse_vec; 192612edc857SStefano Zampini to = pcbddc->vec1_P; 192712edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 192812edc857SStefano Zampini Vec tvec; 192958da7f69SStefano Zampini 193058da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 193158da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 193212edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 193358da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 193458da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 193558da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 193612edc857SStefano Zampini } 193712edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 193812edc857SStefano Zampini from = pcbddc->vec1_P; 193912edc857SStefano Zampini to = pcbddc->coarse_vec; 194012edc857SStefano Zampini } 194112edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 1942674ae819SStefano Zampini PetscFunctionReturn(0); 1943674ae819SStefano Zampini } 1944674ae819SStefano Zampini 1945674ae819SStefano Zampini #undef __FUNCT__ 1946674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 194712edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 1948674ae819SStefano Zampini { 1949674ae819SStefano Zampini PetscErrorCode ierr; 1950674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 195158da7f69SStefano Zampini PetscScalar *array; 195212edc857SStefano Zampini Vec from,to; 1953674ae819SStefano Zampini 1954674ae819SStefano Zampini PetscFunctionBegin; 195512edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 195612edc857SStefano Zampini from = pcbddc->coarse_vec; 195712edc857SStefano Zampini to = pcbddc->vec1_P; 195812edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 195912edc857SStefano Zampini from = pcbddc->vec1_P; 196012edc857SStefano Zampini to = pcbddc->coarse_vec; 196112edc857SStefano Zampini } 196212edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 196312edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 196412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 196512edc857SStefano Zampini Vec tvec; 196658da7f69SStefano Zampini 196712edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 196858da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 196958da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 197058da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 197158da7f69SStefano Zampini } 197258da7f69SStefano Zampini } else { 197358da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 197458da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 197512edc857SStefano Zampini } 197612edc857SStefano Zampini } 1977674ae819SStefano Zampini PetscFunctionReturn(0); 1978674ae819SStefano Zampini } 1979674ae819SStefano Zampini 1980984c4197SStefano Zampini /* uncomment for testing purposes */ 1981984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 1982674ae819SStefano Zampini #undef __FUNCT__ 1983674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 1984674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 1985674ae819SStefano Zampini { 1986674ae819SStefano Zampini PetscErrorCode ierr; 1987674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 1988674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1989674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 1990984c4197SStefano Zampini /* one and zero */ 1991984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 1992984c4197SStefano Zampini /* space to store constraints and their local indices */ 19939162d606SStefano Zampini PetscScalar *constraints_data; 19949162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 19959162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 19969162d606SStefano Zampini PetscInt *constraints_n; 1997984c4197SStefano Zampini /* iterators */ 1998b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 1999984c4197SStefano Zampini /* BLAS integers */ 2000e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 2001e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 2002c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 2003727cdba6SStefano Zampini /* reuse */ 20040e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 20050e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 2006984c4197SStefano Zampini /* change of basis */ 2007b3d85658SStefano Zampini PetscBool qr_needed; 20089162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 2009984c4197SStefano Zampini /* auxiliary stuff */ 201064efe560SStefano Zampini PetscInt *nnz,*is_indices; 20118a0068c3SStefano Zampini PetscInt ncc; 2012984c4197SStefano Zampini /* some quantities */ 201345a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 2014a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 2015984c4197SStefano Zampini 2016674ae819SStefano Zampini PetscFunctionBegin; 20178e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 20188e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 20198e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 2020088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 2021088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 20220e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 20230e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 20240e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 20250e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 20260e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 2027088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2028cf5a6209SStefano Zampini 2029cf5a6209SStefano Zampini /* print some info */ 2030cf5a6209SStefano Zampini if (pcbddc->dbg_flag) { 2031cf5a6209SStefano Zampini IS vertices; 2032cf5a6209SStefano Zampini PetscInt nv,nedges,nfaces; 2033cf5a6209SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 2034cf5a6209SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 2035cf5a6209SStefano Zampini ierr = ISDestroy(&vertices);CHKERRQ(ierr); 2036cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 2037cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2038cf5a6209SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 2039fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 2040fd14bc51SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 2041cf5a6209SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2042cf5a6209SStefano Zampini } 2043cf5a6209SStefano Zampini 2044cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 20459162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 2046cf5a6209SStefano Zampini MatNullSpace nearnullsp; 2047cf5a6209SStefano Zampini const Vec *nearnullvecs; 2048cf5a6209SStefano Zampini Vec *localnearnullsp; 2049cf5a6209SStefano Zampini PetscScalar *array; 2050cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 2051cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 2052674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 2053b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 2054674ae819SStefano Zampini PetscScalar *work; 2055674ae819SStefano Zampini PetscReal *singular_vals; 2056674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2057674ae819SStefano Zampini PetscReal *rwork; 2058674ae819SStefano Zampini #endif 2059674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2060674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 2061674ae819SStefano Zampini #else 2062964fefecSStefano Zampini PetscBLASInt dummy_int=1; 2063964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 2064674ae819SStefano Zampini #endif 2065674ae819SStefano Zampini 2066674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 2067d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 2068d06fc5fdSStefano Zampini /* free unneeded index sets */ 2069d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 2070d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 2071674ae819SStefano Zampini } 2072d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 2073d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2074d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2075d06fc5fdSStefano Zampini } 2076d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2077d06fc5fdSStefano Zampini n_ISForEdges = 0; 2078d06fc5fdSStefano Zampini } 2079d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 2080d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2081d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2082d06fc5fdSStefano Zampini } 2083d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2084d06fc5fdSStefano Zampini n_ISForFaces = 0; 2085d06fc5fdSStefano Zampini } 208670022509SStefano Zampini 208770022509SStefano Zampini #if defined(PETSC_USE_DEBUG) 208870022509SStefano Zampini /* HACK: when solving singular problems not using vertices, a change of basis is mandatory. 208970022509SStefano Zampini Also use_change_of_basis should be consistent among processors */ 209070022509SStefano Zampini if (pcbddc->NullSpace) { 209170022509SStefano Zampini PetscBool tbool[2],gbool[2]; 209270022509SStefano Zampini 209370022509SStefano Zampini if (!ISForVertices && !pcbddc->user_ChangeOfBasisMatrix) { 2094b8ffe317SStefano Zampini pcbddc->use_change_of_basis = PETSC_TRUE; 2095d06fc5fdSStefano Zampini if (!ISForEdges) { 2096d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = PETSC_TRUE; 2097d06fc5fdSStefano Zampini } 2098b8ffe317SStefano Zampini } 2099d06fc5fdSStefano Zampini tbool[0] = pcbddc->use_change_of_basis; 2100d06fc5fdSStefano Zampini tbool[1] = pcbddc->use_change_on_faces; 2101d06fc5fdSStefano Zampini ierr = MPI_Allreduce(tbool,gbool,2,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2102d06fc5fdSStefano Zampini pcbddc->use_change_of_basis = gbool[0]; 2103d06fc5fdSStefano Zampini pcbddc->use_change_on_faces = gbool[1]; 210498a51de6SStefano Zampini } 210570022509SStefano Zampini #endif 210608122e43SStefano Zampini 2107674ae819SStefano Zampini /* check if near null space is attached to global mat */ 2108674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 2109674ae819SStefano Zampini if (nearnullsp) { 2110674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 2111f4ddd8eeSStefano Zampini /* remove any stored info */ 2112f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 2113f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2114f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 2115f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 2116f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 2117473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 2118f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 2119f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 2120f4ddd8eeSStefano Zampini } 2121984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 2122984c4197SStefano Zampini nnsp_size = 0; 2123674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 2124674ae819SStefano Zampini } 2125984c4197SStefano Zampini /* get max number of constraints on a single cc */ 2126984c4197SStefano Zampini max_constraints = nnsp_size; 2127984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 2128984c4197SStefano Zampini 2129674ae819SStefano Zampini /* 2130674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 21319162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 21329162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 21339162d606SStefano Zampini There can be multiple constraints per connected component 2134674ae819SStefano Zampini */ 2135674ae819SStefano Zampini n_vertices = 0; 2136674ae819SStefano Zampini if (ISForVertices) { 2137674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 2138674ae819SStefano Zampini } 21399162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 21409162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 21419162d606SStefano Zampini 21429162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 21439162d606SStefano Zampini total_counts *= max_constraints; 2144674ae819SStefano Zampini total_counts += n_vertices; 21454641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 21469162d606SStefano Zampini 2147674ae819SStefano Zampini total_counts = 0; 2148674ae819SStefano Zampini max_size_of_constraint = 0; 2149674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 21509162d606SStefano Zampini IS used_is; 2151674ae819SStefano Zampini if (i<n_ISForEdges) { 21529162d606SStefano Zampini used_is = ISForEdges[i]; 2153674ae819SStefano Zampini } else { 21549162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 2155674ae819SStefano Zampini } 21569162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 2157674ae819SStefano Zampini total_counts += j; 2158674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 2159674ae819SStefano Zampini } 21609162d606SStefano Zampini ierr = PetscMalloc3(total_counts*max_constraints+n_vertices,&constraints_data,total_counts+n_vertices,&constraints_idxs,total_counts+n_vertices,&constraints_idxs_B);CHKERRQ(ierr); 21619162d606SStefano Zampini 2162984c4197SStefano Zampini /* get local part of global near null space vectors */ 2163785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 2164984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2165984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 2166e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2167e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2168984c4197SStefano Zampini } 2169674ae819SStefano Zampini 2170242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 2171242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 2172a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 2173242a89d7SStefano Zampini 2174984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 2175a773dcb8SStefano Zampini if (!skip_lapack) { 2176674ae819SStefano Zampini PetscScalar temp_work; 2177911cabfeSStefano Zampini 2178674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2179984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 2180785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 2181785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 2182785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 2183674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2184785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 2185674ae819SStefano Zampini #endif 2186674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2187c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 2188c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 2189674ae819SStefano Zampini lwork = -1; 2190674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2191674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2192c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 2193674ae819SStefano Zampini #else 2194c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 2195674ae819SStefano Zampini #endif 2196674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2197984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 2198674ae819SStefano Zampini #else /* on missing GESVD */ 2199674ae819SStefano Zampini /* SVD */ 2200674ae819SStefano Zampini PetscInt max_n,min_n; 2201674ae819SStefano Zampini max_n = max_size_of_constraint; 2202984c4197SStefano Zampini min_n = max_constraints; 2203984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 2204674ae819SStefano Zampini min_n = max_size_of_constraint; 2205984c4197SStefano Zampini max_n = max_constraints; 2206674ae819SStefano Zampini } 2207785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 2208674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2209785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 2210674ae819SStefano Zampini #endif 2211674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 2212674ae819SStefano Zampini lwork = -1; 2213e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 2214e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 2215b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 2216674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2217674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 22189162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&constraints_data[0],&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,&lierr)); 2219674ae819SStefano Zampini #else 22209162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&constraints_data[0],&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,rwork,&lierr)); 2221674ae819SStefano Zampini #endif 2222674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2223984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 2224984c4197SStefano Zampini #endif /* on missing GESVD */ 2225674ae819SStefano Zampini /* Allocate optimal workspace */ 2226674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 2227854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 2228674ae819SStefano Zampini } 2229674ae819SStefano Zampini /* Now we can loop on constraining sets */ 2230674ae819SStefano Zampini total_counts = 0; 22319162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 22329162d606SStefano Zampini constraints_data_ptr[0] = 0; 2233674ae819SStefano Zampini /* vertices */ 22349162d606SStefano Zampini if (n_vertices) { 2235674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 22369162d606SStefano Zampini if (nnsp_has_cnst) { /* it considers all possible vertices */ 22379162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 2238674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 22399162d606SStefano Zampini constraints_n[total_counts] = 1; 22409162d606SStefano Zampini constraints_data[total_counts] = 1.0; 22419162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 22429162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 2243674ae819SStefano Zampini total_counts++; 2244674ae819SStefano Zampini } 2245674ae819SStefano Zampini } else { /* consider vertices for which exist at least a localnearnullsp which is not null there */ 2246984c4197SStefano Zampini PetscBool used_vertex; 2247674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 2248674ae819SStefano Zampini used_vertex = PETSC_FALSE; 2249674ae819SStefano Zampini k = 0; 2250674ae819SStefano Zampini while (!used_vertex && k<nnsp_size) { 2251984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2252984c4197SStefano Zampini if (PetscAbsScalar(array[is_indices[i]])>0.0) { 22539162d606SStefano Zampini constraints_n[total_counts] = 1; 22549162d606SStefano Zampini constraints_idxs[total_counts] = is_indices[i]; 22559162d606SStefano Zampini constraints_data[total_counts] = 1.0; 22569162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 22579162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 2258674ae819SStefano Zampini total_counts++; 2259674ae819SStefano Zampini used_vertex = PETSC_TRUE; 2260674ae819SStefano Zampini } 2261984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2262674ae819SStefano Zampini k++; 2263674ae819SStefano Zampini } 2264674ae819SStefano Zampini } 2265674ae819SStefano Zampini } 2266674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2267674ae819SStefano Zampini n_vertices = total_counts; 2268674ae819SStefano Zampini } 2269984c4197SStefano Zampini 2270674ae819SStefano Zampini /* edges and faces */ 22719162d606SStefano Zampini total_counts_cc = total_counts; 2272911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 22739162d606SStefano Zampini IS used_is; 22749162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 22759162d606SStefano Zampini 2276911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 22779162d606SStefano Zampini used_is = ISForEdges[ncc]; 2278984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 2279674ae819SStefano Zampini } else { 22809162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 2281984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 2282674ae819SStefano Zampini } 2283674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 22849162d606SStefano Zampini 22859162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 22869162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 2287984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 2288984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 2289674ae819SStefano Zampini if (nnsp_has_cnst) { 22905b08dc53SStefano Zampini PetscScalar quad_value; 22919162d606SStefano Zampini 22929162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 22939162d606SStefano Zampini idxs_copied = PETSC_TRUE; 22949162d606SStefano Zampini 2295a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 2296674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 2297a773dcb8SStefano Zampini } else { 2298a773dcb8SStefano Zampini quad_value = 1.0; 2299a773dcb8SStefano Zampini } 2300674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 23019162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 2302674ae819SStefano Zampini } 23039162d606SStefano Zampini temp_constraints++; 2304674ae819SStefano Zampini total_counts++; 2305674ae819SStefano Zampini } 2306674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 2307984c4197SStefano Zampini PetscReal real_value; 23089162d606SStefano Zampini PetscScalar *ptr_to_data; 23099162d606SStefano Zampini 2310984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 23119162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 2312674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 23139162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 2314674ae819SStefano Zampini } 2315984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 2316984c4197SStefano Zampini /* check if array is null on the connected component */ 2317e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 23189162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 23195b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 2320674ae819SStefano Zampini temp_constraints++; 2321674ae819SStefano Zampini total_counts++; 23229162d606SStefano Zampini if (!idxs_copied) { 23239162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 23249162d606SStefano Zampini idxs_copied = PETSC_TRUE; 2325674ae819SStefano Zampini } 2326674ae819SStefano Zampini } 23279162d606SStefano Zampini } 23289162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 232945a1bb75SStefano Zampini valid_constraints = temp_constraints; 2330eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 2331a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 23329162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 23339162d606SStefano Zampini 23349162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2335a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 23369162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 2337a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 23389162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 2339a773dcb8SStefano Zampini } else { /* perform SVD */ 2340984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 23419162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 2342674ae819SStefano Zampini 2343674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2344984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 2345984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 2346984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 2347984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 2348984c4197SStefano Zampini from that computed using LAPACKgesvd 2349984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 2350984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 2351984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 2352674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 2353e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2354984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2355674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 2356674ae819SStefano Zampini for (k=0;k<j+1;k++) { 23579162d606SStefano Zampini PetscStackCallBLAS("BLASdot",correlation_mat[j*temp_constraints+k] = BLASdot_(&Blas_N,ptr_to_data+k*size_of_constraint,&Blas_one,ptr_to_data+j*size_of_constraint,&Blas_one)); 2358674ae819SStefano Zampini } 2359674ae819SStefano Zampini } 2360e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 2361e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2362e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 2363674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 2364c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 2365674ae819SStefano Zampini #else 2366c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 2367674ae819SStefano Zampini #endif 2368674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2369984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 2370984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 2371674ae819SStefano Zampini j = 0; 2372984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 2373674ae819SStefano Zampini total_counts = total_counts-j; 237445a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 2375e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 2376c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2377c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2378c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 2379c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2380c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 2381c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2382674ae819SStefano Zampini if (j<temp_constraints) { 2383984c4197SStefano Zampini PetscInt ii; 2384984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 2385674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 23869162d606SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,ptr_to_data,&Blas_LDA,correlation_mat,&Blas_LDB,&zero,temp_basis,&Blas_LDC)); 2387674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2388984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 2389674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 23909162d606SStefano Zampini ptr_to_data[k*size_of_constraint+ii] = singular_vals[temp_constraints-1-k]*temp_basis[(temp_constraints-1-k)*size_of_constraint+ii]; 2391674ae819SStefano Zampini } 2392674ae819SStefano Zampini } 2393674ae819SStefano Zampini } 2394674ae819SStefano Zampini #else /* on missing GESVD */ 2395e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 2396e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 2397b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2398674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2399674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 24009162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,ptr_to_data,&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,&lierr)); 2401674ae819SStefano Zampini #else 24029162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,ptr_to_data,&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,rwork,&lierr)); 2403674ae819SStefano Zampini #endif 2404984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 2405674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2406984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 2407e310c8b4SStefano Zampini k = temp_constraints; 2408e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 2409674ae819SStefano Zampini j = 0; 2410e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 241145a1bb75SStefano Zampini valid_constraints = k-j; 2412911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 2413984c4197SStefano Zampini #endif /* on missing GESVD */ 2414674ae819SStefano Zampini } 2415a773dcb8SStefano Zampini } 24169162d606SStefano Zampini /* update pointers information */ 24179162d606SStefano Zampini if (valid_constraints) { 24189162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 24199162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 24209162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 24219162d606SStefano Zampini /* set change_of_basis flag */ 242245a1bb75SStefano Zampini if (boolforchange) { 2423b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 24249162d606SStefano Zampini } 2425b3d85658SStefano Zampini total_counts_cc++; 242645a1bb75SStefano Zampini } 242745a1bb75SStefano Zampini } 2428984c4197SStefano Zampini /* free workspace */ 24298f1c130eSStefano Zampini if (!skip_lapack) { 2430984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 2431984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2432984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 2433984c4197SStefano Zampini #endif 2434984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 2435984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 2436984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 2437984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 2438984c4197SStefano Zampini #endif 2439984c4197SStefano Zampini } 2440984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 2441984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 2442984c4197SStefano Zampini } 2443984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 2444cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 2445cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 2446cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 2447cf5a6209SStefano Zampini } 2448cf5a6209SStefano Zampini if (n_ISForFaces) { 2449cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 2450cf5a6209SStefano Zampini } 2451cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 2452cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 2453cf5a6209SStefano Zampini } 2454cf5a6209SStefano Zampini if (n_ISForEdges) { 2455cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 2456cf5a6209SStefano Zampini } 2457cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 245808122e43SStefano Zampini } else { 245908122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 2460984c4197SStefano Zampini 246108122e43SStefano Zampini total_counts = 0; 246208122e43SStefano Zampini n_vertices = 0; 2463d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 2464d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 246508122e43SStefano Zampini } 246608122e43SStefano Zampini max_constraints = 0; 24679162d606SStefano Zampini total_counts_cc = 0; 246808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 246908122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 24709162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 247108122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 247208122e43SStefano Zampini } 24739162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 24749162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 24759162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 24769162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 247774d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 24789162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 24799162d606SStefano Zampini total_counts_cc = 0; 24809162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 24819162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 24829162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 248308122e43SStefano Zampini } 248408122e43SStefano Zampini } 24859162d606SStefano Zampini #if 0 24869162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 24879162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 24889162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 24899162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 24909162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 24919162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 24929162d606SStefano Zampini } 24939162d606SStefano Zampini printf("\n"); 24949162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 24959162d606SStefano Zampini } 24961b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 24978bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 24981b968477SStefano Zampini } 24991b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 25008bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] sub %d, edge %d, n %d\n",PetscGlobalRank,i,(PetscBool)PetscBTLookup(sub_schurs->is_edge,i),pcbddc->adaptive_constraints_n[i+n_vertices]); 25011b968477SStefano Zampini } 250208122e43SStefano Zampini #endif 250308122e43SStefano Zampini 25048bec7fa6SStefano Zampini max_size_of_constraint = 0; 25059162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) max_size_of_constraint = PetscMax(max_size_of_constraint,constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]); 25069162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 250708122e43SStefano Zampini /* Change of basis */ 2508b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 250908122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 251008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 251108122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 2512b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 251308122e43SStefano Zampini } 251408122e43SStefano Zampini } 251508122e43SStefano Zampini } 251608122e43SStefano Zampini } 2517984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 25180e6343abSStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 251908122e43SStefano Zampini 25209162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 25219162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 25229162d606SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) { 25239162d606SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for constraints indices %d != %d\n",constraints_idxs_ptr[total_counts_cc],i); 252408122e43SStefano Zampini } 2525674ae819SStefano Zampini 2526674ae819SStefano Zampini /* Create constraint matrix */ 2527674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 252816f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 2529984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 2530984c4197SStefano Zampini 2531984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 2532a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 2533a717540cSStefano Zampini qr_needed = PETSC_FALSE; 253474d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 2535984c4197SStefano Zampini total_primal_vertices=0; 2536b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 25379162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 25389162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 2539984c4197SStefano Zampini if (size_of_constraint == 1) { 25409162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 2541b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 254264efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 25439162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 25449162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 2545a717540cSStefano Zampini } 2546b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 254774d5cdf7SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single || pcbddc->faster_deluxe) { 2548a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 2549a717540cSStefano Zampini qr_needed = PETSC_TRUE; 2550a717540cSStefano Zampini } 2551fa434743SStefano Zampini } else { 2552b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 2553fa434743SStefano Zampini } 2554a717540cSStefano Zampini } 2555b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 2556b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 2557674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 255870022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 2559b3d85658SStefano Zampini 2560b3d85658SStefano Zampini ierr = PetscMalloc2(pcbddc->local_primal_size_cc,&pcbddc->local_primal_ref_node,pcbddc->local_primal_size_cc,&pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 25610e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 25620e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 2563984c4197SStefano Zampini 2564984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 256574d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 2566785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 2567984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 256874d5cdf7SStefano Zampini 2569984c4197SStefano Zampini j = total_primal_vertices; 257074d5cdf7SStefano Zampini total_counts = total_primal_vertices; 2571b3d85658SStefano Zampini cum = total_primal_vertices; 25729162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 25734641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 2574b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 2575b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 2576b3d85658SStefano Zampini cum++; 25779162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 257874d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 257974d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 258074d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 258174d5cdf7SStefano Zampini } 25829162d606SStefano Zampini j += constraints_n[i]; 2583674ae819SStefano Zampini } 2584674ae819SStefano Zampini } 2585674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 2586674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2587088faed8SStefano Zampini 2588674ae819SStefano Zampini /* set values in constraint matrix */ 2589984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 25900e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 2591674ae819SStefano Zampini } 2592984c4197SStefano Zampini total_counts = total_primal_vertices; 25939162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 25944641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 25959162d606SStefano Zampini PetscInt *cols; 25969162d606SStefano Zampini 25979162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 25989162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 25999162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 26009162d606SStefano Zampini PetscInt row = total_counts+k; 26019162d606SStefano Zampini PetscScalar *vals; 26029162d606SStefano Zampini 26039162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 26049162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 26059162d606SStefano Zampini } 26069162d606SStefano Zampini total_counts += constraints_n[i]; 2607674ae819SStefano Zampini } 2608674ae819SStefano Zampini } 2609674ae819SStefano Zampini /* assembling */ 2610674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2611674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2612088faed8SStefano Zampini 2613984c4197SStefano Zampini /* 261445a1bb75SStefano Zampini ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 2615984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 2616984c4197SStefano Zampini */ 2617674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 2618674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 2619026de310SStefano Zampini /* dual and primal dofs on a single cc */ 2620984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 2621984c4197SStefano Zampini /* working stuff for GEQRF */ 262281d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 2623984c4197SStefano Zampini PetscBLASInt lqr_work; 2624984c4197SStefano Zampini /* working stuff for UNGQR */ 2625984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 2626984c4197SStefano Zampini PetscBLASInt lgqr_work; 2627984c4197SStefano Zampini /* working stuff for TRTRS */ 2628984c4197SStefano Zampini PetscScalar *trs_rhs; 26293f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 2630984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 2631984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 2632984c4197SStefano Zampini PetscScalar *start_vals; 2633984c4197SStefano Zampini /* working stuff for values insertion */ 26344641a718SStefano Zampini PetscBT is_primal; 263564efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 2636906d46d4SStefano Zampini /* matrix sizes */ 2637906d46d4SStefano Zampini PetscInt global_size,local_size; 2638906d46d4SStefano Zampini /* temporary change of basis */ 2639906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 2640cf5a6209SStefano Zampini /* extra space for debugging */ 2641cf5a6209SStefano Zampini PetscScalar *dbg_work; 2642984c4197SStefano Zampini 2643906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 2644906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 264516f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 2646bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 2647906d46d4SStefano Zampini /* nonzeros for local mat */ 2648bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 2649bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 26509162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 2651a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 26529162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 2653a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 26549162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 2655a717540cSStefano Zampini } else { 26569162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 26579162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 2658a717540cSStefano Zampini } 2659a717540cSStefano Zampini } 2660a717540cSStefano Zampini } 2661906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 2662bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2663a717540cSStefano Zampini /* Set initial identity in the matrix */ 2664bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 2665906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 2666a717540cSStefano Zampini } 2667a717540cSStefano Zampini 2668a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2669a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2670a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2671a717540cSStefano Zampini } 2672a717540cSStefano Zampini 2673a717540cSStefano Zampini 2674a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 2675a717540cSStefano Zampini /* 2676a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 2677a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 2678a717540cSStefano Zampini 2679a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 2680a717540cSStefano Zampini 2681a6b551f4SStefano 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) 2682a6b551f4SStefano Zampini 2683a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 2684a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 2685a717540cSStefano Zampini | ... | 2686a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 2687a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 2688a717540cSStefano Zampini 2689a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 2690a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 2691a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 2692a6b551f4SStefano Zampini 2693a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 2694a717540cSStefano Zampini */ 2695a717540cSStefano Zampini if (qr_needed) { 2696984c4197SStefano Zampini /* space to store Q */ 2697854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 2698984c4197SStefano Zampini /* first we issue queries for optimal work */ 26993f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 27003f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 27013f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2702984c4197SStefano Zampini lqr_work = -1; 27033f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 2704984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 2705984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 2706785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 2707984c4197SStefano Zampini lgqr_work = -1; 27083f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 27093f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 27103f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 27113f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 27123f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 27133f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 2714984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 2715984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 2716785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 2717984c4197SStefano Zampini /* array to store scaling factors for reflectors */ 2718785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 2719984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 2720785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 2721a717540cSStefano Zampini /* allocating workspace for check */ 2722a717540cSStefano Zampini if (pcbddc->dbg_flag) { 2723cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 2724a717540cSStefano Zampini } 2725a717540cSStefano Zampini } 2726984c4197SStefano Zampini /* array to store whether a node is primal or not */ 27274641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 2728473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 27290e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 273039e2fb2aSStefano Zampini if (i != total_primal_vertices) { 273139e2fb2aSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Error in boundary numbering for BDDC vertices! %d != %d\n",total_primal_vertices,i); 27324641a718SStefano Zampini } 273339e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 273439e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 273539e2fb2aSStefano Zampini } 273639e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 2737984c4197SStefano Zampini 2738a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 27399162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 27409162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 27414641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 2742984c4197SStefano Zampini /* get constraint info */ 27439162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 2744984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 2745984c4197SStefano Zampini 2746984c4197SStefano Zampini if (pcbddc->dbg_flag) { 27479162d606SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraints %d: %d need a change of basis (size %d)\n",total_counts,primal_dofs,size_of_constraint);CHKERRQ(ierr); 2748674ae819SStefano Zampini } 2749984c4197SStefano Zampini 2750fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 2751a717540cSStefano Zampini 2752a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 2753a717540cSStefano Zampini if (pcbddc->dbg_flag) { 27549162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2755a717540cSStefano Zampini } 2756984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 27579162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2758984c4197SStefano Zampini 2759984c4197SStefano Zampini /* compute QR decomposition of constraints */ 27603f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 27613f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 27623f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2763674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 27643f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 2765984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 2766674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2767984c4197SStefano Zampini 2768984c4197SStefano Zampini /* explictly compute R^-T */ 2769984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 2770984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 27713f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 27723f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 27733f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 27743f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 2775984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 27763f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 2777984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 2778984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2779984c4197SStefano Zampini 2780a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 27813f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 27823f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 27833f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 27843f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2785984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 27863f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 2787984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 2788984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2789984c4197SStefano Zampini 2790984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 2791984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 2792984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 27933f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 27943f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 27953f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 27963f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 27973f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 27983f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 2799984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 28009162d606SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&zero,constraints_data+constraints_data_ptr[total_counts],&Blas_LDC)); 2801984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 28029162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 2803984c4197SStefano Zampini 2804984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 28059162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 2806984c4197SStefano Zampini /* insert cols for primal dofs */ 2807984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 2808984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 28099162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 2810906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 2811984c4197SStefano Zampini } 2812984c4197SStefano Zampini /* insert cols for dual dofs */ 2813984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 28149162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 2815984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 28169162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 2817906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 2818984c4197SStefano Zampini j++; 2819674ae819SStefano Zampini } 2820674ae819SStefano Zampini } 2821984c4197SStefano Zampini 2822984c4197SStefano Zampini /* check change of basis */ 2823984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2824984c4197SStefano Zampini PetscInt ii,jj; 2825984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 2826c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 2827c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 2828c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 2829c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 2830c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 2831c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 2832984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2833cf5a6209SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&Blas_M,&Blas_N,&Blas_K,&one,dbg_work,&Blas_LDA,qr_basis,&Blas_LDB,&zero,&dbg_work[size_of_constraint*primal_dofs],&Blas_LDC)); 2834984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 2835984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 2836984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 2837cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 2838cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) valid_qr = PETSC_FALSE; 2839674ae819SStefano Zampini } 2840674ae819SStefano Zampini } 2841984c4197SStefano Zampini if (!valid_qr) { 284222d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 2843984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 2844984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 2845cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 2846cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not orthogonal to constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 2847674ae819SStefano Zampini } 2848cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 2849cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not unitary w.r.t constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 2850984c4197SStefano Zampini } 2851984c4197SStefano Zampini } 2852984c4197SStefano Zampini } 2853674ae819SStefano Zampini } else { 285422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 2855674ae819SStefano Zampini } 2856674ae819SStefano Zampini } 2857a717540cSStefano Zampini } else { /* simple transformation block */ 2858a717540cSStefano Zampini PetscInt row,col; 2859a6b551f4SStefano Zampini PetscScalar val,norm; 2860a6b551f4SStefano Zampini 2861a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 28629162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,constraints_data+constraints_data_ptr[total_counts],&Blas_one,constraints_data+constraints_data_ptr[total_counts],&Blas_one)); 2863a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 28649162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 28659162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 2866bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 28679162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 2868906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 28699162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 2870a717540cSStefano Zampini } else { 2871a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 28729162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 2873a717540cSStefano Zampini if (row != col) { 28749162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 2875a717540cSStefano Zampini } else { 28769162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 2877a717540cSStefano Zampini } 2878906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 2879a717540cSStefano Zampini } 2880a717540cSStefano Zampini } 2881a717540cSStefano Zampini } 288298a51de6SStefano Zampini if (pcbddc->dbg_flag) { 288322d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 2884a717540cSStefano Zampini } 2885674ae819SStefano Zampini } 2886984c4197SStefano Zampini } else { 2887984c4197SStefano Zampini if (pcbddc->dbg_flag) { 28889162d606SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraint %d does not need a change of basis (size %d)\n",total_counts,size_of_constraint);CHKERRQ(ierr); 2889674ae819SStefano Zampini } 2890674ae819SStefano Zampini } 2891674ae819SStefano Zampini } 2892a717540cSStefano Zampini 2893a717540cSStefano Zampini /* free workspace */ 2894a717540cSStefano Zampini if (qr_needed) { 2895984c4197SStefano Zampini if (pcbddc->dbg_flag) { 2896cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 2897984c4197SStefano Zampini } 2898984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 2899984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 2900984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 2901984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 2902984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 2903674ae819SStefano Zampini } 2904a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 2905906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2906906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2907906d46d4SStefano Zampini 2908906d46d4SStefano Zampini /* assembling of global change of variable */ 2909bbb9e6c6SStefano Zampini { 2910bbb9e6c6SStefano Zampini Mat tmat; 291116f15bc4SStefano Zampini PetscInt bs; 291216f15bc4SStefano Zampini 2913906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 2914906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 2915bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 2916bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 2917bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2918bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 291916f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 292016f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 2921906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 2922bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 2923bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 2924bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2925bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 2926bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 2927e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2928e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2929bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 2930bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 2931906d46d4SStefano Zampini } 2932906d46d4SStefano Zampini /* check */ 2933906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 2934906d46d4SStefano Zampini PetscReal error; 2935906d46d4SStefano Zampini Vec x,x_change; 2936906d46d4SStefano Zampini 2937906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 2938906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 2939906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 2940906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 2941e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2942e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2943bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 2944e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2945e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2946906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 2947906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 2948906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 2949906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2950bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 2951906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 2952906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 2953906d46d4SStefano Zampini } 2954b96c3477SStefano Zampini 2955b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 2956b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2957b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 2958b96c3477SStefano Zampini if (sub_schurs->S_Ej_all) { 2959ac632422SStefano Zampini Mat S_new,tmat; 2960bbb9e6c6SStefano Zampini IS is_all_N; 2961bbb9e6c6SStefano Zampini 2962bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 29636816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 2964bbb9e6c6SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 2965ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 2966b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 2967ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 2968ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 2969ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 2970ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 2971ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 2972b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 2973ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 2974ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 2975ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 2976ac632422SStefano Zampini } 2977b96c3477SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 2978b96c3477SStefano Zampini } 2979b96c3477SStefano Zampini } 2980906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 2981906d46d4SStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix) { 2982b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 2983b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 2984b9b85e73SStefano Zampini } 2985906d46d4SStefano Zampini 2986906d46d4SStefano Zampini /* set up change of basis context */ 2987906d46d4SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 2988906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 2989906d46d4SStefano Zampini 2990906d46d4SStefano Zampini if (!pcbddc->new_global_mat) { 2991906d46d4SStefano Zampini PetscInt global_size,local_size; 2992906d46d4SStefano Zampini 2993906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 2994906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 2995906d46d4SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->new_global_mat);CHKERRQ(ierr); 2996906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->new_global_mat,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 2997906d46d4SStefano Zampini ierr = MatSetType(pcbddc->new_global_mat,MATSHELL);CHKERRQ(ierr); 2998906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT,(void (*)(void))PCBDDCMatMult_Private);CHKERRQ(ierr); 2999906d46d4SStefano Zampini ierr = MatShellSetOperation(pcbddc->new_global_mat,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCMatMultTranspose_Private);CHKERRQ(ierr); 3000906d46d4SStefano Zampini ierr = PetscNew(&change_ctx);CHKERRQ(ierr); 3001906d46d4SStefano Zampini ierr = MatShellSetContext(pcbddc->new_global_mat,change_ctx);CHKERRQ(ierr); 3002906d46d4SStefano Zampini } else { 3003906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 3004906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 3005906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 3006906d46d4SStefano Zampini } 3007906d46d4SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix) { 3008906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 3009906d46d4SStefano Zampini change_ctx->global_change = pcbddc->ChangeOfBasisMatrix; 3010906d46d4SStefano Zampini } else { 3011906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3012906d46d4SStefano Zampini change_ctx->global_change = pcbddc->user_ChangeOfBasisMatrix; 3013906d46d4SStefano Zampini } 3014906d46d4SStefano Zampini ierr = VecDuplicateVecs(pcis->vec1_global,2,&change_ctx->work);CHKERRQ(ierr); 3015906d46d4SStefano Zampini ierr = MatSetUp(pcbddc->new_global_mat);CHKERRQ(ierr); 3016906d46d4SStefano Zampini ierr = MatAssemblyBegin(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3017906d46d4SStefano Zampini ierr = MatAssemblyEnd(pcbddc->new_global_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3018b9b85e73SStefano Zampini } 3019a717540cSStefano Zampini 3020727cdba6SStefano Zampini /* check if a new primal space has been introduced */ 3021727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 3022727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 3023aff50787SStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_node,olocal_primal_ref_node,olocal_primal_size_cc*sizeof(PetscScalar),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 3024c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 30250e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 3026aff50787SStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_mult,olocal_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscScalar),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 3027727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 3028727cdba6SStefano Zampini } 30290e6343abSStefano Zampini } 30300e6343abSStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 3031727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 3032727cdba6SStefano Zampini ierr = MPI_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 3033727cdba6SStefano Zampini 3034a717540cSStefano Zampini /* flush dbg viewer */ 3035b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 3036b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3037b8ffe317SStefano Zampini } 3038a717540cSStefano Zampini 3039e310c8b4SStefano Zampini /* free workspace */ 3040a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 30414641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 304208122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 30439162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 30449162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 304508122e43SStefano Zampini } else { 30469162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 30479162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 30489162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 304908122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 305008122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 30519162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 30529162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 305308122e43SStefano Zampini } 3054674ae819SStefano Zampini PetscFunctionReturn(0); 3055674ae819SStefano Zampini } 3056674ae819SStefano Zampini 3057674ae819SStefano Zampini #undef __FUNCT__ 3058674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 3059674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 3060674ae819SStefano Zampini { 3061674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3062674ae819SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 3063674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 30647fb0e2dbSStefano Zampini PetscInt ierr,i,vertex_size,N; 3065674ae819SStefano Zampini PetscViewer viewer=pcbddc->dbg_viewer; 3066674ae819SStefano Zampini 3067674ae819SStefano Zampini PetscFunctionBegin; 30688e61c736SStefano Zampini /* Reset previously computed graph */ 30698e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 3070674ae819SStefano Zampini /* Init local Graph struct */ 30717fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 30723bbff08aSStefano Zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,pcis->mapping,N);CHKERRQ(ierr); 3073674ae819SStefano Zampini 3074575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 3075575ad6abSStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) { 3076575ad6abSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 3077575ad6abSStefano Zampini } 30789577ea80SStefano Zampini 3079674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 30804d379d7bSStefano Zampini if (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) { 30814d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 30824d379d7bSStefano Zampini PetscInt nvtxs; 3083e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 3084674ae819SStefano Zampini 30854d379d7bSStefano Zampini if (pcbddc->use_local_adj) { 30862fffb893SStefano Zampini 30872fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 30882fffb893SStefano Zampini if (flg_row) { 30894d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 3090b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 30912fffb893SStefano Zampini } 30922fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 30939b28b941SStefano Zampini } else if (pcbddc->current_level && pcis->n_B) { /* just compute subdomain's connected components for coarser levels when the local boundary is not empty */ 30944d379d7bSStefano Zampini IS is_dummy; 30954d379d7bSStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 30964d379d7bSStefano Zampini PetscInt j,sum; 30974d379d7bSStefano Zampini PetscInt *cxadj,*cadjncy; 30984d379d7bSStefano Zampini const PetscInt *idxs; 30994d379d7bSStefano Zampini PCBDDCGraph graph; 31004d379d7bSStefano Zampini PetscBT is_on_boundary; 31014d379d7bSStefano Zampini 31024d379d7bSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcis->n,0,1,&is_dummy);CHKERRQ(ierr); 31034d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 31044d379d7bSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 31054d379d7bSStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 31067fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,pcis->n);CHKERRQ(ierr); 31074d379d7bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 3108e496cd5dSStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 3109e496cd5dSStefano Zampini if (flg_row) { 31104d379d7bSStefano Zampini graph->xadj = xadj; 31114d379d7bSStefano Zampini graph->adjncy = adjncy; 3112e496cd5dSStefano Zampini } 31134d379d7bSStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 31144d379d7bSStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 3115e496cd5dSStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 31164d379d7bSStefano Zampini 31174d379d7bSStefano Zampini if (pcbddc->dbg_flag) { 31189b28b941SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] Found %d subdomains (local size %d)\n",PetscGlobalRank,graph->ncc,pcis->n);CHKERRQ(ierr); 31194d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 31204d379d7bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"[%d] %d cc size %d\n",PetscGlobalRank,i,graph->cptr[i+1]-graph->cptr[i]);CHKERRQ(ierr); 31214d379d7bSStefano Zampini } 31224d379d7bSStefano Zampini } 31234d379d7bSStefano Zampini 3124e496cd5dSStefano Zampini ierr = PetscBTCreate(pcis->n,&is_on_boundary);CHKERRQ(ierr); 31254d379d7bSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 31264d379d7bSStefano Zampini for (i=0;i<pcis->n_B;i++) { 31274d379d7bSStefano Zampini ierr = PetscBTSet(is_on_boundary,idxs[i]);CHKERRQ(ierr); 31284d379d7bSStefano Zampini } 31294d379d7bSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 31304d379d7bSStefano Zampini 3131e496cd5dSStefano Zampini ierr = PetscCalloc1(pcis->n+1,&cxadj);CHKERRQ(ierr); 31324d379d7bSStefano Zampini sum = 0; 31334d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 31344d379d7bSStefano Zampini PetscInt sizecc = 0; 31354d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 31364d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 31374d379d7bSStefano Zampini sizecc++; 31384d379d7bSStefano Zampini } 31394d379d7bSStefano Zampini } 31404d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 31414d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 31424d379d7bSStefano Zampini cxadj[graph->queue[j]] = sizecc; 31434d379d7bSStefano Zampini } 31444d379d7bSStefano Zampini } 31454d379d7bSStefano Zampini sum += sizecc*sizecc; 31464d379d7bSStefano Zampini } 31474d379d7bSStefano Zampini ierr = PetscMalloc1(sum,&cadjncy);CHKERRQ(ierr); 31484d379d7bSStefano Zampini sum = 0; 3149e496cd5dSStefano Zampini for (i=0;i<pcis->n;i++) { 31504d379d7bSStefano Zampini PetscInt temp = cxadj[i]; 31514d379d7bSStefano Zampini cxadj[i] = sum; 31524d379d7bSStefano Zampini sum += temp; 31534d379d7bSStefano Zampini } 3154e496cd5dSStefano Zampini cxadj[pcis->n] = sum; 31554d379d7bSStefano Zampini for (i=0;i<graph->ncc;i++) { 31564d379d7bSStefano Zampini for (j=graph->cptr[i];j<graph->cptr[i+1];j++) { 31574d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[j])) { 31584d379d7bSStefano Zampini PetscInt k,sizecc = 0; 31594d379d7bSStefano Zampini for (k=graph->cptr[i];k<graph->cptr[i+1];k++) { 31604d379d7bSStefano Zampini if (PetscBTLookup(is_on_boundary,graph->queue[k])) { 31614d379d7bSStefano Zampini cadjncy[cxadj[graph->queue[j]]+sizecc]=graph->queue[k]; 31624d379d7bSStefano Zampini sizecc++; 31634d379d7bSStefano Zampini } 31644d379d7bSStefano Zampini } 31654d379d7bSStefano Zampini } 31664d379d7bSStefano Zampini } 31674d379d7bSStefano Zampini } 31689b28b941SStefano Zampini if (sum) { 3169e496cd5dSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,pcis->n,cxadj,cadjncy,PETSC_OWN_POINTER);CHKERRQ(ierr); 31704d379d7bSStefano Zampini } else { 31714d379d7bSStefano Zampini ierr = PetscFree(cxadj);CHKERRQ(ierr); 31724d379d7bSStefano Zampini ierr = PetscFree(cadjncy);CHKERRQ(ierr); 31734d379d7bSStefano Zampini } 31744d379d7bSStefano Zampini graph->xadj = 0; 31754d379d7bSStefano Zampini graph->adjncy = 0; 31764d379d7bSStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 31774d379d7bSStefano Zampini ierr = PetscBTDestroy(&is_on_boundary);CHKERRQ(ierr); 31784d379d7bSStefano Zampini } 3179674ae819SStefano Zampini } 31809b28b941SStefano Zampini if (pcbddc->dbg_flag) { 31819b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3182674ae819SStefano Zampini } 3183674ae819SStefano Zampini 318463602bcaSStefano Zampini /* Set default dofs' splitting if no information has been provided by the user with PCBDDCSetDofsSplitting or PCBDDCSetDofsSplittingLocal */ 3185674ae819SStefano Zampini vertex_size = 1; 318663602bcaSStefano Zampini if (pcbddc->user_provided_isfordofs) { 318763602bcaSStefano Zampini if (pcbddc->n_ISForDofs) { /* need to convert from global to local and remove references to global dofs splitting */ 318895ecbf38SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 318963602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 3190e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 319163602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 3192674ae819SStefano Zampini } 319363602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 319463602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 319563602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 3196674ae819SStefano Zampini } 319763602bcaSStefano Zampini /* mat block size as vertex size (used for elasticity with rigid body modes as nearnullspace) */ 3198674ae819SStefano Zampini ierr = MatGetBlockSize(matis->A,&vertex_size);CHKERRQ(ierr); 319963602bcaSStefano Zampini } else { 320063602bcaSStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering */ 320163602bcaSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->n_ISForDofsLocal);CHKERRQ(ierr); 3202854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 320363602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 320463602bcaSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),pcis->n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 320563602bcaSStefano Zampini } 320663602bcaSStefano Zampini } 3207674ae819SStefano Zampini } 3208674ae819SStefano Zampini 3209674ae819SStefano Zampini /* Setup of Graph */ 3210785d1243SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { /* need to convert from global to local */ 3211e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 3212785d1243SStefano Zampini } 3213785d1243SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { /* need to convert from global to local */ 3214e176bc59SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,pcis->vec1_global,pcis->vec1_N,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3215785d1243SStefano Zampini } 3216302440fdSBarry Smith ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices);CHKERRQ(ierr); 3217674ae819SStefano Zampini 3218674ae819SStefano Zampini /* Graph's connected components analysis */ 3219674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 3220674ae819SStefano Zampini 3221674ae819SStefano Zampini /* print some info to stdout */ 3222674ae819SStefano Zampini if (pcbddc->dbg_flag) { 3223302440fdSBarry Smith ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,viewer);CHKERRQ(ierr); 3224674ae819SStefano Zampini } 3225fb180af4SStefano Zampini 3226fb180af4SStefano Zampini /* mark topography has done */ 3227fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 3228674ae819SStefano Zampini PetscFunctionReturn(0); 3229674ae819SStefano Zampini } 3230674ae819SStefano Zampini 3231dc456d91SStefano Zampini /* given an index sets possibly with holes, renumbers the indexes removing the holes */ 3232674ae819SStefano Zampini #undef __FUNCT__ 3233674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSubsetNumbering" 3234dc456d91SStefano Zampini PetscErrorCode PCBDDCSubsetNumbering(IS subset, IS subset_mult, PetscInt *N_n, IS *subset_n) 3235674ae819SStefano Zampini { 3236dc456d91SStefano Zampini PetscSF sf; 3237dc456d91SStefano Zampini PetscLayout map; 3238dc456d91SStefano Zampini const PetscInt *idxs; 3239dc456d91SStefano Zampini PetscInt *leaf_data,*root_data,*gidxs; 3240dc456d91SStefano Zampini PetscInt N,n,i,lbounds[2],gbounds[2],Nl; 3241dc456d91SStefano Zampini PetscInt n_n,nlocals,start,first_index; 3242dc456d91SStefano Zampini PetscMPIInt commsize; 3243674ae819SStefano Zampini PetscBool first_found; 3244674ae819SStefano Zampini PetscErrorCode ierr; 3245674ae819SStefano Zampini 3246674ae819SStefano Zampini PetscFunctionBegin; 3247dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&n);CHKERRQ(ierr); 3248dc456d91SStefano Zampini if (subset_mult) { 3249dc456d91SStefano Zampini PetscCheckSameComm(subset,1,subset_mult,2); 3250dc456d91SStefano Zampini ierr = ISGetLocalSize(subset,&i);CHKERRQ(ierr); 3251dc456d91SStefano Zampini if (i != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local subset and multiplicity sizes don't match! %d != %d",n,i); 3252674ae819SStefano Zampini } 3253dc456d91SStefano Zampini /* create workspace layout for computing global indices of subset */ 3254dc456d91SStefano Zampini ierr = ISGetIndices(subset,&idxs);CHKERRQ(ierr); 3255dc456d91SStefano Zampini lbounds[0] = lbounds[1] = 0; 3256dc456d91SStefano Zampini for (i=0;i<n;i++) { 3257dc456d91SStefano Zampini if (idxs[i] < lbounds[0]) lbounds[0] = idxs[i]; 3258dc456d91SStefano Zampini else if (idxs[i] > lbounds[1]) lbounds[1] = idxs[i]; 3259674ae819SStefano Zampini } 3260dc456d91SStefano Zampini lbounds[0] = -lbounds[0]; 3261dc456d91SStefano Zampini ierr = MPI_Allreduce(lbounds,gbounds,2,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3262dc456d91SStefano Zampini gbounds[0] = -gbounds[0]; 3263dc456d91SStefano Zampini N = gbounds[1] - gbounds[0] + 1; 3264dc456d91SStefano Zampini ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)subset),&map);CHKERRQ(ierr); 3265dc456d91SStefano Zampini ierr = PetscLayoutSetBlockSize(map,1);CHKERRQ(ierr); 3266dc456d91SStefano Zampini ierr = PetscLayoutSetSize(map,N);CHKERRQ(ierr); 3267dc456d91SStefano Zampini ierr = PetscLayoutSetUp(map);CHKERRQ(ierr); 3268dc456d91SStefano Zampini ierr = PetscLayoutGetLocalSize(map,&Nl);CHKERRQ(ierr); 3269dc456d91SStefano Zampini 3270dc456d91SStefano Zampini /* create sf : leaf_data == multiplicity of indexes, root data == global index in layout */ 3271dc456d91SStefano Zampini ierr = PetscMalloc2(n,&leaf_data,Nl,&root_data);CHKERRQ(ierr); 3272dc456d91SStefano Zampini if (subset_mult) { 3273dc456d91SStefano Zampini const PetscInt* idxs_mult; 3274dc456d91SStefano Zampini 3275dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3276dc456d91SStefano Zampini ierr = PetscMemcpy(leaf_data,idxs_mult,n*sizeof(PetscInt));CHKERRQ(ierr); 3277dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3278674ae819SStefano Zampini } else { 3279dc456d91SStefano Zampini for (i=0;i<n;i++) leaf_data[i] = 1; 3280674ae819SStefano Zampini } 3281dc456d91SStefano Zampini /* local size of new subset */ 3282dc456d91SStefano Zampini n_n = 0; 3283dc456d91SStefano Zampini for (i=0;i<n;i++) n_n += leaf_data[i]; 3284dc456d91SStefano Zampini 3285dc456d91SStefano Zampini /* global indexes in layout */ 3286dc456d91SStefano Zampini ierr = PetscMalloc1(n_n,&gidxs);CHKERRQ(ierr); /* allocating possibly extra space in gidxs which will be used later */ 3287dc456d91SStefano Zampini for (i=0;i<n;i++) gidxs[i] = idxs[i] - gbounds[0]; 3288dc456d91SStefano Zampini ierr = ISRestoreIndices(subset,&idxs);CHKERRQ(ierr); 3289dc456d91SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)subset),&sf);CHKERRQ(ierr); 3290dc456d91SStefano Zampini ierr = PetscSFSetGraphLayout(sf,map,n,NULL,PETSC_COPY_VALUES,gidxs);CHKERRQ(ierr); 3291dc456d91SStefano Zampini ierr = PetscLayoutDestroy(&map);CHKERRQ(ierr); 3292dc456d91SStefano Zampini 3293dc456d91SStefano Zampini /* reduce from leaves to roots */ 3294dc456d91SStefano Zampini ierr = PetscMemzero(root_data,Nl*sizeof(PetscInt));CHKERRQ(ierr); 329564a8e5bcSStefano Zampini ierr = PetscSFReduceBegin(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 329664a8e5bcSStefano Zampini ierr = PetscSFReduceEnd(sf,MPIU_INT,leaf_data,root_data,MPI_MAX);CHKERRQ(ierr); 3297dc456d91SStefano Zampini 3298dc456d91SStefano Zampini /* count indexes in local part of layout */ 3299674ae819SStefano Zampini nlocals = 0; 3300674ae819SStefano Zampini first_index = -1; 3301674ae819SStefano Zampini first_found = PETSC_FALSE; 3302dc456d91SStefano Zampini for (i=0;i<Nl;i++) { 3303dc456d91SStefano Zampini if (!first_found && root_data[i]) { 3304674ae819SStefano Zampini first_found = PETSC_TRUE; 3305674ae819SStefano Zampini first_index = i; 3306674ae819SStefano Zampini } 3307dc456d91SStefano Zampini nlocals += root_data[i]; 3308674ae819SStefano Zampini } 3309dc456d91SStefano Zampini 3310dc456d91SStefano Zampini /* cumulative of number of indexes and size of subset without holes */ 33115fa240b1SStefano Zampini #if defined(PETSC_HAVE_MPI_EXSCAN) 3312dc456d91SStefano Zampini start = 0; 331364a8e5bcSStefano Zampini ierr = MPI_Exscan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 33145fa240b1SStefano Zampini #else 331564a8e5bcSStefano Zampini ierr = MPI_Scan(&nlocals,&start,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 33165fa240b1SStefano Zampini start = start-nlocals; 33175fa240b1SStefano Zampini #endif 33185fa240b1SStefano Zampini 3319dc456d91SStefano Zampini if (N_n) { /* compute total size of new subset if requested */ 3320dc456d91SStefano Zampini *N_n = start + nlocals; 3321dc456d91SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)subset),&commsize);CHKERRQ(ierr); 3322dc456d91SStefano Zampini ierr = MPI_Bcast(N_n,1,MPIU_INT,commsize-1,PetscObjectComm((PetscObject)subset));CHKERRQ(ierr); 3323674ae819SStefano Zampini } 33245fa240b1SStefano Zampini 33255fa240b1SStefano Zampini /* adapt root data with cumulative */ 3326674ae819SStefano Zampini if (first_found) { 3327dc456d91SStefano Zampini PetscInt old_index; 3328dc456d91SStefano Zampini 3329dc456d91SStefano Zampini root_data[first_index] += start; 3330674ae819SStefano Zampini old_index = first_index; 3331dc456d91SStefano Zampini for (i=first_index+1;i<Nl;i++) { 3332dc456d91SStefano Zampini if (root_data[i]) { 3333dc456d91SStefano Zampini root_data[i] += root_data[old_index]; 3334674ae819SStefano Zampini old_index = i; 3335674ae819SStefano Zampini } 3336674ae819SStefano Zampini } 3337674ae819SStefano Zampini } 3338dc456d91SStefano Zampini 3339dc456d91SStefano Zampini /* from roots to leaves */ 3340dc456d91SStefano Zampini ierr = PetscSFBcastBegin(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 3341dc456d91SStefano Zampini ierr = PetscSFBcastEnd(sf,MPIU_INT,root_data,leaf_data);CHKERRQ(ierr); 3342dc456d91SStefano Zampini ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 3343dc456d91SStefano Zampini 3344dc456d91SStefano Zampini /* create new IS with global indexes without holes */ 3345dc456d91SStefano Zampini if (subset_mult) { 3346dc456d91SStefano Zampini const PetscInt* idxs_mult; 3347dc456d91SStefano Zampini PetscInt cum; 3348dc456d91SStefano Zampini 3349dc456d91SStefano Zampini cum = 0; 3350dc456d91SStefano Zampini ierr = ISGetIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3351dc456d91SStefano Zampini for (i=0;i<n;i++) { 3352dc456d91SStefano Zampini PetscInt j; 3353dc456d91SStefano Zampini for (j=0;j<idxs_mult[i];j++) gidxs[cum++] = leaf_data[i] - idxs_mult[i] + j; 3354674ae819SStefano Zampini } 3355dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_mult,&idxs_mult);CHKERRQ(ierr); 3356674ae819SStefano Zampini } else { 3357dc456d91SStefano Zampini for (i=0;i<n;i++) { 3358dc456d91SStefano Zampini gidxs[i] = leaf_data[i]-1; 3359674ae819SStefano Zampini } 3360674ae819SStefano Zampini } 3361dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)subset),n_n,gidxs,PETSC_OWN_POINTER,subset_n);CHKERRQ(ierr); 3362dc456d91SStefano Zampini ierr = PetscFree2(leaf_data,root_data);CHKERRQ(ierr); 3363674ae819SStefano Zampini PetscFunctionReturn(0); 3364674ae819SStefano Zampini } 33659a7d3425SStefano Zampini 33669a7d3425SStefano Zampini #undef __FUNCT__ 33679a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 33689a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 33699a7d3425SStefano Zampini { 33709a7d3425SStefano Zampini PetscInt i,j; 33719a7d3425SStefano Zampini PetscScalar *alphas; 33729a7d3425SStefano Zampini PetscErrorCode ierr; 33739a7d3425SStefano Zampini 33749a7d3425SStefano Zampini PetscFunctionBegin; 33759a7d3425SStefano Zampini /* this implements stabilized Gram-Schmidt */ 3376785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 33779a7d3425SStefano Zampini for (i=0;i<n;i++) { 33789a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 33799a7d3425SStefano Zampini if (i<n) { ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],&alphas[i+1]);CHKERRQ(ierr); } 33809a7d3425SStefano Zampini for (j=i+1;j<n;j++) { ierr = VecAXPY(vecs[j],PetscConj(-alphas[j]),vecs[i]);CHKERRQ(ierr); } 33819a7d3425SStefano Zampini } 33829a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 33839a7d3425SStefano Zampini PetscFunctionReturn(0); 33849a7d3425SStefano Zampini } 33859a7d3425SStefano Zampini 3386e7931f94SStefano Zampini #undef __FUNCT__ 338770cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 3388b0c7d250SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt n_subdomains, PetscInt redprocs, IS* is_sends) 3389e7931f94SStefano Zampini { 339052e5ac9dSStefano Zampini IS ranks_send_to; 3391e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 3392e7931f94SStefano Zampini PetscMPIInt size,rank,color; 339352e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 339452e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 33953837a79fSStefano Zampini PetscInt i,local_size,threshold=0; 33962b510759SStefano Zampini PetscBool use_vwgt=PETSC_FALSE,use_square=PETSC_FALSE; 3397e7931f94SStefano Zampini PetscSubcomm subcomm; 339852e5ac9dSStefano Zampini PetscErrorCode ierr; 3399a57a6d2fSStefano Zampini 3400e7931f94SStefano Zampini PetscFunctionBegin; 34012b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_square",&use_square,NULL);CHKERRQ(ierr); 34022b510759SStefano Zampini ierr = PetscOptionsGetBool(NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 34032b510759SStefano Zampini ierr = PetscOptionsGetInt(NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 3404e7931f94SStefano Zampini 3405e7931f94SStefano Zampini /* Get info on mapping */ 34063bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 34073bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3408e7931f94SStefano Zampini 3409e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 3410785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 3411e7931f94SStefano Zampini xadj[0] = 0; 3412e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 3413785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 3414785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 3415e7931f94SStefano Zampini 34162b510759SStefano Zampini if (threshold) { 3417d023bfaeSStefano Zampini PetscInt xadj_count = 0; 34182b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 3419d023bfaeSStefano Zampini if (n_shared[i] > threshold) { 3420d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 3421d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 3422d023bfaeSStefano Zampini xadj_count++; 3423e7931f94SStefano Zampini } 3424e7931f94SStefano Zampini } 3425d023bfaeSStefano Zampini xadj[1] = xadj_count; 3426c8587f34SStefano Zampini } else { 3427e7931f94SStefano Zampini if (xadj[1]) { 3428e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy,&neighs[1],xadj[1]*sizeof(*adjncy));CHKERRQ(ierr); 3429e7931f94SStefano Zampini ierr = PetscMemcpy(adjncy_wgt,&n_shared[1],xadj[1]*sizeof(*adjncy_wgt));CHKERRQ(ierr); 3430c8587f34SStefano Zampini } 3431e7931f94SStefano Zampini } 34323bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 3433e7931f94SStefano Zampini if (use_square) { 3434e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3435e7931f94SStefano Zampini adjncy_wgt[i] = adjncy_wgt[i]*adjncy_wgt[i]; 3436e7931f94SStefano Zampini } 3437e7931f94SStefano Zampini } 3438e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3439e7931f94SStefano Zampini 34403837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 3441e7931f94SStefano Zampini 3442e7931f94SStefano Zampini /* 3443e7931f94SStefano Zampini Restrict work on active processes only. 3444e7931f94SStefano Zampini */ 3445e7931f94SStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&subcomm);CHKERRQ(ierr); 3446e7931f94SStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 3447e7931f94SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 34482b510759SStefano Zampini ierr = PetscMPIIntCast(!local_size,&color);CHKERRQ(ierr); 3449d3531aaaSJed Brown ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 3450e7931f94SStefano Zampini if (color) { 3451e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 3452e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 3453e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3454c8587f34SStefano Zampini } else { 345552e5ac9dSStefano Zampini Mat subdomain_adj; 345652e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 345752e5ac9dSStefano Zampini MatPartitioning partitioner; 345852e5ac9dSStefano Zampini PetscInt prank,rstart=0,rend=0; 345952e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 3460b0c7d250SStefano Zampini PetscBool aggregate; 3461b0c7d250SStefano Zampini 3462306c2d5bSBarry Smith ierr = MPI_Comm_size(PetscSubcommChild(subcomm),&size);CHKERRQ(ierr); 3463785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 3464e7931f94SStefano Zampini prank = rank; 3465306c2d5bSBarry Smith ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,PetscSubcommChild(subcomm));CHKERRQ(ierr); 34668002ef2cSStefano Zampini /* 3467e7931f94SStefano Zampini for (i=0;i<size;i++) { 3468e7931f94SStefano Zampini PetscPrintf(subcomm->comm,"oldranks[%d] = %d\n",i,oldranks[i]); 3469c8587f34SStefano Zampini } 34708002ef2cSStefano Zampini */ 3471e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 3472e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 3473c8587f34SStefano Zampini } 3474e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 3475b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 3476b0c7d250SStefano Zampini if (aggregate) { 3477b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 3478b0c7d250SStefano Zampini PetscMPIInt nrank; 3479b0c7d250SStefano Zampini PetscScalar *vals; 3480b0c7d250SStefano Zampini 3481b0c7d250SStefano Zampini ierr = MPI_Comm_rank(PetscSubcommChild(subcomm),&nrank);CHKERRQ(ierr); 3482b0c7d250SStefano Zampini lrows = 0; 3483b0c7d250SStefano Zampini if (nrank<redprocs) { 3484b0c7d250SStefano Zampini lrows = size/redprocs; 3485b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 3486b0c7d250SStefano Zampini } 34875fa240b1SStefano Zampini ierr = MatCreateAIJ(PetscSubcommChild(subcomm),lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 3488b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 3489b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 3490b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 3491b0c7d250SStefano Zampini row = nrank; 3492b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 3493b0c7d250SStefano Zampini cols = adjncy; 3494b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 3495b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 3496b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 3497b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3498b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 349952e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 350052e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 350152e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 3502b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 3503b0c7d250SStefano Zampini } else { 3504306c2d5bSBarry Smith ierr = MatCreateMPIAdj(PetscSubcommChild(subcomm),1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 3505b0c7d250SStefano Zampini } 350622b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 3507e7931f94SStefano Zampini 3508e7931f94SStefano Zampini /* Partition */ 3509306c2d5bSBarry Smith ierr = MatPartitioningCreate(PetscSubcommChild(subcomm),&partitioner);CHKERRQ(ierr); 3510e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 3511e7931f94SStefano Zampini if (use_vwgt) { 35123837a79fSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 3513e7931f94SStefano Zampini v_wgt[0] = local_size; 3514e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 3515c8587f34SStefano Zampini } 351628143c3dSStefano Zampini n_subdomains = PetscMin((PetscInt)size,n_subdomains); 351728143c3dSStefano Zampini ierr = MatPartitioningSetNParts(partitioner,n_subdomains);CHKERRQ(ierr); 3518e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 3519e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 352022b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 3521e7931f94SStefano Zampini 352252e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 352352e5ac9dSStefano Zampini ierr = PCBDDCSubsetNumbering(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 352452e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 352552e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3526b0c7d250SStefano Zampini if (!redprocs) { 3527b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 352828143c3dSStefano Zampini } else { 3529b0c7d250SStefano Zampini PetscInt idxs[1]; 3530b0c7d250SStefano Zampini PetscMPIInt tag; 3531b0c7d250SStefano Zampini MPI_Request *reqs; 3532b0c7d250SStefano Zampini 3533b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 3534b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 3535b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 3536b0c7d250SStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,PetscSubcommChild(subcomm),&reqs[i-rstart]);CHKERRQ(ierr); 353728143c3dSStefano Zampini } 3538b0c7d250SStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,PetscSubcommChild(subcomm),MPI_STATUS_IGNORE);CHKERRQ(ierr); 3539b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3540b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 3541b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 3542e7931f94SStefano Zampini } 354352e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 3544e7931f94SStefano Zampini /* clean up */ 3545e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 354652e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 3547e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 3548e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 3549e7931f94SStefano Zampini } 3550e7931f94SStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 3551e7931f94SStefano Zampini 3552e7931f94SStefano Zampini /* assemble parallel IS for sends */ 3553e7931f94SStefano Zampini i = 1; 3554e7931f94SStefano Zampini if (color) i=0; 3555e7931f94SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,&ranks_send_to);CHKERRQ(ierr); 3556e7931f94SStefano Zampini /* get back IS */ 3557e7931f94SStefano Zampini *is_sends = ranks_send_to; 3558e7931f94SStefano Zampini PetscFunctionReturn(0); 3559e7931f94SStefano Zampini } 3560e7931f94SStefano Zampini 3561e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 3562e7931f94SStefano Zampini 3563e7931f94SStefano Zampini #undef __FUNCT__ 3564e7931f94SStefano Zampini #define __FUNCT__ "MatISSubassemble" 356553a05cb3SStefano Zampini PetscErrorCode MatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, PetscBool restrict_full, MatReuse reuse, Mat *mat_n, PetscInt nis, IS isarray[]) 3566e7931f94SStefano Zampini { 356770cf5478SStefano Zampini Mat local_mat; 3568e7931f94SStefano Zampini IS is_sends_internal; 35699d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 357028143c3dSStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals; 35719d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 3572e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 3573e7931f94SStefano Zampini PetscInt* l2gmap_indices; 3574e7931f94SStefano Zampini const PetscInt* is_indices; 3575e7931f94SStefano Zampini MatType new_local_type; 3576e7931f94SStefano Zampini /* buffers */ 3577e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 357828143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 35799d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 3580e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 3581e7931f94SStefano Zampini /* MPI */ 358228143c3dSStefano Zampini MPI_Comm comm,comm_n; 358328143c3dSStefano Zampini PetscSubcomm subcomm; 3584e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 358528143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 358628143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 358728143c3dSStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,source_dest; 358828143c3dSStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals; 358928143c3dSStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals; 3590e7931f94SStefano Zampini PetscErrorCode ierr; 3591e7931f94SStefano Zampini 3592e7931f94SStefano Zampini PetscFunctionBegin; 359328143c3dSStefano Zampini /* TODO: add missing checks */ 359428143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 359528143c3dSStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 359628143c3dSStefano Zampini PetscValidLogicalCollectiveEnum(mat,reuse,5); 359728143c3dSStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,7); 3598e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 359928143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 3600e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 3601e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 3602e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 3603e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 3604e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 360528143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX && *mat_n) { 360670cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 360770cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 360828143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 360970cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 361070cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 361170cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 361270cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 361370cf5478SStefano Zampini } 3614e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 3615e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 3616e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 3617e7931f94SStefano Zampini if (!is_sends) { 361828143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 3619b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,n_subdomains,0,&is_sends_internal);CHKERRQ(ierr); 3620c8587f34SStefano Zampini } else { 3621e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 3622e7931f94SStefano Zampini is_sends_internal = is_sends; 3623c8587f34SStefano Zampini } 3624e7931f94SStefano Zampini 3625e7931f94SStefano Zampini /* get comm */ 3626a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 3627e7931f94SStefano Zampini 3628e7931f94SStefano Zampini /* compute number of sends */ 3629e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 3630e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 3631e7931f94SStefano Zampini 3632e7931f94SStefano Zampini /* compute number of receives */ 3633e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 3634785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 3635e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 3636e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3637e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 3638e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 3639e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 3640e7931f94SStefano Zampini 364128143c3dSStefano Zampini /* restrict comm if requested */ 364228143c3dSStefano Zampini subcomm = 0; 364328143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 364428143c3dSStefano Zampini if (restrict_comm) { 3645779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 3646779c1cceSStefano Zampini 364728143c3dSStefano Zampini color = 0; 364853a05cb3SStefano Zampini if (restrict_full) { 364953a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 365053a05cb3SStefano Zampini } else { 365153a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 365253a05cb3SStefano Zampini } 365328143c3dSStefano Zampini ierr = MPI_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 365428143c3dSStefano Zampini subcommsize = commsize - subcommsize; 365528143c3dSStefano Zampini /* check if reuse has been requested */ 365628143c3dSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 365728143c3dSStefano Zampini if (*mat_n) { 365828143c3dSStefano Zampini PetscMPIInt subcommsize2; 365928143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 366028143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 366128143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 366228143c3dSStefano Zampini } else { 366328143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 366428143c3dSStefano Zampini } 366528143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 3666779c1cceSStefano Zampini PetscMPIInt rank; 3667779c1cceSStefano Zampini 3668779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 366928143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 367028143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 367128143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 3672306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 367328143c3dSStefano Zampini } 367428143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 367528143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 367628143c3dSStefano Zampini } else { 367728143c3dSStefano Zampini comm_n = comm; 367828143c3dSStefano Zampini } 367928143c3dSStefano Zampini 3680e7931f94SStefano Zampini /* prepare send/receive buffers */ 3681785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 3682e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 3683785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 3684e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 368528143c3dSStefano Zampini if (nis) { 3686854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 368728143c3dSStefano Zampini } 3688e7931f94SStefano Zampini 368928143c3dSStefano Zampini /* Get data from local matrices */ 3690e7931f94SStefano Zampini if (!isdense) { 3691a26c9d0eSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 3692e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 3693e7931f94SStefano Zampini /* 3694e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 3695e7931f94SStefano Zampini send_buffer_idxs should contain: 3696e7931f94SStefano Zampini - MatType_PRIVATE type 3697e7931f94SStefano Zampini - PetscInt size_of_l2gmap 3698e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 3699e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 3700e7931f94SStefano Zampini */ 3701e7931f94SStefano Zampini } else { 3702e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 37033bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 3704854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 3705e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 3706e7931f94SStefano Zampini send_buffer_idxs[1] = i; 37073bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 3708e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 37093bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 3710e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 3711e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 3712e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 3713e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 3714c8587f34SStefano Zampini } 3715c8587f34SStefano Zampini } 3716e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 371728143c3dSStefano Zampini /* additional is (if any) */ 371828143c3dSStefano Zampini if (nis) { 371928143c3dSStefano Zampini PetscMPIInt psum; 372028143c3dSStefano Zampini PetscInt j; 372128143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 372228143c3dSStefano Zampini PetscInt plen; 372328143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 372428143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 372528143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 372628143c3dSStefano Zampini } 3727854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 372828143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 372928143c3dSStefano Zampini PetscInt plen; 373028143c3dSStefano Zampini const PetscInt *is_array_idxs; 373128143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 373228143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 373328143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 373428143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 373528143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 373628143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 373728143c3dSStefano Zampini } 373828143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 373928143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 374028143c3dSStefano Zampini } 374128143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 374228143c3dSStefano Zampini } 374328143c3dSStefano Zampini 3744e7931f94SStefano Zampini buf_size_idxs = 0; 3745e7931f94SStefano Zampini buf_size_vals = 0; 374628143c3dSStefano Zampini buf_size_idxs_is = 0; 3747e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3748e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 3749e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 375028143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 3751e7931f94SStefano Zampini } 3752785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 3753785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 375495ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 3755e7931f94SStefano Zampini 3756e7931f94SStefano Zampini /* get new tags for clean communications */ 3757e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 3758e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 375928143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 3760e7931f94SStefano Zampini 3761e7931f94SStefano Zampini /* allocate for requests */ 3762785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 3763785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 376495ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 3765785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 3766785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 376795ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 3768e7931f94SStefano Zampini 3769e7931f94SStefano Zampini /* communications */ 3770e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 3771e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 377228143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 3773e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3774e7931f94SStefano Zampini source_dest = onodes[i]; 3775e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 3776e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 3777e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3778e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 377928143c3dSStefano Zampini if (nis) { 378028143c3dSStefano 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); 378128143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 378228143c3dSStefano Zampini } 3783e7931f94SStefano Zampini } 3784e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 3785e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 3786e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 3787e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 378828143c3dSStefano Zampini if (nis) { 378928143c3dSStefano 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); 379028143c3dSStefano Zampini } 3791e7931f94SStefano Zampini } 3792e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 3793e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 3794e7931f94SStefano Zampini 3795e7931f94SStefano Zampini /* assemble new l2g map */ 3796e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3797e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 37989d30be91SStefano Zampini new_local_rows = 0; 3799e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 38009d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 3801e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3802e7931f94SStefano Zampini } 38039d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 3804e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 38059d30be91SStefano Zampini new_local_rows = 0; 3806e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 38079d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 38089d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 3809e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3810e7931f94SStefano Zampini } 38119d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 38129d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 3813e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 3814e7931f94SStefano Zampini 3815e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 3816e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 3817e7931f94SStefano 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) */ 3818e7931f94SStefano Zampini if (n_recvs) { 381928143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 3820e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 3821e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3822e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 3823e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 3824e7931f94SStefano Zampini break; 3825e7931f94SStefano Zampini } 3826e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3827e7931f94SStefano Zampini } 3828e7931f94SStefano Zampini switch (new_local_type_private) { 382928143c3dSStefano Zampini case MATDENSE_PRIVATE: 383028143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 3831e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 3832e7931f94SStefano Zampini bs = 1; 383328143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 383428143c3dSStefano Zampini new_local_type = MATSEQDENSE; 383528143c3dSStefano Zampini bs = 1; 383628143c3dSStefano Zampini } 3837e7931f94SStefano Zampini break; 3838e7931f94SStefano Zampini case MATAIJ_PRIVATE: 3839e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 3840e7931f94SStefano Zampini bs = 1; 3841e7931f94SStefano Zampini break; 3842e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 3843e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 3844e7931f94SStefano Zampini break; 3845e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 3846e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 3847e7931f94SStefano Zampini break; 3848e7931f94SStefano Zampini default: 38499d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 3850e7931f94SStefano Zampini break; 3851e7931f94SStefano Zampini } 385228143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 385328143c3dSStefano Zampini new_local_type = MATSEQDENSE; 385428143c3dSStefano Zampini bs = 1; 3855e7931f94SStefano Zampini } 3856e7931f94SStefano Zampini 385770cf5478SStefano Zampini /* create MATIS object if needed */ 385870cf5478SStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 3859e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 3860e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 386170cf5478SStefano Zampini } else { 386270cf5478SStefano Zampini /* it also destroys the local matrices */ 386370cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 386470cf5478SStefano Zampini } 386570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 3866e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 38679d30be91SStefano Zampini 38689d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 38699d30be91SStefano Zampini 38709d30be91SStefano Zampini /* Global to local map of received indices */ 38719d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 38729d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 38739d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 38749d30be91SStefano Zampini 38759d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 38769d30be91SStefano Zampini buf_size_idxs = 0; 38779d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 38789d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 38799d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 38809d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 38819d30be91SStefano Zampini } 38829d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 38839d30be91SStefano Zampini 38849d30be91SStefano Zampini /* set preallocation */ 38859d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 38869d30be91SStefano Zampini if (!newisdense) { 38879d30be91SStefano Zampini PetscInt *new_local_nnz=0; 38889d30be91SStefano Zampini 38899d30be91SStefano Zampini ptr_vals = recv_buffer_vals; 38909d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 38919d30be91SStefano Zampini if (n_recvs) { 38929d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 38939d30be91SStefano Zampini } 38949d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 38959d30be91SStefano Zampini PetscInt j; 38969d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 38979d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 38989d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 38999d30be91SStefano Zampini } 39009d30be91SStefano Zampini } else { 39019d30be91SStefano Zampini /* TODO */ 39029d30be91SStefano Zampini } 39039d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 39049d30be91SStefano Zampini } 39059d30be91SStefano Zampini if (new_local_nnz) { 39069d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 39079d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 39089d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 39099d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 39109d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 39119d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 39129d30be91SStefano Zampini } else { 39139d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 39149d30be91SStefano Zampini } 39159d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 39169d30be91SStefano Zampini } else { 39179d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 39189d30be91SStefano Zampini } 3919e7931f94SStefano Zampini 3920e7931f94SStefano Zampini /* set values */ 3921e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 39229d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 3923e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 3924e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 3925e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 39269d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 3927e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 3928e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 3929e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 393028143c3dSStefano Zampini } else { 393128143c3dSStefano Zampini /* TODO */ 3932e7931f94SStefano Zampini } 3933e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 3934e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 3935e7931f94SStefano Zampini } 3936e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3937e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 393870cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 393970cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 39409d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 39419d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 3942e7931f94SStefano Zampini 3943dfd14d43SStefano Zampini #if 0 394428143c3dSStefano Zampini if (!restrict_comm) { /* check */ 3945e7931f94SStefano Zampini Vec lvec,rvec; 3946e7931f94SStefano Zampini PetscReal infty_error; 3947e7931f94SStefano Zampini 39482a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 3949e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 3950e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 3951e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 395270cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 3953e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 3954e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 3955e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 3956e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 3957e7931f94SStefano Zampini } 395828143c3dSStefano Zampini #endif 3959e7931f94SStefano Zampini 396028143c3dSStefano Zampini /* assemble new additional is (if any) */ 396128143c3dSStefano Zampini if (nis) { 396228143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 396328143c3dSStefano Zampini 396428143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 3965854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 396628143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 396728143c3dSStefano Zampini psum = 0; 396828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 396928143c3dSStefano Zampini for (j=0;j<nis;j++) { 397028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 397128143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 397228143c3dSStefano Zampini psum += plen; 397328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 397428143c3dSStefano Zampini } 397528143c3dSStefano Zampini } 3976854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 3977854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 397828143c3dSStefano Zampini for (i=1;i<nis;i++) { 397928143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 398028143c3dSStefano Zampini } 398128143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 398228143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 398328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 398428143c3dSStefano Zampini for (j=0;j<nis;j++) { 398528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 398628143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 398728143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 398828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 398928143c3dSStefano Zampini } 399028143c3dSStefano Zampini } 399128143c3dSStefano Zampini for (i=0;i<nis;i++) { 399228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 399328143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 399428143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 399528143c3dSStefano Zampini } 399628143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 399728143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 399828143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 399928143c3dSStefano Zampini } 4000e7931f94SStefano Zampini /* free workspace */ 400128143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 4002e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4003e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 4004e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 4005e7931f94SStefano Zampini if (isdense) { 4006e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 4007e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 4008e7931f94SStefano Zampini } else { 4009e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 4010e7931f94SStefano Zampini } 401128143c3dSStefano Zampini if (nis) { 401228143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 401328143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 401428143c3dSStefano Zampini } 4015e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 4016e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 401728143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 4018e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 4019e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 402028143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 4021e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 4022e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 4023e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 4024e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 4025e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 402628143c3dSStefano Zampini if (nis) { 402728143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 402828143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 402928143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 403028143c3dSStefano Zampini } 403128143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 403228143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 403328143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 403428143c3dSStefano Zampini for (i=0;i<nis;i++) { 403528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 403628143c3dSStefano Zampini } 403753a05cb3SStefano Zampini *mat_n = NULL; 403828143c3dSStefano Zampini } 4039e7931f94SStefano Zampini PetscFunctionReturn(0); 4040e7931f94SStefano Zampini } 4041a57a6d2fSStefano Zampini 404212edc857SStefano Zampini /* temporary hack into ksp private data structure */ 4043af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 404412edc857SStefano Zampini 4045c8587f34SStefano Zampini #undef __FUNCT__ 4046c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 4047c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 4048c8587f34SStefano Zampini { 4049c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4050c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 405120a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 40529881197aSStefano Zampini MatNullSpace CoarseNullSpace=NULL; 405320a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 40546e683305SStefano Zampini IS coarse_is,*isarray; 40556e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 40566e683305SStefano Zampini PetscInt nis,nisdofs,nisneu; 4057f9eb5b7dSStefano Zampini PC pc_temp; 4058c8587f34SStefano Zampini PCType coarse_pc_type; 4059c8587f34SStefano Zampini KSPType coarse_ksp_type; 4060f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 40614f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 40626e683305SStefano Zampini Mat t_coarse_mat_is; 40636e683305SStefano Zampini PetscInt void_procs,ncoarse_ml,ncoarse_ds,ncoarse; 40646e683305SStefano Zampini PetscMPIInt all_procs; 406574e2c79eSStefano Zampini PetscBool csin_ml,csin_ds,csin,csin_type_simple,redist; 406668457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 406722bc73bbSStefano Zampini PetscScalar *array; 40689881197aSStefano Zampini PetscErrorCode ierr; 4069fdc09c96SStefano Zampini 4070c8587f34SStefano Zampini PetscFunctionBegin; 4071c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 407268457ee5SStefano 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 */ 4073fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 40745a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 4075fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 4076f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 4077f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 4078f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 4079fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 408051bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 408151bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 4082dc4bcba2SStefano Zampini PC pc; 4083dc4bcba2SStefano Zampini PetscBool isbddc; 4084dc4bcba2SStefano Zampini 4085dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 4086dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 4087dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 4088dc4bcba2SStefano Zampini if (isbddc) { 4089dc4bcba2SStefano Zampini ierr = PCDestroy(&pc);CHKERRQ(ierr); 4090dc4bcba2SStefano Zampini } 4091727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 4092fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4093fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 4094fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4095f4ddd8eeSStefano Zampini } 4096fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 4097fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 4098f4ddd8eeSStefano Zampini } 409970cf5478SStefano Zampini /* reset any subassembling information */ 410070cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 41016e683305SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 41026e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 4103fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 4104f4ddd8eeSStefano Zampini } 4105c8587f34SStefano Zampini 41066e683305SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 41072b510759SStefano Zampini im_active = !!(pcis->n); 41082b510759SStefano Zampini ierr = MPI_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 41096e683305SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&all_procs);CHKERRQ(ierr); 41106e683305SStefano Zampini void_procs = all_procs-active_procs; 41116e683305SStefano Zampini csin_type_simple = PETSC_TRUE; 411274e2c79eSStefano Zampini redist = PETSC_FALSE; 411322bc73bbSStefano Zampini if (pcbddc->current_level && void_procs) { 41146e683305SStefano Zampini csin_ml = PETSC_TRUE; 41156e683305SStefano Zampini ncoarse_ml = void_procs; 4116779c1cceSStefano Zampini /* it has no sense to redistribute on a set of processors larger than the number of active processes */ 4117779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < active_procs) { 41186e683305SStefano Zampini csin_ds = PETSC_TRUE; 411918a45a71SStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 412018a45a71SStefano Zampini redist = PETSC_TRUE; 412118a45a71SStefano Zampini } else { 41226e683305SStefano Zampini csin_ds = PETSC_TRUE; 4123779c1cceSStefano Zampini ncoarse_ds = active_procs; 4124779c1cceSStefano Zampini redist = PETSC_TRUE; 412518a45a71SStefano Zampini } 41266e683305SStefano Zampini } else { 41276e683305SStefano Zampini csin_ml = PETSC_FALSE; 41286e683305SStefano Zampini ncoarse_ml = all_procs; 41296e683305SStefano Zampini if (void_procs) { 41306e683305SStefano Zampini csin_ds = PETSC_TRUE; 41316e683305SStefano Zampini ncoarse_ds = void_procs; 41326e683305SStefano Zampini csin_type_simple = PETSC_FALSE; 41336e683305SStefano Zampini } else { 4134779c1cceSStefano Zampini if (pcbddc->redistribute_coarse > 0 && pcbddc->redistribute_coarse < all_procs) { 413574e2c79eSStefano Zampini csin_ds = PETSC_TRUE; 413674e2c79eSStefano Zampini ncoarse_ds = pcbddc->redistribute_coarse; 413774e2c79eSStefano Zampini redist = PETSC_TRUE; 413874e2c79eSStefano Zampini } else { 41396e683305SStefano Zampini csin_ds = PETSC_FALSE; 41406e683305SStefano Zampini ncoarse_ds = all_procs; 41416e683305SStefano Zampini } 41426e683305SStefano Zampini } 414374e2c79eSStefano Zampini } 41446e683305SStefano Zampini 41456e683305SStefano Zampini /* 41466e683305SStefano Zampini test if we can go multilevel: three conditions must be satisfied: 41476e683305SStefano Zampini - we have not exceeded the number of levels requested 41486e683305SStefano Zampini - we can actually subassemble the active processes 41496e683305SStefano Zampini - we can find a suitable number of MPI processes where we can place the subassembled problem 41506e683305SStefano Zampini */ 41516e683305SStefano Zampini multilevel_allowed = PETSC_FALSE; 41526e683305SStefano Zampini multilevel_requested = PETSC_FALSE; 41536e683305SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 41546e683305SStefano Zampini multilevel_requested = PETSC_TRUE; 41556e683305SStefano Zampini if (active_procs/pcbddc->coarsening_ratio < 2 || ncoarse_ml/pcbddc->coarsening_ratio < 2) { 4156f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_FALSE; 41572b510759SStefano Zampini } else { 4158f9eb5b7dSStefano Zampini multilevel_allowed = PETSC_TRUE; 4159c8587f34SStefano Zampini } 4160c8587f34SStefano Zampini } 41616e683305SStefano Zampini /* determine number of process partecipating to coarse solver */ 41626e683305SStefano Zampini if (multilevel_allowed) { 41636e683305SStefano Zampini ncoarse = ncoarse_ml; 41646e683305SStefano Zampini csin = csin_ml; 416558da7f69SStefano Zampini redist = PETSC_FALSE; 41666e683305SStefano Zampini } else { 41676e683305SStefano Zampini ncoarse = ncoarse_ds; 41686e683305SStefano Zampini csin = csin_ds; 41696e683305SStefano Zampini } 4170e7931f94SStefano Zampini 4171abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 4172abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 4173abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 4174abbbba34SStefano Zampini 4175abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 417622bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 417722bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 417822bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 417922bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 4180b9b85e73SStefano Zampini #if 0 4181b9b85e73SStefano Zampini { 4182b9b85e73SStefano Zampini PetscViewer viewer; 4183b9b85e73SStefano Zampini char filename[256]; 4184b9b85e73SStefano Zampini sprintf(filename,"local_coarse_mat%d.m",PetscGlobalRank); 4185b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4186b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4187b9b85e73SStefano Zampini ierr = MatView(coarse_submat_dense,viewer);CHKERRQ(ierr); 4188b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4189b9b85e73SStefano Zampini } 4190b9b85e73SStefano Zampini #endif 4191e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)pc),1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_islg,NULL,&t_coarse_mat_is);CHKERRQ(ierr); 41926e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 41936e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 41946e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4195abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 4196abbbba34SStefano Zampini 41976e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 41986e683305SStefano Zampini if (multilevel_allowed && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal) ) { /* protects from unneded computations */ 41996e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 42006e683305SStefano Zampini const PetscInt *idxs; 42016e683305SStefano Zampini ISLocalToGlobalMapping tmap; 42026e683305SStefano Zampini 42036e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 42040be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 42056e683305SStefano Zampini /* allocate space for temporary storage */ 4206854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 4207854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 42086e683305SStefano Zampini /* allocate for IS array */ 42096e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 42106e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 42116e683305SStefano Zampini nis = nisdofs + nisneu; 4212854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 42136e683305SStefano Zampini /* dofs splitting */ 42146e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 42156e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 42166e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 42176e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 42186e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 42196e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 42206e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 42216e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->ISForDofsLocal[i]),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 42226e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 42236e683305SStefano Zampini } 42246e683305SStefano Zampini /* neumann boundaries */ 42256e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 42266e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 42276e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 42286e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 42296e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 42306e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 42316e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 42326e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pcbddc->NeumannBoundariesLocal),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 42336e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 42346e683305SStefano Zampini } 42356e683305SStefano Zampini /* free memory */ 42366e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 42376e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 42386e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 42396e683305SStefano Zampini } else { 42406e683305SStefano Zampini nis = 0; 42416e683305SStefano Zampini nisdofs = 0; 42426e683305SStefano Zampini nisneu = 0; 42436e683305SStefano Zampini isarray = NULL; 42446e683305SStefano Zampini } 42456e683305SStefano Zampini /* destroy no longer needed map */ 42466e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 42476e683305SStefano Zampini 42486e683305SStefano Zampini /* restrict on coarse candidates (if needed) */ 42496e683305SStefano Zampini coarse_mat_is = NULL; 42506e683305SStefano Zampini if (csin) { 42516e683305SStefano Zampini if (!pcbddc->coarse_subassembling_init ) { /* creates subassembling init pattern if not present */ 425274e2c79eSStefano Zampini if (redist) { 425374e2c79eSStefano Zampini PetscMPIInt rank; 4254779c1cceSStefano Zampini PetscInt spc,n_spc_p1,dest[1],destsize; 425574e2c79eSStefano Zampini 425674e2c79eSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 425758da7f69SStefano Zampini spc = active_procs/ncoarse; 425858da7f69SStefano Zampini n_spc_p1 = active_procs%ncoarse; 4259779c1cceSStefano Zampini if (im_active) { 4260779c1cceSStefano Zampini destsize = 1; 426174e2c79eSStefano Zampini if (rank > n_spc_p1*(spc+1)-1) { 426274e2c79eSStefano Zampini dest[0] = n_spc_p1+(rank-(n_spc_p1*(spc+1)))/spc; 426374e2c79eSStefano Zampini } else { 426474e2c79eSStefano Zampini dest[0] = rank/(spc+1); 426574e2c79eSStefano Zampini } 426674e2c79eSStefano Zampini } else { 4267779c1cceSStefano Zampini destsize = 0; 42686e683305SStefano Zampini } 4269779c1cceSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),destsize,dest,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4270779c1cceSStefano Zampini } else if (csin_type_simple) { 42716e683305SStefano Zampini PetscMPIInt rank; 42726e683305SStefano Zampini PetscInt issize,isidx; 4273779c1cceSStefano Zampini 42746e683305SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 42756e683305SStefano Zampini if (im_active) { 42766e683305SStefano Zampini issize = 1; 42776e683305SStefano Zampini isidx = (PetscInt)rank; 42786e683305SStefano Zampini } else { 42796e683305SStefano Zampini issize = 0; 42806e683305SStefano Zampini isidx = -1; 42816e683305SStefano Zampini } 42826e683305SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),issize,&isidx,PETSC_COPY_VALUES,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 4283779c1cceSStefano Zampini } else { /* get a suitable subassembling pattern from MATIS code */ 4284b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(t_coarse_mat_is,ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling_init);CHKERRQ(ierr); 42856e683305SStefano Zampini } 4286779c1cceSStefano Zampini 4287779c1cceSStefano Zampini /* we need to shift on coarse candidates either if we are not redistributing or we are redistributing and we have enough void processes */ 4288779c1cceSStefano Zampini if (!redist || ncoarse <= void_procs) { 4289779c1cceSStefano Zampini PetscInt ncoarse_cand,tissize,*nisindices; 4290779c1cceSStefano Zampini PetscInt *coarse_candidates; 4291779c1cceSStefano Zampini const PetscInt* tisindices; 4292779c1cceSStefano Zampini 4293779c1cceSStefano Zampini /* get coarse candidates' ranks in pc communicator */ 4294779c1cceSStefano Zampini ierr = PetscMalloc1(all_procs,&coarse_candidates);CHKERRQ(ierr); 4295779c1cceSStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,coarse_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4296779c1cceSStefano Zampini for (i=0,ncoarse_cand=0;i<all_procs;i++) { 4297779c1cceSStefano Zampini if (!coarse_candidates[i]) { 4298779c1cceSStefano Zampini coarse_candidates[ncoarse_cand++]=i; 4299779c1cceSStefano Zampini } 4300779c1cceSStefano Zampini } 4301779c1cceSStefano Zampini if (ncoarse_cand < ncoarse) SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen! %d < %d",ncoarse_cand,ncoarse); 4302779c1cceSStefano Zampini 4303779c1cceSStefano Zampini 43046e683305SStefano Zampini if (pcbddc->dbg_flag) { 43056e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 43066e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init (before shift)\n");CHKERRQ(ierr); 43076e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 43086e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse candidates\n");CHKERRQ(ierr); 4309779c1cceSStefano Zampini for (i=0;i<ncoarse_cand;i++) { 43106e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"%d ",coarse_candidates[i]);CHKERRQ(ierr); 43116e683305SStefano Zampini } 43126e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"\n");CHKERRQ(ierr); 43136e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 43146e683305SStefano Zampini } 43156e683305SStefano Zampini /* shift the pattern on coarse candidates */ 43166e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->coarse_subassembling_init,&tissize);CHKERRQ(ierr); 43176e683305SStefano Zampini ierr = ISGetIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 4318854ce69bSBarry Smith ierr = PetscMalloc1(tissize,&nisindices);CHKERRQ(ierr); 43196e683305SStefano Zampini for (i=0;i<tissize;i++) nisindices[i] = coarse_candidates[tisindices[i]]; 43206e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->coarse_subassembling_init,&tisindices);CHKERRQ(ierr); 43216e683305SStefano Zampini ierr = ISGeneralSetIndices(pcbddc->coarse_subassembling_init,tissize,nisindices,PETSC_OWN_POINTER);CHKERRQ(ierr); 43226e683305SStefano Zampini ierr = PetscFree(coarse_candidates);CHKERRQ(ierr); 43236e683305SStefano Zampini } 43246e683305SStefano Zampini if (pcbddc->dbg_flag) { 43256e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 43266e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init\n");CHKERRQ(ierr); 43276e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling_init,pcbddc->dbg_viewer);CHKERRQ(ierr); 43286e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 43296e683305SStefano Zampini } 4330779c1cceSStefano Zampini } 43316e683305SStefano Zampini /* get temporary coarse mat in IS format restricted on coarse procs (plus additional index sets of isarray) */ 433253a05cb3SStefano Zampini if (multilevel_allowed) { /* we need to keep tracking of void processes for future placements */ 433353a05cb3SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,PETSC_FALSE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 433453a05cb3SStefano Zampini } else { /* this is the last level, so use just receiving processes in subcomm */ 433553a05cb3SStefano Zampini ierr = MatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling_init,0,PETSC_TRUE,PETSC_TRUE,MAT_INITIAL_MATRIX,&coarse_mat_is,nis,isarray);CHKERRQ(ierr); 433653a05cb3SStefano Zampini } 43376e683305SStefano Zampini } else { 43386e683305SStefano Zampini if (pcbddc->dbg_flag) { 43396e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 43406e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Subassembling pattern init not needed\n");CHKERRQ(ierr); 43416e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 43426e683305SStefano Zampini } 43436e683305SStefano Zampini ierr = PetscObjectReference((PetscObject)t_coarse_mat_is);CHKERRQ(ierr); 43446e683305SStefano Zampini coarse_mat_is = t_coarse_mat_is; 43456e683305SStefano Zampini } 43466e683305SStefano Zampini 43476e683305SStefano Zampini /* create local to global scatters for coarse problem */ 434868457ee5SStefano Zampini if (compute_vecs) { 43496e683305SStefano Zampini PetscInt lrows; 43506e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 43516e683305SStefano Zampini if (coarse_mat_is) { 43526e683305SStefano Zampini ierr = MatGetLocalSize(coarse_mat_is,&lrows,NULL);CHKERRQ(ierr); 43536e683305SStefano Zampini } else { 43546e683305SStefano Zampini lrows = 0; 43556e683305SStefano Zampini } 43566e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 43576e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 43586e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 43596e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 43606e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 43616e683305SStefano Zampini } 43626e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 43636e683305SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 4364c8587f34SStefano Zampini 4365f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 4366f9eb5b7dSStefano Zampini if (multilevel_allowed) { 4367f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 4368f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 4369f9eb5b7dSStefano Zampini } else { 4370f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 4371f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 4372c8587f34SStefano Zampini } 4373c8587f34SStefano Zampini 43746e683305SStefano Zampini /* print some info if requested */ 43756e683305SStefano Zampini if (pcbddc->dbg_flag) { 43766e683305SStefano Zampini if (!multilevel_allowed) { 43776e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 43786e683305SStefano Zampini if (multilevel_requested) { 43796e683305SStefano 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); 43806e683305SStefano Zampini } else if (pcbddc->max_levels) { 43816e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 43826e683305SStefano Zampini } 43836e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 43846e683305SStefano Zampini } 43856e683305SStefano Zampini } 43866e683305SStefano Zampini 4387f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 43886e683305SStefano Zampini if (coarse_mat_is) { 43896e683305SStefano Zampini MatReuse coarse_mat_reuse; 43906a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 43916e683305SStefano Zampini if (pcbddc->dbg_flag) { 43926e683305SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat_is)); 43936e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 43946e683305SStefano Zampini } 4395f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 4396312be037SStefano Zampini char prefix[256],str_level[16]; 4397e604994aSStefano Zampini size_t len; 43986e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat_is),&pcbddc->coarse_ksp);CHKERRQ(ierr); 4399422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 4400c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 4401f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 44025f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat_is,coarse_mat_is);CHKERRQ(ierr); 4403c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 44046e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 4405c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 4406c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4407e604994aSStefano Zampini /* prefix */ 4408e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 4409e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4410e604994aSStefano Zampini if (!pcbddc->current_level) { 4411e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4412e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 4413c8587f34SStefano Zampini } else { 4414e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4415312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4416312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 441734d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4418312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4419e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 4420e604994aSStefano Zampini } 4421e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 44223e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 44233e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 44243e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 44253e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 4426f9eb5b7dSStefano Zampini /* allow user customization */ 4427f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 44283e3c6dadSStefano Zampini } 44293e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 443051bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 44313e3c6dadSStefano Zampini if (nisdofs) { 44323e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 44333e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 44343e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 44353e3c6dadSStefano Zampini } 44363e3c6dadSStefano Zampini } 44373e3c6dadSStefano Zampini if (nisneu) { 44383e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 44393e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 4440312be037SStefano Zampini } 4441f9eb5b7dSStefano Zampini 4442f9eb5b7dSStefano Zampini /* get some info after set from options */ 4443f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 4444f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 44454f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 44466e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 4447f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 4448f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 4449f9eb5b7dSStefano Zampini } 445039f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 44514f3a063dSStefano Zampini if (isredundant) { 44524f3a063dSStefano Zampini KSP inner_ksp; 44534f3a063dSStefano Zampini PC inner_pc; 44544f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 44554f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 44564f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 44574f3a063dSStefano Zampini } 4458f9eb5b7dSStefano Zampini 4459f9eb5b7dSStefano Zampini /* assemble coarse matrix */ 4460fa7f1dd8SStefano Zampini if (coarse_reuse) { 446181d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 4462fa7f1dd8SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 44636e683305SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 4464fa7f1dd8SStefano Zampini } else { 44656e683305SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 4466fa7f1dd8SStefano Zampini } 4467c8587f34SStefano Zampini if (isbddc || isnn) { 446822bc73bbSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 446970cf5478SStefano Zampini if (!pcbddc->coarse_subassembling) { /* subassembling info is not present */ 4470b0c7d250SStefano Zampini ierr = MatISGetSubassemblingPattern(coarse_mat_is,active_procs/pcbddc->coarsening_ratio,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 447122b6e8a2SStefano Zampini if (pcbddc->dbg_flag) { 44726e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 44736e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Subassembling pattern\n");CHKERRQ(ierr); 44746e683305SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,dbg_viewer);CHKERRQ(ierr); 44756e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 447622b6e8a2SStefano Zampini } 447770cf5478SStefano Zampini } 447853a05cb3SStefano Zampini ierr = MatISSubassemble(coarse_mat_is,pcbddc->coarse_subassembling,0,PETSC_FALSE,PETSC_FALSE,coarse_mat_reuse,&coarse_mat,0,NULL);CHKERRQ(ierr); 447970cf5478SStefano Zampini } else { 448022bc73bbSStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 448122bc73bbSStefano Zampini coarse_mat = coarse_mat_is; 448222bc73bbSStefano Zampini } 448322bc73bbSStefano Zampini } else { 44842e1e5fa4SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 4485c8587f34SStefano Zampini } 4486c8587f34SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 4487c8587f34SStefano Zampini 44883301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 44895a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 44903301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 44913301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 44923301b35fSStefano Zampini } 44933301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 44943301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 44953301b35fSStefano Zampini } 44963301b35fSStefano Zampini if (pc->pmat->spd_set) { 44973301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 44983301b35fSStefano Zampini } 44996e683305SStefano Zampini /* set operators */ 45005f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 45016e683305SStefano Zampini if (pcbddc->dbg_flag) { 45026e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 45036e683305SStefano Zampini } 45046e683305SStefano Zampini } else { /* processes non partecipating to coarse solver (if any) */ 45056e683305SStefano Zampini coarse_mat = 0; 45066e683305SStefano Zampini } 45076e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 4508b9b85e73SStefano Zampini #if 0 4509b9b85e73SStefano Zampini { 4510b9b85e73SStefano Zampini PetscViewer viewer; 4511b9b85e73SStefano Zampini char filename[256]; 4512b9b85e73SStefano Zampini sprintf(filename,"coarse_mat.m"); 4513b9b85e73SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,filename,&viewer);CHKERRQ(ierr); 4514b9b85e73SStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4515b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 4516b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4517b9b85e73SStefano Zampini } 4518b9b85e73SStefano Zampini #endif 4519c8587f34SStefano Zampini 4520c8587f34SStefano Zampini /* Compute coarse null space (special handling by BDDC only) */ 4521298c0119SStefano Zampini #if 0 4522c8587f34SStefano Zampini if (pcbddc->NullSpace) { 4523c8587f34SStefano Zampini ierr = PCBDDCNullSpaceAssembleCoarse(pc,coarse_mat,&CoarseNullSpace);CHKERRQ(ierr); 452498a51de6SStefano Zampini } 4525298c0119SStefano Zampini #endif 452698a51de6SStefano Zampini 452798a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 452898a51de6SStefano Zampini Vec crhs,csol; 452998a51de6SStefano Zampini PetscBool ispreonly; 453004708bb6SStefano Zampini 453198a51de6SStefano Zampini if (CoarseNullSpace) { 4532c8587f34SStefano Zampini if (isbddc) { 4533c8587f34SStefano Zampini ierr = PCBDDCSetNullSpace(pc_temp,CoarseNullSpace);CHKERRQ(ierr); 4534c8587f34SStefano Zampini } else { 45355fa7ec2dSBarry Smith ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 4536c8587f34SStefano Zampini } 4537c8587f34SStefano Zampini } 4538f9eb5b7dSStefano Zampini /* setup coarse ksp */ 4539f9eb5b7dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 4540f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 4541f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 45426e683305SStefano Zampini /* hack */ 4543f347579bSStefano Zampini if (!csol) { 45442a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 4545f9eb5b7dSStefano Zampini } 4546f347579bSStefano Zampini if (!crhs) { 45472a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 4548f347579bSStefano Zampini } 4549cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 4550cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 45516e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 4552c8587f34SStefano Zampini KSP check_ksp; 45532b510759SStefano Zampini KSPType check_ksp_type; 4554c8587f34SStefano Zampini PC check_pc; 45556e683305SStefano Zampini Vec check_vec,coarse_vec; 45566a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 45572b510759SStefano Zampini PetscInt its; 45586e683305SStefano Zampini PetscBool compute_eigs; 45596e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 45606e683305SStefano Zampini PetscInt neigs; 45618e185a42SStefano Zampini const char *prefix; 4562c8587f34SStefano Zampini 45632b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 45646e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 4565422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 456623ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 4567f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 45682b510759SStefano Zampini if (ispreonly) { 45692b510759SStefano Zampini check_ksp_type = KSPPREONLY; 45706e683305SStefano Zampini compute_eigs = PETSC_FALSE; 45712b510759SStefano Zampini } else { 4572cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 45736e683305SStefano Zampini compute_eigs = PETSC_TRUE; 4574c8587f34SStefano Zampini } 4575c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 45766e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 45776e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 45786e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 4579a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 4580a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 4581a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 4582a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 4583c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 4584c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 4585c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 4586c8587f34SStefano Zampini /* create random vec */ 45876e683305SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&coarse_vec);CHKERRQ(ierr); 45886e683305SStefano Zampini ierr = VecDuplicate(coarse_vec,&check_vec);CHKERRQ(ierr); 4589c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 4590c8587f34SStefano Zampini if (CoarseNullSpace) { 4591c8587f34SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,check_vec);CHKERRQ(ierr); 4592c8587f34SStefano Zampini } 45936e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 4594c8587f34SStefano Zampini /* solve coarse problem */ 45956e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 4596c8587f34SStefano Zampini if (CoarseNullSpace) { 45976e683305SStefano Zampini ierr = MatNullSpaceRemove(CoarseNullSpace,coarse_vec);CHKERRQ(ierr); 4598c8587f34SStefano Zampini } 4599cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 46006e683305SStefano Zampini if (compute_eigs) { 4601854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 4602854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 46036e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 46046e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 46056e683305SStefano Zampini lambda_min = eigs_r[0]; 46066e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 46076e683305SStefano Zampini if (lambda_max>lambda_min) { 4608cbcc2c2aSStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max,lambda_min);CHKERRQ(ierr); 4609cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 4610cbcc2c2aSStefano Zampini } 4611c8587f34SStefano Zampini } 4612c8587f34SStefano Zampini } 4613cbcc2c2aSStefano Zampini 4614c8587f34SStefano Zampini /* check coarse problem residual error */ 46156e683305SStefano Zampini if (pcbddc->dbg_flag) { 46166e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 46176e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 46186e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 4619c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 46206e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 46216e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 4622c8587f34SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 4623779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 46246e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 46256e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 46266e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 46276e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 46286e683305SStefano Zampini if (compute_eigs) { 46296e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 4630deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 4631c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 46326e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 46336e683305SStefano 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); 46346e683305SStefano Zampini for (i=0;i<neigs;i++) { 46356e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 4636c8587f34SStefano Zampini } 46376e683305SStefano Zampini } 46386e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 46396e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 46406e683305SStefano Zampini } 4641c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 46426e683305SStefano Zampini if (compute_eigs) { 46436e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 46446e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 4645c8587f34SStefano Zampini } 46466e683305SStefano Zampini } 46476e683305SStefano Zampini } 4648cbcc2c2aSStefano Zampini /* print additional info */ 4649cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 46506e683305SStefano Zampini /* waits until all processes reaches this point */ 46516e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 4652cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 4653cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4654cbcc2c2aSStefano Zampini } 4655cbcc2c2aSStefano Zampini 46562b510759SStefano Zampini /* free memory */ 4657c8587f34SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 4658fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 4659c8587f34SStefano Zampini PetscFunctionReturn(0); 4660c8587f34SStefano Zampini } 4661674ae819SStefano Zampini 4662f34684f1SStefano Zampini #undef __FUNCT__ 4663f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 4664f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 4665f34684f1SStefano Zampini { 4666f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4667f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 4668f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4669dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 4670dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 467173be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 4672dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 4673f34684f1SStefano Zampini PetscErrorCode ierr; 4674f34684f1SStefano Zampini 4675f34684f1SStefano Zampini PetscFunctionBegin; 4676f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 46770e6343abSStefano Zampini if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) { 46780e6343abSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 4679727cdba6SStefano Zampini } 4680dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 46813bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 4682dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 4683dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 4684dc456d91SStefano Zampini ierr = PCBDDCSubsetNumbering(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 4685dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 4686dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 4687dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 46880e6343abSStefano Zampini if (local_size != pcbddc->local_primal_size) { 46890e6343abSStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %d != %d",local_size,pcbddc->local_primal_size); 46900e6343abSStefano Zampini } 4691dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 4692dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 4693dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 4694dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 4695dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 4696f34684f1SStefano Zampini 4697f34684f1SStefano Zampini /* check numbering */ 4698f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 4699f34684f1SStefano Zampini PetscScalar coarsesum,*array; 4700dc456d91SStefano Zampini PetscInt i; 4701b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 4702f34684f1SStefano Zampini 4703f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4704f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4705f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 47060fccc4e9SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 4707f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 4708f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 4709727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 4710f34684f1SStefano Zampini } 4711f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 4712f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 4713f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4714e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4715e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4716e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4717e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4718f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4719f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 4720f34684f1SStefano Zampini if (array[i] == 1.0) { 4721b9b85e73SStefano Zampini set_error = PETSC_TRUE; 4722f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d: local index %d owned by a single process!\n",PetscGlobalRank,i);CHKERRQ(ierr); 4723f34684f1SStefano Zampini } 4724f34684f1SStefano Zampini } 4725b9b85e73SStefano Zampini ierr = MPI_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4726f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4727f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 4728f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 4729f34684f1SStefano Zampini } 4730f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 4731f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 4732e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4733e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4734f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 4735f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 4736b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 4737ca8b9ea9SStefano Zampini PetscInt *gidxs; 4738ca8b9ea9SStefano Zampini 4739ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 47403bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 4741f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 4742f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4743f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 4744f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 47454bc2dc4bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_primal_indices[%d]=%d (%d,%d)\n",i,local_primal_indices[i],pcbddc->primal_indices_local_idxs[i],gidxs[i]);CHKERRQ(ierr); 4746f34684f1SStefano Zampini } 4747f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4748ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 4749f34684f1SStefano Zampini } 4750f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4751302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 4752f34684f1SStefano Zampini } 47538bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 4754f34684f1SStefano Zampini /* get back data */ 4755f34684f1SStefano Zampini *coarse_size_n = coarse_size; 4756f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 4757674ae819SStefano Zampini PetscFunctionReturn(0); 4758674ae819SStefano Zampini } 4759674ae819SStefano Zampini 4760e456f2a8SStefano Zampini #undef __FUNCT__ 4761e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 4762a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 4763e456f2a8SStefano Zampini { 4764e456f2a8SStefano Zampini IS localis_t; 4765a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 4766e456f2a8SStefano Zampini PetscScalar *vals; 4767e456f2a8SStefano Zampini PetscErrorCode ierr; 4768e456f2a8SStefano Zampini 4769e456f2a8SStefano Zampini PetscFunctionBegin; 4770a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 4771e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 4772854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 4773e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 4774e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 4775a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 4776a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 47771035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 4778a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 47791035eff8SStefano Zampini } 4780a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 4781e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 4782e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 4783a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 4784a7dc3881SStefano Zampini /* now compute set in local ordering */ 4785a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4786a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4787a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 4788a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 4789a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 4790ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 4791e456f2a8SStefano Zampini lsize++; 4792e456f2a8SStefano Zampini } 4793e456f2a8SStefano Zampini } 4794854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 4795a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 4796ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 4797e456f2a8SStefano Zampini idxs[lsize++] = i; 4798e456f2a8SStefano Zampini } 4799e456f2a8SStefano Zampini } 4800a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 4801a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 4802e456f2a8SStefano Zampini *localis = localis_t; 4803e456f2a8SStefano Zampini PetscFunctionReturn(0); 4804e456f2a8SStefano Zampini } 4805906d46d4SStefano Zampini 4806906d46d4SStefano Zampini /* the next two functions will be called in KSPMatMult if a change of basis has been requested */ 4807906d46d4SStefano Zampini #undef __FUNCT__ 4808906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMult_Private" 4809906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMult_Private(Mat A, Vec x, Vec y) 4810906d46d4SStefano Zampini { 4811906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4812906d46d4SStefano Zampini PetscErrorCode ierr; 4813906d46d4SStefano Zampini 4814906d46d4SStefano Zampini PetscFunctionBegin; 4815906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 4816906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 4817906d46d4SStefano Zampini ierr = MatMult(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 4818906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 4819906d46d4SStefano Zampini PetscFunctionReturn(0); 4820906d46d4SStefano Zampini } 4821906d46d4SStefano Zampini 4822906d46d4SStefano Zampini #undef __FUNCT__ 4823906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCMatMultTranspose_Private" 4824906d46d4SStefano Zampini static PetscErrorCode PCBDDCMatMultTranspose_Private(Mat A, Vec x, Vec y) 4825906d46d4SStefano Zampini { 4826906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 4827906d46d4SStefano Zampini PetscErrorCode ierr; 4828906d46d4SStefano Zampini 4829906d46d4SStefano Zampini PetscFunctionBegin; 4830906d46d4SStefano Zampini ierr = MatShellGetContext(A,&change_ctx);CHKERRQ(ierr); 4831906d46d4SStefano Zampini ierr = MatMult(change_ctx->global_change,x,change_ctx->work[0]);CHKERRQ(ierr); 4832906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->original_mat,change_ctx->work[0],change_ctx->work[1]);CHKERRQ(ierr); 4833906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,change_ctx->work[1],y);CHKERRQ(ierr); 4834906d46d4SStefano Zampini PetscFunctionReturn(0); 4835906d46d4SStefano Zampini } 4836b96c3477SStefano Zampini 4837b96c3477SStefano Zampini #undef __FUNCT__ 4838b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 483908122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 4840b96c3477SStefano Zampini { 4841a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 4842b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 4843b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4844a64f4aa4SStefano Zampini Mat S_j; 4845b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 4846b96c3477SStefano Zampini PetscBool free_used_adj; 4847b96c3477SStefano Zampini PetscErrorCode ierr; 4848b96c3477SStefano Zampini 4849b96c3477SStefano Zampini PetscFunctionBegin; 4850b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 4851b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 485208122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 4853b96c3477SStefano Zampini used_xadj = NULL; 4854b96c3477SStefano Zampini used_adjncy = NULL; 4855b96c3477SStefano Zampini } else { 485608122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 485708122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 485808122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 485908122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 4860b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 4861b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 4862b96c3477SStefano Zampini } else { 48632fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 4864b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 4865b96c3477SStefano Zampini PetscInt nvtxs; 4866b96c3477SStefano Zampini 48672fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 48682fffb893SStefano Zampini if (flg_row) { 4869b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 4870b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 4871b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 4872b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 48732fffb893SStefano Zampini } else { 48742fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 48752fffb893SStefano Zampini used_xadj = NULL; 48762fffb893SStefano Zampini used_adjncy = NULL; 48772fffb893SStefano Zampini } 48782fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4879b96c3477SStefano Zampini } 4880b96c3477SStefano Zampini } 4881d5574798SStefano Zampini 4882d5574798SStefano Zampini /* setup sub_schurs data */ 4883a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 4884a64f4aa4SStefano Zampini if (!sub_schurs->use_mumps) { 4885a64f4aa4SStefano Zampini /* pcbddc->ksp_D up to date only if not using MUMPS */ 4886a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 4887*06a4e24aSStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,NULL,S_j,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,pcbddc->faster_deluxe,pcbddc->adaptive_selection,PETSC_FALSE,PETSC_FALSE);CHKERRQ(ierr); 4888a64f4aa4SStefano Zampini } else { 48896816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 489004708bb6SStefano Zampini PetscBool isseqaij; 48915feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 48925feab87aSStefano Zampini PetscInt n_vertices; 48935feab87aSStefano Zampini 48945feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 48952034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 48965feab87aSStefano Zampini } 489704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 489804708bb6SStefano Zampini if (!isseqaij) { 489904708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 490004708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 490104708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 490204708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 490304708bb6SStefano Zampini } else { 490404708bb6SStefano Zampini ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_REUSE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 490504708bb6SStefano Zampini } 490604708bb6SStefano Zampini } 4907*06a4e24aSStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,pcbddc->local_mat,S_j,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,pcbddc->faster_deluxe,pcbddc->adaptive_selection,reuse_solvers,pcbddc->benign_saddle_point);CHKERRQ(ierr); 4908a64f4aa4SStefano Zampini } 4909a64f4aa4SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 4910b96c3477SStefano Zampini 4911b96c3477SStefano Zampini /* free adjacency */ 4912b96c3477SStefano Zampini if (free_used_adj) { 4913b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 4914b96c3477SStefano Zampini } 4915b96c3477SStefano Zampini PetscFunctionReturn(0); 4916b96c3477SStefano Zampini } 4917b96c3477SStefano Zampini 4918b96c3477SStefano Zampini #undef __FUNCT__ 4919b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 492008122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 4921b96c3477SStefano Zampini { 4922b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 4923b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 4924b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 4925b96c3477SStefano Zampini PCBDDCGraph graph; 4926b96c3477SStefano Zampini PetscErrorCode ierr; 4927b96c3477SStefano Zampini 4928b96c3477SStefano Zampini PetscFunctionBegin; 4929b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 493008122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 49313301b35fSStefano Zampini IS verticesIS,verticescomm; 49323301b35fSStefano Zampini PetscInt vsize,*idxs; 4933b96c3477SStefano Zampini 4934b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 49353301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 49363301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 49373301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 49383301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 49393301b35fSStefano Zampini ierr = ISDestroy(&verticesIS);CHKERRQ(ierr); 4940b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 49417fb0e2dbSStefano Zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global);CHKERRQ(ierr); 49423301b35fSStefano Zampini ierr = PCBDDCGraphSetUp(graph,0,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 49433301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 4944b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 4945b96c3477SStefano Zampini /* 4946b96c3477SStefano Zampini if (pcbddc->dbg_flag) { 4947b96c3477SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 4948b96c3477SStefano Zampini } 4949b96c3477SStefano Zampini */ 4950b96c3477SStefano Zampini } else { 4951b96c3477SStefano Zampini graph = pcbddc->mat_graph; 4952b96c3477SStefano Zampini } 4953b96c3477SStefano Zampini 4954b96c3477SStefano Zampini /* sub_schurs init */ 4955a64f4aa4SStefano Zampini ierr = PCBDDCSubSchursInit(sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap);CHKERRQ(ierr); 4956a64f4aa4SStefano Zampini 4957b96c3477SStefano Zampini /* free graph struct */ 495808122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 4959b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 4960b96c3477SStefano Zampini } 4961b96c3477SStefano Zampini PetscFunctionReturn(0); 4962b96c3477SStefano Zampini } 4963