134a97f8cSStefano Zampini #include <../src/ksp/pc/impls/bddc/bddc.h> 234a97f8cSStefano Zampini #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 334a97f8cSStefano Zampini 434a97f8cSStefano Zampini static PetscErrorCode PCBDDCAdjGetNextLayer_Private(PetscInt*,PetscInt,PetscBT,PetscInt*,PetscInt*,PetscInt*); 534a97f8cSStefano Zampini 634a97f8cSStefano Zampini #undef __FUNCT__ 734a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursCreate" 834a97f8cSStefano Zampini PetscErrorCode PCBDDCSubSchursCreate(PCBDDCSubSchurs *sub_schurs) 934a97f8cSStefano Zampini { 1034a97f8cSStefano Zampini PCBDDCSubSchurs schurs_ctx; 1134a97f8cSStefano Zampini PetscErrorCode ierr; 1234a97f8cSStefano Zampini 1334a97f8cSStefano Zampini PetscFunctionBegin; 1434a97f8cSStefano Zampini ierr = PetscNew(&schurs_ctx);CHKERRQ(ierr); 1534a97f8cSStefano Zampini *sub_schurs = schurs_ctx; 1634a97f8cSStefano Zampini PetscFunctionReturn(0); 1734a97f8cSStefano Zampini } 1834a97f8cSStefano Zampini 1934a97f8cSStefano Zampini #undef __FUNCT__ 2034a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursDestroy" 2134a97f8cSStefano Zampini PetscErrorCode PCBDDCSubSchursDestroy(PCBDDCSubSchurs *sub_schurs) 2234a97f8cSStefano Zampini { 2334a97f8cSStefano Zampini PetscErrorCode ierr; 2434a97f8cSStefano Zampini 2534a97f8cSStefano Zampini PetscFunctionBegin; 2634a97f8cSStefano Zampini ierr = PCBDDCSubSchursReset(*sub_schurs);CHKERRQ(ierr); 2734a97f8cSStefano Zampini ierr = PetscFree(*sub_schurs);CHKERRQ(ierr); 2834a97f8cSStefano Zampini PetscFunctionReturn(0); 2934a97f8cSStefano Zampini } 3034a97f8cSStefano Zampini 3134a97f8cSStefano Zampini #undef __FUNCT__ 3234a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursReset" 3334a97f8cSStefano Zampini PetscErrorCode PCBDDCSubSchursReset(PCBDDCSubSchurs sub_schurs) 3434a97f8cSStefano Zampini { 3534a97f8cSStefano Zampini PetscInt i; 3634a97f8cSStefano Zampini PetscErrorCode ierr; 3734a97f8cSStefano Zampini 3834a97f8cSStefano Zampini PetscFunctionBegin; 3934a97f8cSStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4034a97f8cSStefano Zampini ierr = ISDestroy(&sub_schurs->is_AEj_I[i]);CHKERRQ(ierr); 4134a97f8cSStefano Zampini ierr = ISDestroy(&sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 4234a97f8cSStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej[i]);CHKERRQ(ierr); 4334a97f8cSStefano Zampini ierr = VecDestroy(&sub_schurs->work1[i]);CHKERRQ(ierr); 4434a97f8cSStefano Zampini ierr = VecDestroy(&sub_schurs->work2[i]);CHKERRQ(ierr); 4534a97f8cSStefano Zampini } 4634a97f8cSStefano Zampini ierr = PetscFree5(sub_schurs->is_AEj_I,sub_schurs->is_AEj_B,sub_schurs->S_Ej,sub_schurs->work1,sub_schurs->work2);CHKERRQ(ierr); 4734a97f8cSStefano Zampini sub_schurs->n_subs = 0; 4834a97f8cSStefano Zampini PetscFunctionReturn(0); 4934a97f8cSStefano Zampini } 5034a97f8cSStefano Zampini 5134a97f8cSStefano Zampini #undef __FUNCT__ 5234a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCAdjGetNextLayer_Private" 53*2a155e38SStefano Zampini PETSC_STATIC_INLINE PetscErrorCode PCBDDCAdjGetNextLayer_Private(PetscInt* queue_tip,PetscInt n_prev,PetscBT touched,PetscInt* xadj,PetscInt* adjncy,PetscInt* n_added) 5434a97f8cSStefano Zampini { 5534a97f8cSStefano Zampini PetscInt i,j,n; 5634a97f8cSStefano Zampini PetscErrorCode ierr; 5734a97f8cSStefano Zampini 5834a97f8cSStefano Zampini PetscFunctionBegin; 5934a97f8cSStefano Zampini n = 0; 6034a97f8cSStefano Zampini for (i=-n_prev;i<0;i++) { 6134a97f8cSStefano Zampini PetscInt start_dof = queue_tip[i]; 6234a97f8cSStefano Zampini for (j=xadj[start_dof];j<xadj[start_dof+1];j++) { 6334a97f8cSStefano Zampini PetscInt dof = adjncy[j]; 6434a97f8cSStefano Zampini if (!PetscBTLookup(touched,dof)) { 6534a97f8cSStefano Zampini ierr = PetscBTSet(touched,dof);CHKERRQ(ierr); 6634a97f8cSStefano Zampini queue_tip[n] = dof; 6734a97f8cSStefano Zampini n++; 6834a97f8cSStefano Zampini } 6934a97f8cSStefano Zampini } 7034a97f8cSStefano Zampini } 7134a97f8cSStefano Zampini *n_added = n; 7234a97f8cSStefano Zampini PetscFunctionReturn(0); 7334a97f8cSStefano Zampini } 7434a97f8cSStefano Zampini 7534a97f8cSStefano Zampini #undef __FUNCT__ 7634a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursSetUp" 777821e9e7SStefano Zampini PetscErrorCode PCBDDCSubSchursSetUp(PCBDDCSubSchurs sub_schurs, Mat S, IS is_A_I, IS is_A_B, PetscInt ncc, IS is_cc[], PetscInt xadj[], PetscInt adjncy[], PetscInt nlayers) 7834a97f8cSStefano Zampini { 7934a97f8cSStefano Zampini Mat A_II,A_IB,A_BI,A_BB; 80*2a155e38SStefano Zampini Mat AE_II,*AE_IE,*AE_EI,*AE_EE; 81*2a155e38SStefano Zampini IS is_I,*is_subset_B; 82*2a155e38SStefano Zampini ISLocalToGlobalMapping BtoNmap; 83*2a155e38SStefano Zampini PetscInt i; 8434a97f8cSStefano Zampini PetscBool is_sorted; 8534a97f8cSStefano Zampini PetscErrorCode ierr; 8634a97f8cSStefano Zampini 8734a97f8cSStefano Zampini PetscFunctionBegin; 8834a97f8cSStefano Zampini ierr = ISSorted(is_A_I,&is_sorted);CHKERRQ(ierr); 8934a97f8cSStefano Zampini if (!is_sorted) { 9034a97f8cSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)is_A_I),PETSC_ERR_PLIB,"IS for I dofs should be shorted"); 9134a97f8cSStefano Zampini } 9234a97f8cSStefano Zampini ierr = ISSorted(is_A_B,&is_sorted);CHKERRQ(ierr); 9334a97f8cSStefano Zampini if (!is_sorted) { 9434a97f8cSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)is_A_B),PETSC_ERR_PLIB,"IS for B dofs should be shorted"); 9534a97f8cSStefano Zampini } 9634a97f8cSStefano Zampini 9734a97f8cSStefano Zampini /* get Schur complement matrices */ 9834a97f8cSStefano Zampini ierr = MatSchurComplementGetSubMatrices(S,&A_II,NULL,&A_IB,&A_BI,&A_BB);CHKERRQ(ierr); 9934a97f8cSStefano Zampini 10034a97f8cSStefano Zampini /* allocate space for schur complements */ 10134a97f8cSStefano Zampini ierr = PetscMalloc5(ncc,&sub_schurs->is_AEj_I,ncc,&sub_schurs->is_AEj_B,ncc,&sub_schurs->S_Ej,ncc,&sub_schurs->work1,ncc,&sub_schurs->work2);CHKERRQ(ierr); 102*2a155e38SStefano Zampini ierr = PetscMalloc4(ncc,&is_subset_B,ncc,&AE_IE,ncc,&AE_EI,ncc,&AE_EE);CHKERRQ(ierr); 10334a97f8cSStefano Zampini sub_schurs->n_subs = ncc; 10434a97f8cSStefano Zampini 105*2a155e38SStefano Zampini /* maps */ 106*2a155e38SStefano Zampini if (sub_schurs->n_subs && nlayers >= 0 && xadj != NULL && adjncy != NULL) { /* Interior problems can be different from the original one */ 107*2a155e38SStefano Zampini ISLocalToGlobalMapping ItoNmap; 108*2a155e38SStefano Zampini PetscBT touched; 10934a97f8cSStefano Zampini const PetscInt* idx_B; 110*2a155e38SStefano Zampini PetscInt n_I,n_B,n_local_dofs,n_prev_added,j,layer,*local_numbering; 111*2a155e38SStefano Zampini 112*2a155e38SStefano Zampini /* get sizes */ 113*2a155e38SStefano Zampini ierr = ISGetLocalSize(is_A_I,&n_I);CHKERRQ(ierr); 114*2a155e38SStefano Zampini ierr = ISGetLocalSize(is_A_B,&n_B);CHKERRQ(ierr); 115*2a155e38SStefano Zampini 116*2a155e38SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_A_I,&ItoNmap);CHKERRQ(ierr); 117*2a155e38SStefano Zampini ierr = PetscMalloc1(n_I+n_B,&local_numbering);CHKERRQ(ierr); 118*2a155e38SStefano Zampini ierr = PetscBTCreate(n_I+n_B,&touched);CHKERRQ(ierr); 119*2a155e38SStefano Zampini ierr = PetscBTMemzero(n_I+n_B,touched);CHKERRQ(ierr); 12034a97f8cSStefano Zampini 12134a97f8cSStefano Zampini /* all boundary dofs must be skipped when adding layers */ 12234a97f8cSStefano Zampini ierr = ISGetIndices(is_A_B,&idx_B);CHKERRQ(ierr); 12334a97f8cSStefano Zampini for (j=0;j<n_B;j++) { 12434a97f8cSStefano Zampini ierr = PetscBTSet(touched,idx_B[j]);CHKERRQ(ierr); 12534a97f8cSStefano Zampini } 126*2a155e38SStefano Zampini ierr = PetscMemcpy(local_numbering,idx_B,n_B*sizeof(PetscInt));CHKERRQ(ierr); 12734a97f8cSStefano Zampini ierr = ISRestoreIndices(is_A_B,&idx_B);CHKERRQ(ierr); 12834a97f8cSStefano Zampini 12934a97f8cSStefano Zampini /* add next layers of dofs */ 130*2a155e38SStefano Zampini n_local_dofs = n_B; 131*2a155e38SStefano Zampini n_prev_added = n_B; 13234a97f8cSStefano Zampini for (layer=0;layer<nlayers;layer++) { 13334a97f8cSStefano Zampini PetscInt n_added; 134*2a155e38SStefano Zampini if (n_local_dofs == n_I+n_B) break; 135*2a155e38SStefano Zampini if (n_local_dofs > n_I+n_B) { 136*2a155e38SStefano Zampini SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error querying layer %d. Out of bound access (%d > %d)",layer,n_local_dofs,n_I+n_B); 13734a97f8cSStefano Zampini } 13834a97f8cSStefano Zampini ierr = PCBDDCAdjGetNextLayer_Private(local_numbering+n_local_dofs,n_prev_added,touched,xadj,adjncy,&n_added);CHKERRQ(ierr); 13934a97f8cSStefano Zampini n_prev_added = n_added; 14034a97f8cSStefano Zampini n_local_dofs += n_added; 1419b0e569cSStefano Zampini if (!n_added) break; 14234a97f8cSStefano Zampini } 143*2a155e38SStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 14434a97f8cSStefano Zampini 14534a97f8cSStefano Zampini /* IS for I dofs in original numbering and in I numbering */ 146*2a155e38SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)ItoNmap),n_local_dofs-n_B,local_numbering+n_B,PETSC_COPY_VALUES,&sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 147*2a155e38SStefano Zampini ierr = PetscFree(local_numbering);CHKERRQ(ierr); 148*2a155e38SStefano Zampini ierr = ISSort(sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 149*2a155e38SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(ItoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_I[0],&is_I);CHKERRQ(ierr); 150*2a155e38SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&ItoNmap);CHKERRQ(ierr); 15134a97f8cSStefano Zampini 15234a97f8cSStefano Zampini /* II block */ 15334a97f8cSStefano Zampini ierr = MatGetSubMatrix(A_II,is_I,is_I,MAT_INITIAL_MATRIX,&AE_II);CHKERRQ(ierr); 154*2a155e38SStefano Zampini } else { 155*2a155e38SStefano Zampini PetscInt n_I; 156*2a155e38SStefano Zampini 15734a97f8cSStefano Zampini /* IS for I dofs in original numbering */ 15834a97f8cSStefano Zampini ierr = PetscObjectReference((PetscObject)is_A_I);CHKERRQ(ierr); 159*2a155e38SStefano Zampini sub_schurs->is_AEj_I[0] = is_A_I; 16034a97f8cSStefano Zampini 161*2a155e38SStefano Zampini /* IS for I dofs in I numbering (strided 1) */ 162*2a155e38SStefano Zampini ierr = ISGetSize(is_A_I,&n_I);CHKERRQ(ierr); 16334a97f8cSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is_A_I),n_I,0,1,&is_I);CHKERRQ(ierr); 16434a97f8cSStefano Zampini 16534a97f8cSStefano Zampini /* II block is the same */ 16634a97f8cSStefano Zampini ierr = PetscObjectReference((PetscObject)A_II);CHKERRQ(ierr); 16734a97f8cSStefano Zampini AE_II = A_II; 16834a97f8cSStefano Zampini } 16934a97f8cSStefano Zampini 170*2a155e38SStefano Zampini /* TODO: just for compatibility with the previous version, needs to be fixed */ 171*2a155e38SStefano Zampini for (i=1;i<sub_schurs->n_subs;i++) { 172*2a155e38SStefano Zampini ierr = PetscObjectReference((PetscObject)sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 173*2a155e38SStefano Zampini sub_schurs->is_AEj_I[i] = sub_schurs->is_AEj_I[0]; 174*2a155e38SStefano Zampini } 17534a97f8cSStefano Zampini 176*2a155e38SStefano Zampini /* subsets in original and boundary numbering */ 177*2a155e38SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_A_B,&BtoNmap);CHKERRQ(ierr); 178*2a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 179*2a155e38SStefano Zampini ierr = ISDuplicate(is_cc[i],&sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 180*2a155e38SStefano Zampini ierr = ISSort(sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 181*2a155e38SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(BtoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_B[i],&is_subset_B[i]);CHKERRQ(ierr); 182*2a155e38SStefano Zampini } 183*2a155e38SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&BtoNmap);CHKERRQ(ierr); 184*2a155e38SStefano Zampini 185*2a155e38SStefano Zampini /* EE block */ 186*2a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 187*2a155e38SStefano Zampini ierr = MatGetSubMatrix(A_BB,is_subset_B[i],is_subset_B[i],MAT_INITIAL_MATRIX,&AE_EE[i]);CHKERRQ(ierr); 188*2a155e38SStefano Zampini } 189*2a155e38SStefano Zampini /* IE block */ 190*2a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 191*2a155e38SStefano Zampini ierr = MatGetSubMatrix(A_IB,is_I,is_subset_B[i],MAT_INITIAL_MATRIX,&AE_IE[i]);CHKERRQ(ierr); 192*2a155e38SStefano Zampini } 19334a97f8cSStefano Zampini /* EI block */ 194*2a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 195*2a155e38SStefano Zampini ierr = MatGetSubMatrix(A_BI,is_subset_B[i],is_I,MAT_INITIAL_MATRIX,&AE_EI[i]);CHKERRQ(ierr); 196*2a155e38SStefano Zampini } 19734a97f8cSStefano Zampini 19834a97f8cSStefano Zampini /* setup Schur complements on subset */ 199*2a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 200*2a155e38SStefano Zampini ierr = MatCreateSchurComplement(AE_II,AE_II,AE_IE[i],AE_EI[i],AE_EE[i],&sub_schurs->S_Ej[i]);CHKERRQ(ierr); 2018a26ef87SStefano Zampini ierr = MatCreateVecs(sub_schurs->S_Ej[i],&sub_schurs->work1[i],&sub_schurs->work2[i]);CHKERRQ(ierr); 20234a97f8cSStefano Zampini if (AE_II == A_II) { /* we can reuse the same ksp */ 20334a97f8cSStefano Zampini KSP ksp; 20434a97f8cSStefano Zampini ierr = MatSchurComplementGetKSP(S,&ksp);CHKERRQ(ierr); 20534a97f8cSStefano Zampini ierr = MatSchurComplementSetKSP(sub_schurs->S_Ej[i],ksp);CHKERRQ(ierr); 20634a97f8cSStefano Zampini } else { /* build new ksp object which inherits ksp and pc types from the original one */ 20734a97f8cSStefano Zampini KSP origksp,schurksp; 20834a97f8cSStefano Zampini PC origpc,schurpc; 20934a97f8cSStefano Zampini KSPType ksp_type; 21034a97f8cSStefano Zampini PCType pc_type; 21134a97f8cSStefano Zampini PetscInt n_internal; 21234a97f8cSStefano Zampini 21334a97f8cSStefano Zampini ierr = MatSchurComplementGetKSP(S,&origksp);CHKERRQ(ierr); 21434a97f8cSStefano Zampini ierr = MatSchurComplementGetKSP(sub_schurs->S_Ej[i],&schurksp);CHKERRQ(ierr); 21534a97f8cSStefano Zampini ierr = KSPGetType(origksp,&ksp_type);CHKERRQ(ierr); 21634a97f8cSStefano Zampini ierr = KSPSetType(schurksp,ksp_type);CHKERRQ(ierr); 21734a97f8cSStefano Zampini ierr = KSPGetPC(schurksp,&schurpc);CHKERRQ(ierr); 21834a97f8cSStefano Zampini ierr = KSPGetPC(origksp,&origpc);CHKERRQ(ierr); 21934a97f8cSStefano Zampini ierr = PCGetType(origpc,&pc_type);CHKERRQ(ierr); 22034a97f8cSStefano Zampini ierr = PCSetType(schurpc,pc_type);CHKERRQ(ierr); 22134a97f8cSStefano Zampini ierr = ISGetSize(is_I,&n_internal);CHKERRQ(ierr); 22234a97f8cSStefano Zampini if (n_internal) { /* UMFPACK gives error with 0 sized problems */ 22334a97f8cSStefano Zampini MatSolverPackage solver=NULL; 22434a97f8cSStefano Zampini ierr = PCFactorGetMatSolverPackage(origpc,(const MatSolverPackage*)&solver);CHKERRQ(ierr); 22534a97f8cSStefano Zampini if (solver) { 22634a97f8cSStefano Zampini ierr = PCFactorSetMatSolverPackage(schurpc,solver);CHKERRQ(ierr); 22734a97f8cSStefano Zampini } 22834a97f8cSStefano Zampini } 22934a97f8cSStefano Zampini ierr = KSPSetUp(schurksp);CHKERRQ(ierr); 23034a97f8cSStefano Zampini } 23134a97f8cSStefano Zampini } 23234a97f8cSStefano Zampini /* free */ 233*2a155e38SStefano Zampini ierr = ISDestroy(&is_I);CHKERRQ(ierr); 234*2a155e38SStefano Zampini ierr = MatDestroy(&AE_II);CHKERRQ(ierr); 235*2a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 236*2a155e38SStefano Zampini ierr = MatDestroy(&AE_EE[i]);CHKERRQ(ierr); 237*2a155e38SStefano Zampini ierr = MatDestroy(&AE_IE[i]);CHKERRQ(ierr); 238*2a155e38SStefano Zampini ierr = MatDestroy(&AE_EI[i]);CHKERRQ(ierr); 239*2a155e38SStefano Zampini ierr = ISDestroy(&is_subset_B[i]);CHKERRQ(ierr); 240*2a155e38SStefano Zampini } 241*2a155e38SStefano Zampini ierr = PetscFree4(is_subset_B,AE_IE,AE_EI,AE_EE);CHKERRQ(ierr); 24234a97f8cSStefano Zampini PetscFunctionReturn(0); 24334a97f8cSStefano Zampini } 244