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__ 7*b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCSubSchursSetUpNew" 8*b1b3d7a2SStefano Zampini PetscErrorCode PCBDDCSubSchursSetUpNew(PCBDDCSubSchurs sub_schurs, PetscInt xadj[], PetscInt adjncy[], PetscInt nlayers) 9*b1b3d7a2SStefano Zampini { 10*b1b3d7a2SStefano Zampini Mat A_II,A_IB,A_BI,A_BB; 11*b1b3d7a2SStefano Zampini Mat AE_II,*AE_IE,*AE_EI,*AE_EE; 12*b1b3d7a2SStefano Zampini IS is_I,*is_subset_B; 13*b1b3d7a2SStefano Zampini ISLocalToGlobalMapping BtoNmap; 14*b1b3d7a2SStefano Zampini PetscInt i; 15*b1b3d7a2SStefano Zampini PetscBool implicit_schurs; 16*b1b3d7a2SStefano Zampini PetscErrorCode ierr; 17*b1b3d7a2SStefano Zampini 18*b1b3d7a2SStefano Zampini PetscFunctionBegin; 19*b1b3d7a2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)sub_schurs->S,MATSCHURCOMPLEMENT,&implicit_schurs);CHKERRQ(ierr); 20*b1b3d7a2SStefano Zampini 21*b1b3d7a2SStefano Zampini /* allocate space for schur complements */ 22*b1b3d7a2SStefano Zampini ierr = PetscMalloc5(sub_schurs->n_subs,&sub_schurs->is_AEj_I, 23*b1b3d7a2SStefano Zampini sub_schurs->n_subs,&sub_schurs->is_AEj_B, 24*b1b3d7a2SStefano Zampini sub_schurs->n_subs,&sub_schurs->S_Ej, 25*b1b3d7a2SStefano Zampini sub_schurs->n_subs,&sub_schurs->work1, 26*b1b3d7a2SStefano Zampini sub_schurs->n_subs,&sub_schurs->work2);CHKERRQ(ierr); 27*b1b3d7a2SStefano Zampini 28*b1b3d7a2SStefano Zampini /* get Schur complement matrices */ 29*b1b3d7a2SStefano Zampini if (implicit_schurs) { 30*b1b3d7a2SStefano Zampini ierr = MatSchurComplementGetSubMatrices(sub_schurs->S,&A_II,NULL,&A_IB,&A_BI,&A_BB);CHKERRQ(ierr); 31*b1b3d7a2SStefano Zampini ierr = PetscMalloc4(sub_schurs->n_subs,&is_subset_B, 32*b1b3d7a2SStefano Zampini sub_schurs->n_subs,&AE_IE, 33*b1b3d7a2SStefano Zampini sub_schurs->n_subs,&AE_EI, 34*b1b3d7a2SStefano Zampini sub_schurs->n_subs,&AE_EE);CHKERRQ(ierr); 35*b1b3d7a2SStefano Zampini } 36*b1b3d7a2SStefano Zampini 37*b1b3d7a2SStefano Zampini /* determine interior problems */ 38*b1b3d7a2SStefano Zampini if (nlayers >= 0 && xadj != NULL && adjncy != NULL) { /* Interior problems can be different from the original one */ 39*b1b3d7a2SStefano Zampini PetscBT touched; 40*b1b3d7a2SStefano Zampini const PetscInt* idx_B; 41*b1b3d7a2SStefano Zampini PetscInt n_I,n_B,n_local_dofs,n_prev_added,j,layer,*local_numbering; 42*b1b3d7a2SStefano Zampini 43*b1b3d7a2SStefano Zampini /* get sizes */ 44*b1b3d7a2SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_I,&n_I);CHKERRQ(ierr); 45*b1b3d7a2SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_B,&n_B);CHKERRQ(ierr); 46*b1b3d7a2SStefano Zampini 47*b1b3d7a2SStefano Zampini ierr = PetscMalloc1(n_I+n_B,&local_numbering);CHKERRQ(ierr); 48*b1b3d7a2SStefano Zampini ierr = PetscBTCreate(n_I+n_B,&touched);CHKERRQ(ierr); 49*b1b3d7a2SStefano Zampini ierr = PetscBTMemzero(n_I+n_B,touched);CHKERRQ(ierr); 50*b1b3d7a2SStefano Zampini 51*b1b3d7a2SStefano Zampini /* all boundary dofs must be skipped when adding layers */ 52*b1b3d7a2SStefano Zampini ierr = ISGetIndices(sub_schurs->is_B,&idx_B);CHKERRQ(ierr); 53*b1b3d7a2SStefano Zampini for (j=0;j<n_B;j++) { 54*b1b3d7a2SStefano Zampini ierr = PetscBTSet(touched,idx_B[j]);CHKERRQ(ierr); 55*b1b3d7a2SStefano Zampini } 56*b1b3d7a2SStefano Zampini ierr = PetscMemcpy(local_numbering,idx_B,n_B*sizeof(PetscInt));CHKERRQ(ierr); 57*b1b3d7a2SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_B,&idx_B);CHKERRQ(ierr); 58*b1b3d7a2SStefano Zampini 59*b1b3d7a2SStefano Zampini /* add prescribed number of layers of dofs */ 60*b1b3d7a2SStefano Zampini n_local_dofs = n_B; 61*b1b3d7a2SStefano Zampini n_prev_added = n_B; 62*b1b3d7a2SStefano Zampini for (layer=0;layer<nlayers;layer++) { 63*b1b3d7a2SStefano Zampini PetscInt n_added; 64*b1b3d7a2SStefano Zampini if (n_local_dofs == n_I+n_B) break; 65*b1b3d7a2SStefano Zampini if (n_local_dofs > n_I+n_B) { 66*b1b3d7a2SStefano 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); 67*b1b3d7a2SStefano Zampini } 68*b1b3d7a2SStefano Zampini ierr = PCBDDCAdjGetNextLayer_Private(local_numbering+n_local_dofs,n_prev_added,touched,xadj,adjncy,&n_added);CHKERRQ(ierr); 69*b1b3d7a2SStefano Zampini n_prev_added = n_added; 70*b1b3d7a2SStefano Zampini n_local_dofs += n_added; 71*b1b3d7a2SStefano Zampini if (!n_added) break; 72*b1b3d7a2SStefano Zampini } 73*b1b3d7a2SStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 74*b1b3d7a2SStefano Zampini 75*b1b3d7a2SStefano Zampini /* IS for I dofs in original numbering */ 76*b1b3d7a2SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)sub_schurs->is_I),n_local_dofs-n_B,local_numbering+n_B,PETSC_COPY_VALUES,&sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 77*b1b3d7a2SStefano Zampini ierr = PetscFree(local_numbering);CHKERRQ(ierr); 78*b1b3d7a2SStefano Zampini ierr = ISSort(sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 79*b1b3d7a2SStefano Zampini /* IS for I dofs in boundary numbering */ 80*b1b3d7a2SStefano Zampini if (implicit_schurs) { 81*b1b3d7a2SStefano Zampini ISLocalToGlobalMapping ItoNmap; 82*b1b3d7a2SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(sub_schurs->is_I,&ItoNmap);CHKERRQ(ierr); 83*b1b3d7a2SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(ItoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_I[0],&is_I);CHKERRQ(ierr); 84*b1b3d7a2SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&ItoNmap);CHKERRQ(ierr); 85*b1b3d7a2SStefano Zampini 86*b1b3d7a2SStefano Zampini /* II block */ 87*b1b3d7a2SStefano Zampini ierr = MatGetSubMatrix(A_II,is_I,is_I,MAT_INITIAL_MATRIX,&AE_II);CHKERRQ(ierr); 88*b1b3d7a2SStefano Zampini } 89*b1b3d7a2SStefano Zampini } else { 90*b1b3d7a2SStefano Zampini PetscInt n_I; 91*b1b3d7a2SStefano Zampini 92*b1b3d7a2SStefano Zampini /* IS for I dofs in original numbering */ 93*b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)sub_schurs->is_I);CHKERRQ(ierr); 94*b1b3d7a2SStefano Zampini sub_schurs->is_AEj_I[0] = sub_schurs->is_I; 95*b1b3d7a2SStefano Zampini 96*b1b3d7a2SStefano Zampini /* IS for I dofs in I numbering (strided 1) */ 97*b1b3d7a2SStefano Zampini if (implicit_schurs) { 98*b1b3d7a2SStefano Zampini ierr = ISGetSize(sub_schurs->is_I,&n_I);CHKERRQ(ierr); 99*b1b3d7a2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)sub_schurs->is_I),n_I,0,1,&is_I);CHKERRQ(ierr); 100*b1b3d7a2SStefano Zampini 101*b1b3d7a2SStefano Zampini /* II block is the same */ 102*b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)A_II);CHKERRQ(ierr); 103*b1b3d7a2SStefano Zampini AE_II = A_II; 104*b1b3d7a2SStefano Zampini } 105*b1b3d7a2SStefano Zampini } 106*b1b3d7a2SStefano Zampini 107*b1b3d7a2SStefano Zampini /* TODO: just for compatibility with the previous version, needs to be fixed */ 108*b1b3d7a2SStefano Zampini for (i=1;i<sub_schurs->n_subs;i++) { 109*b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 110*b1b3d7a2SStefano Zampini sub_schurs->is_AEj_I[i] = sub_schurs->is_AEj_I[0]; 111*b1b3d7a2SStefano Zampini } 112*b1b3d7a2SStefano Zampini 113*b1b3d7a2SStefano Zampini if (implicit_schurs) { 114*b1b3d7a2SStefano Zampini /* subsets in original and boundary numbering */ 115*b1b3d7a2SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(sub_schurs->is_B,&BtoNmap);CHKERRQ(ierr); 116*b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 117*b1b3d7a2SStefano Zampini ierr = ISDuplicate(sub_schurs->is_subs[i],&sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 118*b1b3d7a2SStefano Zampini ierr = ISSort(sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 119*b1b3d7a2SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(BtoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_B[i],&is_subset_B[i]);CHKERRQ(ierr); 120*b1b3d7a2SStefano Zampini } 121*b1b3d7a2SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&BtoNmap);CHKERRQ(ierr); 122*b1b3d7a2SStefano Zampini 123*b1b3d7a2SStefano Zampini /* EE block */ 124*b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 125*b1b3d7a2SStefano Zampini ierr = MatGetSubMatrix(A_BB,is_subset_B[i],is_subset_B[i],MAT_INITIAL_MATRIX,&AE_EE[i]);CHKERRQ(ierr); 126*b1b3d7a2SStefano Zampini } 127*b1b3d7a2SStefano Zampini /* IE block */ 128*b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 129*b1b3d7a2SStefano Zampini ierr = MatGetSubMatrix(A_IB,is_I,is_subset_B[i],MAT_INITIAL_MATRIX,&AE_IE[i]);CHKERRQ(ierr); 130*b1b3d7a2SStefano Zampini } 131*b1b3d7a2SStefano Zampini /* EI block */ 132*b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 133*b1b3d7a2SStefano Zampini ierr = MatGetSubMatrix(A_BI,is_subset_B[i],is_I,MAT_INITIAL_MATRIX,&AE_EI[i]);CHKERRQ(ierr); 134*b1b3d7a2SStefano Zampini } 135*b1b3d7a2SStefano Zampini 136*b1b3d7a2SStefano Zampini /* setup Schur complements on subset */ 137*b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 138*b1b3d7a2SStefano Zampini ierr = MatCreateSchurComplement(AE_II,AE_II,AE_IE[i],AE_EI[i],AE_EE[i],&sub_schurs->S_Ej[i]);CHKERRQ(ierr); 139*b1b3d7a2SStefano Zampini ierr = MatCreateVecs(sub_schurs->S_Ej[i],&sub_schurs->work1[i],&sub_schurs->work2[i]);CHKERRQ(ierr); 140*b1b3d7a2SStefano Zampini if (AE_II == A_II) { /* we can reuse the same ksp */ 141*b1b3d7a2SStefano Zampini KSP ksp; 142*b1b3d7a2SStefano Zampini ierr = MatSchurComplementGetKSP(sub_schurs->S,&ksp);CHKERRQ(ierr); 143*b1b3d7a2SStefano Zampini ierr = MatSchurComplementSetKSP(sub_schurs->S_Ej[i],ksp);CHKERRQ(ierr); 144*b1b3d7a2SStefano Zampini } else { /* build new ksp object which inherits ksp and pc types from the original one */ 145*b1b3d7a2SStefano Zampini KSP origksp,schurksp; 146*b1b3d7a2SStefano Zampini PC origpc,schurpc; 147*b1b3d7a2SStefano Zampini KSPType ksp_type; 148*b1b3d7a2SStefano Zampini PCType pc_type; 149*b1b3d7a2SStefano Zampini PetscInt n_internal; 150*b1b3d7a2SStefano Zampini 151*b1b3d7a2SStefano Zampini ierr = MatSchurComplementGetKSP(sub_schurs->S,&origksp);CHKERRQ(ierr); 152*b1b3d7a2SStefano Zampini ierr = MatSchurComplementGetKSP(sub_schurs->S_Ej[i],&schurksp);CHKERRQ(ierr); 153*b1b3d7a2SStefano Zampini ierr = KSPGetType(origksp,&ksp_type);CHKERRQ(ierr); 154*b1b3d7a2SStefano Zampini ierr = KSPSetType(schurksp,ksp_type);CHKERRQ(ierr); 155*b1b3d7a2SStefano Zampini ierr = KSPGetPC(schurksp,&schurpc);CHKERRQ(ierr); 156*b1b3d7a2SStefano Zampini ierr = KSPGetPC(origksp,&origpc);CHKERRQ(ierr); 157*b1b3d7a2SStefano Zampini ierr = PCGetType(origpc,&pc_type);CHKERRQ(ierr); 158*b1b3d7a2SStefano Zampini ierr = PCSetType(schurpc,pc_type);CHKERRQ(ierr); 159*b1b3d7a2SStefano Zampini ierr = ISGetSize(is_I,&n_internal);CHKERRQ(ierr); 160*b1b3d7a2SStefano Zampini if (n_internal) { /* UMFPACK gives error with 0 sized problems */ 161*b1b3d7a2SStefano Zampini MatSolverPackage solver=NULL; 162*b1b3d7a2SStefano Zampini ierr = PCFactorGetMatSolverPackage(origpc,(const MatSolverPackage*)&solver);CHKERRQ(ierr); 163*b1b3d7a2SStefano Zampini if (solver) { 164*b1b3d7a2SStefano Zampini ierr = PCFactorSetMatSolverPackage(schurpc,solver);CHKERRQ(ierr); 165*b1b3d7a2SStefano Zampini } 166*b1b3d7a2SStefano Zampini } 167*b1b3d7a2SStefano Zampini ierr = KSPSetUp(schurksp);CHKERRQ(ierr); 168*b1b3d7a2SStefano Zampini } 169*b1b3d7a2SStefano Zampini } 170*b1b3d7a2SStefano Zampini /* free */ 171*b1b3d7a2SStefano Zampini ierr = ISDestroy(&is_I);CHKERRQ(ierr); 172*b1b3d7a2SStefano Zampini ierr = MatDestroy(&AE_II);CHKERRQ(ierr); 173*b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 174*b1b3d7a2SStefano Zampini ierr = MatDestroy(&AE_EE[i]);CHKERRQ(ierr); 175*b1b3d7a2SStefano Zampini ierr = MatDestroy(&AE_IE[i]);CHKERRQ(ierr); 176*b1b3d7a2SStefano Zampini ierr = MatDestroy(&AE_EI[i]);CHKERRQ(ierr); 177*b1b3d7a2SStefano Zampini ierr = ISDestroy(&is_subset_B[i]);CHKERRQ(ierr); 178*b1b3d7a2SStefano Zampini } 179*b1b3d7a2SStefano Zampini ierr = PetscFree4(is_subset_B,AE_IE,AE_EI,AE_EE);CHKERRQ(ierr); 180*b1b3d7a2SStefano Zampini } 181*b1b3d7a2SStefano Zampini PetscFunctionReturn(0); 182*b1b3d7a2SStefano Zampini } 183*b1b3d7a2SStefano Zampini 184*b1b3d7a2SStefano Zampini #undef __FUNCT__ 185*b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCSubSchursInit" 186*b1b3d7a2SStefano Zampini PetscErrorCode PCBDDCSubSchursInit(PCBDDCSubSchurs sub_schurs, Mat S, IS is_I, IS is_B, PCBDDCGraph graph, PetscInt seqthreshold) 187*b1b3d7a2SStefano Zampini { 188*b1b3d7a2SStefano Zampini IS *faces,*edges,*all_cc; 189*b1b3d7a2SStefano Zampini PetscInt *index_sequential,*index_parallel; 190*b1b3d7a2SStefano Zampini PetscInt *auxlocal_sequential,*auxlocal_parallel; 191*b1b3d7a2SStefano Zampini PetscInt *auxglobal_sequential,*auxglobal_parallel; 192*b1b3d7a2SStefano Zampini PetscInt *auxmapping;//,*idxs; 193*b1b3d7a2SStefano Zampini PetscInt i,max_subset_size; 194*b1b3d7a2SStefano Zampini PetscInt n_sequential_problems,n_local_sequential_problems,n_parallel_problems,n_local_parallel_problems; 195*b1b3d7a2SStefano Zampini PetscInt n_faces,n_edges,n_all_cc; 196*b1b3d7a2SStefano Zampini PetscBool is_sorted; 197*b1b3d7a2SStefano Zampini PetscErrorCode ierr; 198*b1b3d7a2SStefano Zampini 199*b1b3d7a2SStefano Zampini PetscFunctionBegin; 200*b1b3d7a2SStefano Zampini ierr = ISSorted(is_I,&is_sorted);CHKERRQ(ierr); 201*b1b3d7a2SStefano Zampini if (!is_sorted) { 202*b1b3d7a2SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)is_I),PETSC_ERR_PLIB,"IS for I dofs should be shorted"); 203*b1b3d7a2SStefano Zampini } 204*b1b3d7a2SStefano Zampini ierr = ISSorted(is_B,&is_sorted);CHKERRQ(ierr); 205*b1b3d7a2SStefano Zampini if (!is_sorted) { 206*b1b3d7a2SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)is_B),PETSC_ERR_PLIB,"IS for B dofs should be shorted"); 207*b1b3d7a2SStefano Zampini } 208*b1b3d7a2SStefano Zampini 209*b1b3d7a2SStefano Zampini /* reset any previous data */ 210*b1b3d7a2SStefano Zampini ierr = PCBDDCSubSchursReset(sub_schurs);CHKERRQ(ierr); 211*b1b3d7a2SStefano Zampini 212*b1b3d7a2SStefano Zampini /* get index sets for faces and edges */ 213*b1b3d7a2SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&n_faces,&faces,&n_edges,&edges,NULL);CHKERRQ(ierr); 214*b1b3d7a2SStefano Zampini n_all_cc = n_faces+n_edges; 215*b1b3d7a2SStefano Zampini ierr = PetscMalloc1(n_all_cc,&all_cc);CHKERRQ(ierr); 216*b1b3d7a2SStefano Zampini for (i=0;i<n_faces;i++) { 217*b1b3d7a2SStefano Zampini all_cc[i] = faces[i]; 218*b1b3d7a2SStefano Zampini } 219*b1b3d7a2SStefano Zampini for (i=0;i<n_edges;i++) { 220*b1b3d7a2SStefano Zampini all_cc[n_faces+i] = edges[i]; 221*b1b3d7a2SStefano Zampini } 222*b1b3d7a2SStefano Zampini ierr = PetscFree(faces);CHKERRQ(ierr); 223*b1b3d7a2SStefano Zampini ierr = PetscFree(edges);CHKERRQ(ierr); 224*b1b3d7a2SStefano Zampini 225*b1b3d7a2SStefano Zampini /* map interface's subsets */ 226*b1b3d7a2SStefano Zampini max_subset_size = 0; 227*b1b3d7a2SStefano Zampini for (i=0;i<n_all_cc;i++) { 228*b1b3d7a2SStefano Zampini PetscInt subset_size; 229*b1b3d7a2SStefano Zampini ierr = ISGetLocalSize(all_cc[i],&subset_size);CHKERRQ(ierr); 230*b1b3d7a2SStefano Zampini max_subset_size = PetscMax(max_subset_size,subset_size); 231*b1b3d7a2SStefano Zampini } 232*b1b3d7a2SStefano Zampini ierr = PetscMalloc1(max_subset_size,&auxmapping);CHKERRQ(ierr); 233*b1b3d7a2SStefano Zampini ierr = PetscMalloc2(graph->ncc,&auxlocal_sequential, 234*b1b3d7a2SStefano Zampini graph->ncc,&auxlocal_parallel);CHKERRQ(ierr); 235*b1b3d7a2SStefano Zampini ierr = PetscMalloc2(graph->ncc,&index_sequential, 236*b1b3d7a2SStefano Zampini graph->ncc,&index_parallel);CHKERRQ(ierr); 237*b1b3d7a2SStefano Zampini 238*b1b3d7a2SStefano Zampini /* if threshold is negative, uses all sequential problems */ 239*b1b3d7a2SStefano Zampini if (seqthreshold < 0) seqthreshold = max_subset_size; 240*b1b3d7a2SStefano Zampini 241*b1b3d7a2SStefano Zampini /* determine which problem has to be solved in parallel or sequentially */ 242*b1b3d7a2SStefano Zampini n_local_sequential_problems = 0; 243*b1b3d7a2SStefano Zampini n_local_parallel_problems = 0; 244*b1b3d7a2SStefano Zampini for (i=0;i<n_all_cc;i++) { 245*b1b3d7a2SStefano Zampini PetscInt subset_size,j,min_loc = 0; 246*b1b3d7a2SStefano Zampini const PetscInt *idxs; 247*b1b3d7a2SStefano Zampini 248*b1b3d7a2SStefano Zampini ierr = ISGetLocalSize(all_cc[i],&subset_size);CHKERRQ(ierr); 249*b1b3d7a2SStefano Zampini ierr = ISGetIndices(all_cc[i],&idxs);CHKERRQ(ierr); 250*b1b3d7a2SStefano Zampini ierr = ISLocalToGlobalMappingApply(graph->l2gmap,subset_size,idxs,auxmapping);CHKERRQ(ierr); 251*b1b3d7a2SStefano Zampini for (j=1;j<subset_size;j++) { 252*b1b3d7a2SStefano Zampini if (auxmapping[j]<auxmapping[min_loc]) { 253*b1b3d7a2SStefano Zampini min_loc = j; 254*b1b3d7a2SStefano Zampini } 255*b1b3d7a2SStefano Zampini } 256*b1b3d7a2SStefano Zampini if (subset_size > seqthreshold) { 257*b1b3d7a2SStefano Zampini index_parallel[n_local_parallel_problems] = i; 258*b1b3d7a2SStefano Zampini auxlocal_parallel[n_local_parallel_problems] = idxs[min_loc]; 259*b1b3d7a2SStefano Zampini n_local_parallel_problems++; 260*b1b3d7a2SStefano Zampini } else { 261*b1b3d7a2SStefano Zampini index_sequential[n_local_sequential_problems] = i; 262*b1b3d7a2SStefano Zampini auxlocal_sequential[n_local_sequential_problems] = idxs[min_loc]; 263*b1b3d7a2SStefano Zampini n_local_sequential_problems++; 264*b1b3d7a2SStefano Zampini } 265*b1b3d7a2SStefano Zampini ierr = ISRestoreIndices(all_cc[i],&idxs);CHKERRQ(ierr); 266*b1b3d7a2SStefano Zampini } 267*b1b3d7a2SStefano Zampini 268*b1b3d7a2SStefano Zampini /* Number parallel problems */ 269*b1b3d7a2SStefano Zampini auxglobal_parallel = 0; 270*b1b3d7a2SStefano Zampini ierr = PCBDDCSubsetNumbering(PetscObjectComm((PetscObject)graph->l2gmap),graph->l2gmap,n_local_parallel_problems,auxlocal_parallel,PETSC_NULL,&n_parallel_problems,&auxglobal_parallel);CHKERRQ(ierr); 271*b1b3d7a2SStefano Zampini 272*b1b3d7a2SStefano Zampini /* Number sequential problems */ 273*b1b3d7a2SStefano Zampini auxglobal_sequential = 0; 274*b1b3d7a2SStefano Zampini ierr = PCBDDCSubsetNumbering(PetscObjectComm((PetscObject)graph->l2gmap),graph->l2gmap,n_local_sequential_problems,auxlocal_sequential,PETSC_NULL,&n_sequential_problems,&auxglobal_sequential);CHKERRQ(ierr); 275*b1b3d7a2SStefano Zampini 276*b1b3d7a2SStefano Zampini /* update info in sub_schurs */ 277*b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)S);CHKERRQ(ierr); 278*b1b3d7a2SStefano Zampini sub_schurs->S = S; 279*b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)is_I);CHKERRQ(ierr); 280*b1b3d7a2SStefano Zampini sub_schurs->is_I = is_I; 281*b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)is_B);CHKERRQ(ierr); 282*b1b3d7a2SStefano Zampini sub_schurs->is_B = is_B; 283*b1b3d7a2SStefano Zampini sub_schurs->n_subs_seq = n_local_sequential_problems; 284*b1b3d7a2SStefano Zampini sub_schurs->n_subs_par = n_local_parallel_problems; 285*b1b3d7a2SStefano Zampini sub_schurs->n_subs_seq_g = n_sequential_problems; 286*b1b3d7a2SStefano Zampini sub_schurs->n_subs_par_g = n_parallel_problems; 287*b1b3d7a2SStefano Zampini sub_schurs->n_subs = sub_schurs->n_subs_seq + sub_schurs->n_subs_par; 288*b1b3d7a2SStefano Zampini sub_schurs->is_subs = all_cc; 289*b1b3d7a2SStefano Zampini sub_schurs->index_sequential = index_sequential; 290*b1b3d7a2SStefano Zampini sub_schurs->index_parallel = index_parallel; 291*b1b3d7a2SStefano Zampini sub_schurs->auxglobal_sequential = auxglobal_sequential; 292*b1b3d7a2SStefano Zampini sub_schurs->auxglobal_parallel = auxglobal_parallel; 293*b1b3d7a2SStefano Zampini 294*b1b3d7a2SStefano Zampini /* free workspace */ 295*b1b3d7a2SStefano Zampini ierr = PetscFree(auxmapping);CHKERRQ(ierr); 296*b1b3d7a2SStefano Zampini ierr = PetscFree2(auxlocal_sequential,auxlocal_parallel);CHKERRQ(ierr); 297*b1b3d7a2SStefano Zampini 298*b1b3d7a2SStefano Zampini PetscFunctionReturn(0); 299*b1b3d7a2SStefano Zampini } 300*b1b3d7a2SStefano Zampini 301*b1b3d7a2SStefano Zampini #undef __FUNCT__ 30234a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursCreate" 30334a97f8cSStefano Zampini PetscErrorCode PCBDDCSubSchursCreate(PCBDDCSubSchurs *sub_schurs) 30434a97f8cSStefano Zampini { 30534a97f8cSStefano Zampini PCBDDCSubSchurs schurs_ctx; 30634a97f8cSStefano Zampini PetscErrorCode ierr; 30734a97f8cSStefano Zampini 30834a97f8cSStefano Zampini PetscFunctionBegin; 30934a97f8cSStefano Zampini ierr = PetscNew(&schurs_ctx);CHKERRQ(ierr); 3105ff63025SStefano Zampini schurs_ctx->n_subs = 0; 31134a97f8cSStefano Zampini *sub_schurs = schurs_ctx; 31234a97f8cSStefano Zampini PetscFunctionReturn(0); 31334a97f8cSStefano Zampini } 31434a97f8cSStefano Zampini 31534a97f8cSStefano Zampini #undef __FUNCT__ 31634a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursDestroy" 31734a97f8cSStefano Zampini PetscErrorCode PCBDDCSubSchursDestroy(PCBDDCSubSchurs *sub_schurs) 31834a97f8cSStefano Zampini { 31934a97f8cSStefano Zampini PetscErrorCode ierr; 32034a97f8cSStefano Zampini 32134a97f8cSStefano Zampini PetscFunctionBegin; 32234a97f8cSStefano Zampini ierr = PCBDDCSubSchursReset(*sub_schurs);CHKERRQ(ierr); 32334a97f8cSStefano Zampini ierr = PetscFree(*sub_schurs);CHKERRQ(ierr); 32434a97f8cSStefano Zampini PetscFunctionReturn(0); 32534a97f8cSStefano Zampini } 32634a97f8cSStefano Zampini 32734a97f8cSStefano Zampini #undef __FUNCT__ 32834a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursReset" 32934a97f8cSStefano Zampini PetscErrorCode PCBDDCSubSchursReset(PCBDDCSubSchurs sub_schurs) 33034a97f8cSStefano Zampini { 33134a97f8cSStefano Zampini PetscInt i; 33234a97f8cSStefano Zampini PetscErrorCode ierr; 33334a97f8cSStefano Zampini 33434a97f8cSStefano Zampini PetscFunctionBegin; 335*b1b3d7a2SStefano Zampini ierr = MatDestroy(&sub_schurs->S);CHKERRQ(ierr); 336*b1b3d7a2SStefano Zampini ierr = ISDestroy(&sub_schurs->is_I);CHKERRQ(ierr); 337*b1b3d7a2SStefano Zampini ierr = ISDestroy(&sub_schurs->is_B);CHKERRQ(ierr); 33834a97f8cSStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 339*b1b3d7a2SStefano Zampini ierr = ISDestroy(&sub_schurs->is_subs[i]);CHKERRQ(ierr); 34034a97f8cSStefano Zampini ierr = ISDestroy(&sub_schurs->is_AEj_I[i]);CHKERRQ(ierr); 34134a97f8cSStefano Zampini ierr = ISDestroy(&sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 34234a97f8cSStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej[i]);CHKERRQ(ierr); 34334a97f8cSStefano Zampini ierr = VecDestroy(&sub_schurs->work1[i]);CHKERRQ(ierr); 34434a97f8cSStefano Zampini ierr = VecDestroy(&sub_schurs->work2[i]);CHKERRQ(ierr); 34534a97f8cSStefano Zampini } 3465ff63025SStefano Zampini if (sub_schurs->n_subs) { 347*b1b3d7a2SStefano Zampini ierr = PetscFree(sub_schurs->is_subs);CHKERRQ(ierr); 34834a97f8cSStefano 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); 349*b1b3d7a2SStefano Zampini ierr = PetscFree2(sub_schurs->index_sequential,sub_schurs->index_parallel);CHKERRQ(ierr); 350*b1b3d7a2SStefano Zampini ierr = PetscFree(sub_schurs->auxglobal_sequential);CHKERRQ(ierr); 351*b1b3d7a2SStefano Zampini ierr = PetscFree(sub_schurs->auxglobal_parallel);CHKERRQ(ierr); 3525ff63025SStefano Zampini } 35334a97f8cSStefano Zampini sub_schurs->n_subs = 0; 35434a97f8cSStefano Zampini PetscFunctionReturn(0); 35534a97f8cSStefano Zampini } 35634a97f8cSStefano Zampini 35734a97f8cSStefano Zampini #undef __FUNCT__ 35834a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCAdjGetNextLayer_Private" 3592a155e38SStefano Zampini PETSC_STATIC_INLINE PetscErrorCode PCBDDCAdjGetNextLayer_Private(PetscInt* queue_tip,PetscInt n_prev,PetscBT touched,PetscInt* xadj,PetscInt* adjncy,PetscInt* n_added) 36034a97f8cSStefano Zampini { 36134a97f8cSStefano Zampini PetscInt i,j,n; 36234a97f8cSStefano Zampini PetscErrorCode ierr; 36334a97f8cSStefano Zampini 36434a97f8cSStefano Zampini PetscFunctionBegin; 36534a97f8cSStefano Zampini n = 0; 36634a97f8cSStefano Zampini for (i=-n_prev;i<0;i++) { 36734a97f8cSStefano Zampini PetscInt start_dof = queue_tip[i]; 36834a97f8cSStefano Zampini for (j=xadj[start_dof];j<xadj[start_dof+1];j++) { 36934a97f8cSStefano Zampini PetscInt dof = adjncy[j]; 37034a97f8cSStefano Zampini if (!PetscBTLookup(touched,dof)) { 37134a97f8cSStefano Zampini ierr = PetscBTSet(touched,dof);CHKERRQ(ierr); 37234a97f8cSStefano Zampini queue_tip[n] = dof; 37334a97f8cSStefano Zampini n++; 37434a97f8cSStefano Zampini } 37534a97f8cSStefano Zampini } 37634a97f8cSStefano Zampini } 37734a97f8cSStefano Zampini *n_added = n; 37834a97f8cSStefano Zampini PetscFunctionReturn(0); 37934a97f8cSStefano Zampini } 38034a97f8cSStefano Zampini 38134a97f8cSStefano Zampini #undef __FUNCT__ 38234a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursSetUp" 3837821e9e7SStefano 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) 38434a97f8cSStefano Zampini { 38534a97f8cSStefano Zampini Mat A_II,A_IB,A_BI,A_BB; 3862a155e38SStefano Zampini Mat AE_II,*AE_IE,*AE_EI,*AE_EE; 3872a155e38SStefano Zampini IS is_I,*is_subset_B; 3882a155e38SStefano Zampini ISLocalToGlobalMapping BtoNmap; 3892a155e38SStefano Zampini PetscInt i; 39034a97f8cSStefano Zampini PetscBool is_sorted; 39134a97f8cSStefano Zampini PetscErrorCode ierr; 39234a97f8cSStefano Zampini 39334a97f8cSStefano Zampini PetscFunctionBegin; 39434a97f8cSStefano Zampini ierr = ISSorted(is_A_I,&is_sorted);CHKERRQ(ierr); 39534a97f8cSStefano Zampini if (!is_sorted) { 39634a97f8cSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)is_A_I),PETSC_ERR_PLIB,"IS for I dofs should be shorted"); 39734a97f8cSStefano Zampini } 39834a97f8cSStefano Zampini ierr = ISSorted(is_A_B,&is_sorted);CHKERRQ(ierr); 39934a97f8cSStefano Zampini if (!is_sorted) { 40034a97f8cSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)is_A_B),PETSC_ERR_PLIB,"IS for B dofs should be shorted"); 40134a97f8cSStefano Zampini } 40234a97f8cSStefano Zampini 40334a97f8cSStefano Zampini /* get Schur complement matrices */ 40434a97f8cSStefano Zampini ierr = MatSchurComplementGetSubMatrices(S,&A_II,NULL,&A_IB,&A_BI,&A_BB);CHKERRQ(ierr); 40534a97f8cSStefano Zampini 40634a97f8cSStefano Zampini /* allocate space for schur complements */ 40734a97f8cSStefano 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); 4082a155e38SStefano Zampini ierr = PetscMalloc4(ncc,&is_subset_B,ncc,&AE_IE,ncc,&AE_EI,ncc,&AE_EE);CHKERRQ(ierr); 40934a97f8cSStefano Zampini sub_schurs->n_subs = ncc; 41034a97f8cSStefano Zampini 4112a155e38SStefano Zampini /* maps */ 4122a155e38SStefano Zampini if (sub_schurs->n_subs && nlayers >= 0 && xadj != NULL && adjncy != NULL) { /* Interior problems can be different from the original one */ 4132a155e38SStefano Zampini ISLocalToGlobalMapping ItoNmap; 4142a155e38SStefano Zampini PetscBT touched; 41534a97f8cSStefano Zampini const PetscInt* idx_B; 4162a155e38SStefano Zampini PetscInt n_I,n_B,n_local_dofs,n_prev_added,j,layer,*local_numbering; 4172a155e38SStefano Zampini 4182a155e38SStefano Zampini /* get sizes */ 4192a155e38SStefano Zampini ierr = ISGetLocalSize(is_A_I,&n_I);CHKERRQ(ierr); 4202a155e38SStefano Zampini ierr = ISGetLocalSize(is_A_B,&n_B);CHKERRQ(ierr); 4212a155e38SStefano Zampini 4222a155e38SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_A_I,&ItoNmap);CHKERRQ(ierr); 4232a155e38SStefano Zampini ierr = PetscMalloc1(n_I+n_B,&local_numbering);CHKERRQ(ierr); 4242a155e38SStefano Zampini ierr = PetscBTCreate(n_I+n_B,&touched);CHKERRQ(ierr); 4252a155e38SStefano Zampini ierr = PetscBTMemzero(n_I+n_B,touched);CHKERRQ(ierr); 42634a97f8cSStefano Zampini 42734a97f8cSStefano Zampini /* all boundary dofs must be skipped when adding layers */ 42834a97f8cSStefano Zampini ierr = ISGetIndices(is_A_B,&idx_B);CHKERRQ(ierr); 42934a97f8cSStefano Zampini for (j=0;j<n_B;j++) { 43034a97f8cSStefano Zampini ierr = PetscBTSet(touched,idx_B[j]);CHKERRQ(ierr); 43134a97f8cSStefano Zampini } 4322a155e38SStefano Zampini ierr = PetscMemcpy(local_numbering,idx_B,n_B*sizeof(PetscInt));CHKERRQ(ierr); 43334a97f8cSStefano Zampini ierr = ISRestoreIndices(is_A_B,&idx_B);CHKERRQ(ierr); 43434a97f8cSStefano Zampini 43534a97f8cSStefano Zampini /* add next layers of dofs */ 4362a155e38SStefano Zampini n_local_dofs = n_B; 4372a155e38SStefano Zampini n_prev_added = n_B; 43834a97f8cSStefano Zampini for (layer=0;layer<nlayers;layer++) { 43934a97f8cSStefano Zampini PetscInt n_added; 4402a155e38SStefano Zampini if (n_local_dofs == n_I+n_B) break; 4412a155e38SStefano Zampini if (n_local_dofs > n_I+n_B) { 4422a155e38SStefano 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); 44334a97f8cSStefano Zampini } 44434a97f8cSStefano Zampini ierr = PCBDDCAdjGetNextLayer_Private(local_numbering+n_local_dofs,n_prev_added,touched,xadj,adjncy,&n_added);CHKERRQ(ierr); 44534a97f8cSStefano Zampini n_prev_added = n_added; 44634a97f8cSStefano Zampini n_local_dofs += n_added; 4479b0e569cSStefano Zampini if (!n_added) break; 44834a97f8cSStefano Zampini } 4492a155e38SStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 45034a97f8cSStefano Zampini 45134a97f8cSStefano Zampini /* IS for I dofs in original numbering and in I numbering */ 4522a155e38SStefano 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); 4532a155e38SStefano Zampini ierr = PetscFree(local_numbering);CHKERRQ(ierr); 4542a155e38SStefano Zampini ierr = ISSort(sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 4552a155e38SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(ItoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_I[0],&is_I);CHKERRQ(ierr); 4562a155e38SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&ItoNmap);CHKERRQ(ierr); 45734a97f8cSStefano Zampini 45834a97f8cSStefano Zampini /* II block */ 45934a97f8cSStefano Zampini ierr = MatGetSubMatrix(A_II,is_I,is_I,MAT_INITIAL_MATRIX,&AE_II);CHKERRQ(ierr); 4602a155e38SStefano Zampini } else { 4612a155e38SStefano Zampini PetscInt n_I; 4622a155e38SStefano Zampini 46334a97f8cSStefano Zampini /* IS for I dofs in original numbering */ 46434a97f8cSStefano Zampini ierr = PetscObjectReference((PetscObject)is_A_I);CHKERRQ(ierr); 4652a155e38SStefano Zampini sub_schurs->is_AEj_I[0] = is_A_I; 46634a97f8cSStefano Zampini 4672a155e38SStefano Zampini /* IS for I dofs in I numbering (strided 1) */ 4682a155e38SStefano Zampini ierr = ISGetSize(is_A_I,&n_I);CHKERRQ(ierr); 46934a97f8cSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is_A_I),n_I,0,1,&is_I);CHKERRQ(ierr); 47034a97f8cSStefano Zampini 47134a97f8cSStefano Zampini /* II block is the same */ 47234a97f8cSStefano Zampini ierr = PetscObjectReference((PetscObject)A_II);CHKERRQ(ierr); 47334a97f8cSStefano Zampini AE_II = A_II; 47434a97f8cSStefano Zampini } 47534a97f8cSStefano Zampini 4762a155e38SStefano Zampini /* TODO: just for compatibility with the previous version, needs to be fixed */ 4772a155e38SStefano Zampini for (i=1;i<sub_schurs->n_subs;i++) { 4782a155e38SStefano Zampini ierr = PetscObjectReference((PetscObject)sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 4792a155e38SStefano Zampini sub_schurs->is_AEj_I[i] = sub_schurs->is_AEj_I[0]; 4802a155e38SStefano Zampini } 48134a97f8cSStefano Zampini 4822a155e38SStefano Zampini /* subsets in original and boundary numbering */ 4832a155e38SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_A_B,&BtoNmap);CHKERRQ(ierr); 4842a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4852a155e38SStefano Zampini ierr = ISDuplicate(is_cc[i],&sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 4862a155e38SStefano Zampini ierr = ISSort(sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 4872a155e38SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(BtoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_B[i],&is_subset_B[i]);CHKERRQ(ierr); 4882a155e38SStefano Zampini } 4892a155e38SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&BtoNmap);CHKERRQ(ierr); 4902a155e38SStefano Zampini 4912a155e38SStefano Zampini /* EE block */ 4922a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4932a155e38SStefano Zampini ierr = MatGetSubMatrix(A_BB,is_subset_B[i],is_subset_B[i],MAT_INITIAL_MATRIX,&AE_EE[i]);CHKERRQ(ierr); 4942a155e38SStefano Zampini } 4952a155e38SStefano Zampini /* IE block */ 4962a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4972a155e38SStefano Zampini ierr = MatGetSubMatrix(A_IB,is_I,is_subset_B[i],MAT_INITIAL_MATRIX,&AE_IE[i]);CHKERRQ(ierr); 4982a155e38SStefano Zampini } 49934a97f8cSStefano Zampini /* EI block */ 5002a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5012a155e38SStefano Zampini ierr = MatGetSubMatrix(A_BI,is_subset_B[i],is_I,MAT_INITIAL_MATRIX,&AE_EI[i]);CHKERRQ(ierr); 5022a155e38SStefano Zampini } 50334a97f8cSStefano Zampini 50434a97f8cSStefano Zampini /* setup Schur complements on subset */ 5052a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5062a155e38SStefano Zampini ierr = MatCreateSchurComplement(AE_II,AE_II,AE_IE[i],AE_EI[i],AE_EE[i],&sub_schurs->S_Ej[i]);CHKERRQ(ierr); 5078a26ef87SStefano Zampini ierr = MatCreateVecs(sub_schurs->S_Ej[i],&sub_schurs->work1[i],&sub_schurs->work2[i]);CHKERRQ(ierr); 50834a97f8cSStefano Zampini if (AE_II == A_II) { /* we can reuse the same ksp */ 50934a97f8cSStefano Zampini KSP ksp; 51034a97f8cSStefano Zampini ierr = MatSchurComplementGetKSP(S,&ksp);CHKERRQ(ierr); 51134a97f8cSStefano Zampini ierr = MatSchurComplementSetKSP(sub_schurs->S_Ej[i],ksp);CHKERRQ(ierr); 51234a97f8cSStefano Zampini } else { /* build new ksp object which inherits ksp and pc types from the original one */ 51334a97f8cSStefano Zampini KSP origksp,schurksp; 51434a97f8cSStefano Zampini PC origpc,schurpc; 51534a97f8cSStefano Zampini KSPType ksp_type; 51634a97f8cSStefano Zampini PCType pc_type; 51734a97f8cSStefano Zampini PetscInt n_internal; 51834a97f8cSStefano Zampini 51934a97f8cSStefano Zampini ierr = MatSchurComplementGetKSP(S,&origksp);CHKERRQ(ierr); 52034a97f8cSStefano Zampini ierr = MatSchurComplementGetKSP(sub_schurs->S_Ej[i],&schurksp);CHKERRQ(ierr); 52134a97f8cSStefano Zampini ierr = KSPGetType(origksp,&ksp_type);CHKERRQ(ierr); 52234a97f8cSStefano Zampini ierr = KSPSetType(schurksp,ksp_type);CHKERRQ(ierr); 52334a97f8cSStefano Zampini ierr = KSPGetPC(schurksp,&schurpc);CHKERRQ(ierr); 52434a97f8cSStefano Zampini ierr = KSPGetPC(origksp,&origpc);CHKERRQ(ierr); 52534a97f8cSStefano Zampini ierr = PCGetType(origpc,&pc_type);CHKERRQ(ierr); 52634a97f8cSStefano Zampini ierr = PCSetType(schurpc,pc_type);CHKERRQ(ierr); 52734a97f8cSStefano Zampini ierr = ISGetSize(is_I,&n_internal);CHKERRQ(ierr); 52834a97f8cSStefano Zampini if (n_internal) { /* UMFPACK gives error with 0 sized problems */ 52934a97f8cSStefano Zampini MatSolverPackage solver=NULL; 53034a97f8cSStefano Zampini ierr = PCFactorGetMatSolverPackage(origpc,(const MatSolverPackage*)&solver);CHKERRQ(ierr); 53134a97f8cSStefano Zampini if (solver) { 53234a97f8cSStefano Zampini ierr = PCFactorSetMatSolverPackage(schurpc,solver);CHKERRQ(ierr); 53334a97f8cSStefano Zampini } 53434a97f8cSStefano Zampini } 53534a97f8cSStefano Zampini ierr = KSPSetUp(schurksp);CHKERRQ(ierr); 53634a97f8cSStefano Zampini } 53734a97f8cSStefano Zampini } 53834a97f8cSStefano Zampini /* free */ 5392a155e38SStefano Zampini ierr = ISDestroy(&is_I);CHKERRQ(ierr); 5402a155e38SStefano Zampini ierr = MatDestroy(&AE_II);CHKERRQ(ierr); 5412a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5422a155e38SStefano Zampini ierr = MatDestroy(&AE_EE[i]);CHKERRQ(ierr); 5432a155e38SStefano Zampini ierr = MatDestroy(&AE_IE[i]);CHKERRQ(ierr); 5442a155e38SStefano Zampini ierr = MatDestroy(&AE_EI[i]);CHKERRQ(ierr); 5452a155e38SStefano Zampini ierr = ISDestroy(&is_subset_B[i]);CHKERRQ(ierr); 5462a155e38SStefano Zampini } 5472a155e38SStefano Zampini ierr = PetscFree4(is_subset_B,AE_IE,AE_EI,AE_EE);CHKERRQ(ierr); 54834a97f8cSStefano Zampini PetscFunctionReturn(0); 54934a97f8cSStefano Zampini } 550