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__ 7b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCSubSchursSetUpNew" 8b1b3d7a2SStefano Zampini PetscErrorCode PCBDDCSubSchursSetUpNew(PCBDDCSubSchurs sub_schurs, PetscInt xadj[], PetscInt adjncy[], PetscInt nlayers) 9b1b3d7a2SStefano Zampini { 10b1b3d7a2SStefano Zampini Mat A_II,A_IB,A_BI,A_BB; 11b1b3d7a2SStefano Zampini Mat AE_II,*AE_IE,*AE_EI,*AE_EE; 12b1b3d7a2SStefano Zampini IS is_I,*is_subset_B; 13b1b3d7a2SStefano Zampini ISLocalToGlobalMapping BtoNmap; 14b1b3d7a2SStefano Zampini PetscInt i; 15b1b3d7a2SStefano Zampini PetscBool implicit_schurs; 16b1b3d7a2SStefano Zampini PetscErrorCode ierr; 17b1b3d7a2SStefano Zampini 18b1b3d7a2SStefano Zampini PetscFunctionBegin; 19b1b3d7a2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)sub_schurs->S,MATSCHURCOMPLEMENT,&implicit_schurs);CHKERRQ(ierr); 20b1b3d7a2SStefano Zampini 21b1b3d7a2SStefano Zampini /* allocate space for schur complements */ 22b1b3d7a2SStefano Zampini ierr = PetscMalloc5(sub_schurs->n_subs,&sub_schurs->is_AEj_I, 23b1b3d7a2SStefano Zampini sub_schurs->n_subs,&sub_schurs->is_AEj_B, 24b1b3d7a2SStefano Zampini sub_schurs->n_subs,&sub_schurs->S_Ej, 25b1b3d7a2SStefano Zampini sub_schurs->n_subs,&sub_schurs->work1, 26b1b3d7a2SStefano Zampini sub_schurs->n_subs,&sub_schurs->work2);CHKERRQ(ierr); 27b1b3d7a2SStefano Zampini 28b1b3d7a2SStefano Zampini /* get Schur complement matrices */ 29b1b3d7a2SStefano Zampini if (implicit_schurs) { 30b1b3d7a2SStefano Zampini ierr = MatSchurComplementGetSubMatrices(sub_schurs->S,&A_II,NULL,&A_IB,&A_BI,&A_BB);CHKERRQ(ierr); 31b1b3d7a2SStefano Zampini ierr = PetscMalloc4(sub_schurs->n_subs,&is_subset_B, 32b1b3d7a2SStefano Zampini sub_schurs->n_subs,&AE_IE, 33b1b3d7a2SStefano Zampini sub_schurs->n_subs,&AE_EI, 34b1b3d7a2SStefano Zampini sub_schurs->n_subs,&AE_EE);CHKERRQ(ierr); 35b1b3d7a2SStefano Zampini } 36b1b3d7a2SStefano Zampini 37b1b3d7a2SStefano Zampini /* determine interior problems */ 38b1b3d7a2SStefano Zampini if (nlayers >= 0 && xadj != NULL && adjncy != NULL) { /* Interior problems can be different from the original one */ 39b1b3d7a2SStefano Zampini PetscBT touched; 40b1b3d7a2SStefano Zampini const PetscInt* idx_B; 41b1b3d7a2SStefano Zampini PetscInt n_I,n_B,n_local_dofs,n_prev_added,j,layer,*local_numbering; 42b1b3d7a2SStefano Zampini 43b1b3d7a2SStefano Zampini /* get sizes */ 44b1b3d7a2SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_I,&n_I);CHKERRQ(ierr); 45b1b3d7a2SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_B,&n_B);CHKERRQ(ierr); 46b1b3d7a2SStefano Zampini 47b1b3d7a2SStefano Zampini ierr = PetscMalloc1(n_I+n_B,&local_numbering);CHKERRQ(ierr); 48b1b3d7a2SStefano Zampini ierr = PetscBTCreate(n_I+n_B,&touched);CHKERRQ(ierr); 49b1b3d7a2SStefano Zampini ierr = PetscBTMemzero(n_I+n_B,touched);CHKERRQ(ierr); 50b1b3d7a2SStefano Zampini 51b1b3d7a2SStefano Zampini /* all boundary dofs must be skipped when adding layers */ 52b1b3d7a2SStefano Zampini ierr = ISGetIndices(sub_schurs->is_B,&idx_B);CHKERRQ(ierr); 53b1b3d7a2SStefano Zampini for (j=0;j<n_B;j++) { 54b1b3d7a2SStefano Zampini ierr = PetscBTSet(touched,idx_B[j]);CHKERRQ(ierr); 55b1b3d7a2SStefano Zampini } 56b1b3d7a2SStefano Zampini ierr = PetscMemcpy(local_numbering,idx_B,n_B*sizeof(PetscInt));CHKERRQ(ierr); 57b1b3d7a2SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_B,&idx_B);CHKERRQ(ierr); 58b1b3d7a2SStefano Zampini 59b1b3d7a2SStefano Zampini /* add prescribed number of layers of dofs */ 60b1b3d7a2SStefano Zampini n_local_dofs = n_B; 61b1b3d7a2SStefano Zampini n_prev_added = n_B; 62b1b3d7a2SStefano Zampini for (layer=0;layer<nlayers;layer++) { 63b1b3d7a2SStefano Zampini PetscInt n_added; 64b1b3d7a2SStefano Zampini if (n_local_dofs == n_I+n_B) break; 65b1b3d7a2SStefano Zampini if (n_local_dofs > n_I+n_B) { 66b1b3d7a2SStefano 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); 67b1b3d7a2SStefano Zampini } 68b1b3d7a2SStefano Zampini ierr = PCBDDCAdjGetNextLayer_Private(local_numbering+n_local_dofs,n_prev_added,touched,xadj,adjncy,&n_added);CHKERRQ(ierr); 69b1b3d7a2SStefano Zampini n_prev_added = n_added; 70b1b3d7a2SStefano Zampini n_local_dofs += n_added; 71b1b3d7a2SStefano Zampini if (!n_added) break; 72b1b3d7a2SStefano Zampini } 73b1b3d7a2SStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 74b1b3d7a2SStefano Zampini 75b1b3d7a2SStefano Zampini /* IS for I dofs in original numbering */ 76b1b3d7a2SStefano 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); 77b1b3d7a2SStefano Zampini ierr = PetscFree(local_numbering);CHKERRQ(ierr); 78b1b3d7a2SStefano Zampini ierr = ISSort(sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 79b1b3d7a2SStefano Zampini /* IS for I dofs in boundary numbering */ 80b1b3d7a2SStefano Zampini if (implicit_schurs) { 81b1b3d7a2SStefano Zampini ISLocalToGlobalMapping ItoNmap; 82b1b3d7a2SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(sub_schurs->is_I,&ItoNmap);CHKERRQ(ierr); 83b1b3d7a2SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(ItoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_I[0],&is_I);CHKERRQ(ierr); 84b1b3d7a2SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&ItoNmap);CHKERRQ(ierr); 85b1b3d7a2SStefano Zampini 86b1b3d7a2SStefano Zampini /* II block */ 87b1b3d7a2SStefano Zampini ierr = MatGetSubMatrix(A_II,is_I,is_I,MAT_INITIAL_MATRIX,&AE_II);CHKERRQ(ierr); 88b1b3d7a2SStefano Zampini } 89b1b3d7a2SStefano Zampini } else { 90b1b3d7a2SStefano Zampini PetscInt n_I; 91b1b3d7a2SStefano Zampini 92b1b3d7a2SStefano Zampini /* IS for I dofs in original numbering */ 93b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)sub_schurs->is_I);CHKERRQ(ierr); 94b1b3d7a2SStefano Zampini sub_schurs->is_AEj_I[0] = sub_schurs->is_I; 95b1b3d7a2SStefano Zampini 96b1b3d7a2SStefano Zampini /* IS for I dofs in I numbering (strided 1) */ 97b1b3d7a2SStefano Zampini if (implicit_schurs) { 98b1b3d7a2SStefano Zampini ierr = ISGetSize(sub_schurs->is_I,&n_I);CHKERRQ(ierr); 99b1b3d7a2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)sub_schurs->is_I),n_I,0,1,&is_I);CHKERRQ(ierr); 100b1b3d7a2SStefano Zampini 101b1b3d7a2SStefano Zampini /* II block is the same */ 102b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)A_II);CHKERRQ(ierr); 103b1b3d7a2SStefano Zampini AE_II = A_II; 104b1b3d7a2SStefano Zampini } 105b1b3d7a2SStefano Zampini } 106b1b3d7a2SStefano Zampini 107b1b3d7a2SStefano Zampini /* TODO: just for compatibility with the previous version, needs to be fixed */ 108b1b3d7a2SStefano Zampini for (i=1;i<sub_schurs->n_subs;i++) { 109b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 110b1b3d7a2SStefano Zampini sub_schurs->is_AEj_I[i] = sub_schurs->is_AEj_I[0]; 111b1b3d7a2SStefano Zampini } 112b1b3d7a2SStefano Zampini 113b1b3d7a2SStefano Zampini if (implicit_schurs) { 114b1b3d7a2SStefano Zampini /* subsets in original and boundary numbering */ 115b1b3d7a2SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(sub_schurs->is_B,&BtoNmap);CHKERRQ(ierr); 116b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 117b1b3d7a2SStefano Zampini ierr = ISDuplicate(sub_schurs->is_subs[i],&sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 118b1b3d7a2SStefano Zampini ierr = ISSort(sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 119b1b3d7a2SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(BtoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_B[i],&is_subset_B[i]);CHKERRQ(ierr); 120b1b3d7a2SStefano Zampini } 121b1b3d7a2SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&BtoNmap);CHKERRQ(ierr); 122b1b3d7a2SStefano Zampini 123b1b3d7a2SStefano Zampini /* EE block */ 124b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 125b1b3d7a2SStefano Zampini ierr = MatGetSubMatrix(A_BB,is_subset_B[i],is_subset_B[i],MAT_INITIAL_MATRIX,&AE_EE[i]);CHKERRQ(ierr); 126b1b3d7a2SStefano Zampini } 127b1b3d7a2SStefano Zampini /* IE block */ 128b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 129b1b3d7a2SStefano Zampini ierr = MatGetSubMatrix(A_IB,is_I,is_subset_B[i],MAT_INITIAL_MATRIX,&AE_IE[i]);CHKERRQ(ierr); 130b1b3d7a2SStefano Zampini } 131b1b3d7a2SStefano Zampini /* EI block */ 132b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 133b1b3d7a2SStefano Zampini ierr = MatGetSubMatrix(A_BI,is_subset_B[i],is_I,MAT_INITIAL_MATRIX,&AE_EI[i]);CHKERRQ(ierr); 134b1b3d7a2SStefano Zampini } 135b1b3d7a2SStefano Zampini 136b1b3d7a2SStefano Zampini /* setup Schur complements on subset */ 137b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 138b1b3d7a2SStefano Zampini ierr = MatCreateSchurComplement(AE_II,AE_II,AE_IE[i],AE_EI[i],AE_EE[i],&sub_schurs->S_Ej[i]);CHKERRQ(ierr); 139b1b3d7a2SStefano Zampini ierr = MatCreateVecs(sub_schurs->S_Ej[i],&sub_schurs->work1[i],&sub_schurs->work2[i]);CHKERRQ(ierr); 140b1b3d7a2SStefano Zampini if (AE_II == A_II) { /* we can reuse the same ksp */ 141b1b3d7a2SStefano Zampini KSP ksp; 142b1b3d7a2SStefano Zampini ierr = MatSchurComplementGetKSP(sub_schurs->S,&ksp);CHKERRQ(ierr); 143b1b3d7a2SStefano Zampini ierr = MatSchurComplementSetKSP(sub_schurs->S_Ej[i],ksp);CHKERRQ(ierr); 144b1b3d7a2SStefano Zampini } else { /* build new ksp object which inherits ksp and pc types from the original one */ 145b1b3d7a2SStefano Zampini KSP origksp,schurksp; 146b1b3d7a2SStefano Zampini PC origpc,schurpc; 147b1b3d7a2SStefano Zampini KSPType ksp_type; 148b1b3d7a2SStefano Zampini PCType pc_type; 149b1b3d7a2SStefano Zampini PetscInt n_internal; 150b1b3d7a2SStefano Zampini 151b1b3d7a2SStefano Zampini ierr = MatSchurComplementGetKSP(sub_schurs->S,&origksp);CHKERRQ(ierr); 152b1b3d7a2SStefano Zampini ierr = MatSchurComplementGetKSP(sub_schurs->S_Ej[i],&schurksp);CHKERRQ(ierr); 153b1b3d7a2SStefano Zampini ierr = KSPGetType(origksp,&ksp_type);CHKERRQ(ierr); 154b1b3d7a2SStefano Zampini ierr = KSPSetType(schurksp,ksp_type);CHKERRQ(ierr); 155b1b3d7a2SStefano Zampini ierr = KSPGetPC(schurksp,&schurpc);CHKERRQ(ierr); 156b1b3d7a2SStefano Zampini ierr = KSPGetPC(origksp,&origpc);CHKERRQ(ierr); 157b1b3d7a2SStefano Zampini ierr = PCGetType(origpc,&pc_type);CHKERRQ(ierr); 158b1b3d7a2SStefano Zampini ierr = PCSetType(schurpc,pc_type);CHKERRQ(ierr); 159b1b3d7a2SStefano Zampini ierr = ISGetSize(is_I,&n_internal);CHKERRQ(ierr); 160b1b3d7a2SStefano Zampini if (n_internal) { /* UMFPACK gives error with 0 sized problems */ 161b1b3d7a2SStefano Zampini MatSolverPackage solver=NULL; 162b1b3d7a2SStefano Zampini ierr = PCFactorGetMatSolverPackage(origpc,(const MatSolverPackage*)&solver);CHKERRQ(ierr); 163b1b3d7a2SStefano Zampini if (solver) { 164b1b3d7a2SStefano Zampini ierr = PCFactorSetMatSolverPackage(schurpc,solver);CHKERRQ(ierr); 165b1b3d7a2SStefano Zampini } 166b1b3d7a2SStefano Zampini } 167b1b3d7a2SStefano Zampini ierr = KSPSetUp(schurksp);CHKERRQ(ierr); 168b1b3d7a2SStefano Zampini } 169b1b3d7a2SStefano Zampini } 170b1b3d7a2SStefano Zampini /* free */ 171b1b3d7a2SStefano Zampini ierr = ISDestroy(&is_I);CHKERRQ(ierr); 172b1b3d7a2SStefano Zampini ierr = MatDestroy(&AE_II);CHKERRQ(ierr); 173b1b3d7a2SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 174b1b3d7a2SStefano Zampini ierr = MatDestroy(&AE_EE[i]);CHKERRQ(ierr); 175b1b3d7a2SStefano Zampini ierr = MatDestroy(&AE_IE[i]);CHKERRQ(ierr); 176b1b3d7a2SStefano Zampini ierr = MatDestroy(&AE_EI[i]);CHKERRQ(ierr); 177b1b3d7a2SStefano Zampini ierr = ISDestroy(&is_subset_B[i]);CHKERRQ(ierr); 178b1b3d7a2SStefano Zampini } 179b1b3d7a2SStefano Zampini ierr = PetscFree4(is_subset_B,AE_IE,AE_EI,AE_EE);CHKERRQ(ierr); 180b1b3d7a2SStefano Zampini } 181b1b3d7a2SStefano Zampini PetscFunctionReturn(0); 182b1b3d7a2SStefano Zampini } 183b1b3d7a2SStefano Zampini 184b1b3d7a2SStefano Zampini #undef __FUNCT__ 185b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCSubSchursInit" 1861e9c79c2SStefano Zampini PetscErrorCode PCBDDCSubSchursInit(PCBDDCSubSchurs sub_schurs, Mat A, Mat S, IS is_I, IS is_B, PCBDDCGraph graph, PetscInt seqthreshold) 187b1b3d7a2SStefano Zampini { 188b1b3d7a2SStefano Zampini IS *faces,*edges,*all_cc; 189b1b3d7a2SStefano Zampini PetscInt *index_sequential,*index_parallel; 190b1b3d7a2SStefano Zampini PetscInt *auxlocal_sequential,*auxlocal_parallel; 191b1b3d7a2SStefano Zampini PetscInt *auxglobal_sequential,*auxglobal_parallel; 192b1b3d7a2SStefano Zampini PetscInt *auxmapping;//,*idxs; 193b1b3d7a2SStefano Zampini PetscInt i,max_subset_size; 194b1b3d7a2SStefano Zampini PetscInt n_sequential_problems,n_local_sequential_problems,n_parallel_problems,n_local_parallel_problems; 195b1b3d7a2SStefano Zampini PetscInt n_faces,n_edges,n_all_cc; 196b1b3d7a2SStefano Zampini PetscBool is_sorted; 197b1b3d7a2SStefano Zampini PetscErrorCode ierr; 198b1b3d7a2SStefano Zampini 199b1b3d7a2SStefano Zampini PetscFunctionBegin; 200b1b3d7a2SStefano Zampini ierr = ISSorted(is_I,&is_sorted);CHKERRQ(ierr); 201b1b3d7a2SStefano Zampini if (!is_sorted) { 202b1b3d7a2SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)is_I),PETSC_ERR_PLIB,"IS for I dofs should be shorted"); 203b1b3d7a2SStefano Zampini } 204b1b3d7a2SStefano Zampini ierr = ISSorted(is_B,&is_sorted);CHKERRQ(ierr); 205b1b3d7a2SStefano Zampini if (!is_sorted) { 206b1b3d7a2SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)is_B),PETSC_ERR_PLIB,"IS for B dofs should be shorted"); 207b1b3d7a2SStefano Zampini } 208b1b3d7a2SStefano Zampini 209b1b3d7a2SStefano Zampini /* reset any previous data */ 210b1b3d7a2SStefano Zampini ierr = PCBDDCSubSchursReset(sub_schurs);CHKERRQ(ierr); 211b1b3d7a2SStefano Zampini 212b1b3d7a2SStefano Zampini /* get index sets for faces and edges */ 213b1b3d7a2SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&n_faces,&faces,&n_edges,&edges,NULL);CHKERRQ(ierr); 214b1b3d7a2SStefano Zampini n_all_cc = n_faces+n_edges; 215b1b3d7a2SStefano Zampini ierr = PetscMalloc1(n_all_cc,&all_cc);CHKERRQ(ierr); 216b1b3d7a2SStefano Zampini for (i=0;i<n_faces;i++) { 217b1b3d7a2SStefano Zampini all_cc[i] = faces[i]; 218b1b3d7a2SStefano Zampini } 219b1b3d7a2SStefano Zampini for (i=0;i<n_edges;i++) { 220b1b3d7a2SStefano Zampini all_cc[n_faces+i] = edges[i]; 221b1b3d7a2SStefano Zampini } 222b1b3d7a2SStefano Zampini ierr = PetscFree(faces);CHKERRQ(ierr); 223b1b3d7a2SStefano Zampini ierr = PetscFree(edges);CHKERRQ(ierr); 224b1b3d7a2SStefano Zampini 225b1b3d7a2SStefano Zampini /* map interface's subsets */ 226b1b3d7a2SStefano Zampini max_subset_size = 0; 227b1b3d7a2SStefano Zampini for (i=0;i<n_all_cc;i++) { 228b1b3d7a2SStefano Zampini PetscInt subset_size; 229b1b3d7a2SStefano Zampini ierr = ISGetLocalSize(all_cc[i],&subset_size);CHKERRQ(ierr); 230b1b3d7a2SStefano Zampini max_subset_size = PetscMax(max_subset_size,subset_size); 231b1b3d7a2SStefano Zampini } 232b1b3d7a2SStefano Zampini ierr = PetscMalloc1(max_subset_size,&auxmapping);CHKERRQ(ierr); 233b1b3d7a2SStefano Zampini ierr = PetscMalloc2(graph->ncc,&auxlocal_sequential, 234b1b3d7a2SStefano Zampini graph->ncc,&auxlocal_parallel);CHKERRQ(ierr); 235b1b3d7a2SStefano Zampini ierr = PetscMalloc2(graph->ncc,&index_sequential, 236b1b3d7a2SStefano Zampini graph->ncc,&index_parallel);CHKERRQ(ierr); 237b1b3d7a2SStefano Zampini 238b1b3d7a2SStefano Zampini /* if threshold is negative, uses all sequential problems */ 239b1b3d7a2SStefano Zampini if (seqthreshold < 0) seqthreshold = max_subset_size; 240b1b3d7a2SStefano Zampini 241b1b3d7a2SStefano Zampini /* determine which problem has to be solved in parallel or sequentially */ 242b1b3d7a2SStefano Zampini n_local_sequential_problems = 0; 243b1b3d7a2SStefano Zampini n_local_parallel_problems = 0; 244b1b3d7a2SStefano Zampini for (i=0;i<n_all_cc;i++) { 245b1b3d7a2SStefano Zampini PetscInt subset_size,j,min_loc = 0; 246b1b3d7a2SStefano Zampini const PetscInt *idxs; 247b1b3d7a2SStefano Zampini 248b1b3d7a2SStefano Zampini ierr = ISGetLocalSize(all_cc[i],&subset_size);CHKERRQ(ierr); 249b1b3d7a2SStefano Zampini ierr = ISGetIndices(all_cc[i],&idxs);CHKERRQ(ierr); 250b1b3d7a2SStefano Zampini ierr = ISLocalToGlobalMappingApply(graph->l2gmap,subset_size,idxs,auxmapping);CHKERRQ(ierr); 251b1b3d7a2SStefano Zampini for (j=1;j<subset_size;j++) { 252b1b3d7a2SStefano Zampini if (auxmapping[j]<auxmapping[min_loc]) { 253b1b3d7a2SStefano Zampini min_loc = j; 254b1b3d7a2SStefano Zampini } 255b1b3d7a2SStefano Zampini } 256b1b3d7a2SStefano Zampini if (subset_size > seqthreshold) { 257b1b3d7a2SStefano Zampini index_parallel[n_local_parallel_problems] = i; 258b1b3d7a2SStefano Zampini auxlocal_parallel[n_local_parallel_problems] = idxs[min_loc]; 259b1b3d7a2SStefano Zampini n_local_parallel_problems++; 260b1b3d7a2SStefano Zampini } else { 261b1b3d7a2SStefano Zampini index_sequential[n_local_sequential_problems] = i; 262b1b3d7a2SStefano Zampini auxlocal_sequential[n_local_sequential_problems] = idxs[min_loc]; 263b1b3d7a2SStefano Zampini n_local_sequential_problems++; 264b1b3d7a2SStefano Zampini } 265b1b3d7a2SStefano Zampini ierr = ISRestoreIndices(all_cc[i],&idxs);CHKERRQ(ierr); 266b1b3d7a2SStefano Zampini } 267b1b3d7a2SStefano Zampini 268b1b3d7a2SStefano Zampini /* Number parallel problems */ 269b1b3d7a2SStefano Zampini auxglobal_parallel = 0; 270b1b3d7a2SStefano Zampini ierr = PCBDDCSubsetNumbering(PetscObjectComm((PetscObject)graph->l2gmap),graph->l2gmap,n_local_parallel_problems,auxlocal_parallel,PETSC_NULL,&n_parallel_problems,&auxglobal_parallel);CHKERRQ(ierr); 271b1b3d7a2SStefano Zampini 272b1b3d7a2SStefano Zampini /* Number sequential problems */ 273b1b3d7a2SStefano Zampini auxglobal_sequential = 0; 274b1b3d7a2SStefano Zampini ierr = PCBDDCSubsetNumbering(PetscObjectComm((PetscObject)graph->l2gmap),graph->l2gmap,n_local_sequential_problems,auxlocal_sequential,PETSC_NULL,&n_sequential_problems,&auxglobal_sequential);CHKERRQ(ierr); 275b1b3d7a2SStefano Zampini 276b1b3d7a2SStefano Zampini /* update info in sub_schurs */ 2771e9c79c2SStefano Zampini if (A) { 2781e9c79c2SStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 2791e9c79c2SStefano Zampini sub_schurs->A = A; 2801e9c79c2SStefano Zampini } 281b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)S);CHKERRQ(ierr); 282b1b3d7a2SStefano Zampini sub_schurs->S = S; 283b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)is_I);CHKERRQ(ierr); 284b1b3d7a2SStefano Zampini sub_schurs->is_I = is_I; 285b1b3d7a2SStefano Zampini ierr = PetscObjectReference((PetscObject)is_B);CHKERRQ(ierr); 286b1b3d7a2SStefano Zampini sub_schurs->is_B = is_B; 287b1b3d7a2SStefano Zampini sub_schurs->n_subs_seq = n_local_sequential_problems; 288b1b3d7a2SStefano Zampini sub_schurs->n_subs_par = n_local_parallel_problems; 289b1b3d7a2SStefano Zampini sub_schurs->n_subs_seq_g = n_sequential_problems; 290b1b3d7a2SStefano Zampini sub_schurs->n_subs_par_g = n_parallel_problems; 291b1b3d7a2SStefano Zampini sub_schurs->n_subs = sub_schurs->n_subs_seq + sub_schurs->n_subs_par; 292b1b3d7a2SStefano Zampini sub_schurs->is_subs = all_cc; 293b1b3d7a2SStefano Zampini sub_schurs->index_sequential = index_sequential; 294b1b3d7a2SStefano Zampini sub_schurs->index_parallel = index_parallel; 295b1b3d7a2SStefano Zampini sub_schurs->auxglobal_sequential = auxglobal_sequential; 296b1b3d7a2SStefano Zampini sub_schurs->auxglobal_parallel = auxglobal_parallel; 297b1b3d7a2SStefano Zampini 298b1b3d7a2SStefano Zampini /* free workspace */ 299b1b3d7a2SStefano Zampini ierr = PetscFree(auxmapping);CHKERRQ(ierr); 300b1b3d7a2SStefano Zampini ierr = PetscFree2(auxlocal_sequential,auxlocal_parallel);CHKERRQ(ierr); 301b1b3d7a2SStefano Zampini 302b1b3d7a2SStefano Zampini PetscFunctionReturn(0); 303b1b3d7a2SStefano Zampini } 304b1b3d7a2SStefano Zampini 305b1b3d7a2SStefano Zampini #undef __FUNCT__ 30634a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursCreate" 30734a97f8cSStefano Zampini PetscErrorCode PCBDDCSubSchursCreate(PCBDDCSubSchurs *sub_schurs) 30834a97f8cSStefano Zampini { 30934a97f8cSStefano Zampini PCBDDCSubSchurs schurs_ctx; 31034a97f8cSStefano Zampini PetscErrorCode ierr; 31134a97f8cSStefano Zampini 31234a97f8cSStefano Zampini PetscFunctionBegin; 31334a97f8cSStefano Zampini ierr = PetscNew(&schurs_ctx);CHKERRQ(ierr); 3145ff63025SStefano Zampini schurs_ctx->n_subs = 0; 31534a97f8cSStefano Zampini *sub_schurs = schurs_ctx; 31634a97f8cSStefano Zampini PetscFunctionReturn(0); 31734a97f8cSStefano Zampini } 31834a97f8cSStefano Zampini 31934a97f8cSStefano Zampini #undef __FUNCT__ 32034a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursDestroy" 32134a97f8cSStefano Zampini PetscErrorCode PCBDDCSubSchursDestroy(PCBDDCSubSchurs *sub_schurs) 32234a97f8cSStefano Zampini { 32334a97f8cSStefano Zampini PetscErrorCode ierr; 32434a97f8cSStefano Zampini 32534a97f8cSStefano Zampini PetscFunctionBegin; 32634a97f8cSStefano Zampini ierr = PCBDDCSubSchursReset(*sub_schurs);CHKERRQ(ierr); 32734a97f8cSStefano Zampini ierr = PetscFree(*sub_schurs);CHKERRQ(ierr); 32834a97f8cSStefano Zampini PetscFunctionReturn(0); 32934a97f8cSStefano Zampini } 33034a97f8cSStefano Zampini 33134a97f8cSStefano Zampini #undef __FUNCT__ 33234a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursReset" 33334a97f8cSStefano Zampini PetscErrorCode PCBDDCSubSchursReset(PCBDDCSubSchurs sub_schurs) 33434a97f8cSStefano Zampini { 33534a97f8cSStefano Zampini PetscInt i; 33634a97f8cSStefano Zampini PetscErrorCode ierr; 33734a97f8cSStefano Zampini 33834a97f8cSStefano Zampini PetscFunctionBegin; 3391e9c79c2SStefano Zampini ierr = MatDestroy(&sub_schurs->A);CHKERRQ(ierr); 340b1b3d7a2SStefano Zampini ierr = MatDestroy(&sub_schurs->S);CHKERRQ(ierr); 341b1b3d7a2SStefano Zampini ierr = ISDestroy(&sub_schurs->is_I);CHKERRQ(ierr); 342b1b3d7a2SStefano Zampini ierr = ISDestroy(&sub_schurs->is_B);CHKERRQ(ierr); 343*41c3ba1bSStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 344*41c3ba1bSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 34534a97f8cSStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 346b1b3d7a2SStefano Zampini ierr = ISDestroy(&sub_schurs->is_subs[i]);CHKERRQ(ierr); 34734a97f8cSStefano Zampini ierr = ISDestroy(&sub_schurs->is_AEj_I[i]);CHKERRQ(ierr); 34834a97f8cSStefano Zampini ierr = ISDestroy(&sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 34934a97f8cSStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej[i]);CHKERRQ(ierr); 35034a97f8cSStefano Zampini ierr = VecDestroy(&sub_schurs->work1[i]);CHKERRQ(ierr); 35134a97f8cSStefano Zampini ierr = VecDestroy(&sub_schurs->work2[i]);CHKERRQ(ierr); 35234a97f8cSStefano Zampini } 3535ff63025SStefano Zampini if (sub_schurs->n_subs) { 354b1b3d7a2SStefano Zampini ierr = PetscFree(sub_schurs->is_subs);CHKERRQ(ierr); 35534a97f8cSStefano 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); 356b1b3d7a2SStefano Zampini ierr = PetscFree2(sub_schurs->index_sequential,sub_schurs->index_parallel);CHKERRQ(ierr); 357b1b3d7a2SStefano Zampini ierr = PetscFree(sub_schurs->auxglobal_sequential);CHKERRQ(ierr); 358b1b3d7a2SStefano Zampini ierr = PetscFree(sub_schurs->auxglobal_parallel);CHKERRQ(ierr); 3595ff63025SStefano Zampini } 36034a97f8cSStefano Zampini sub_schurs->n_subs = 0; 36134a97f8cSStefano Zampini PetscFunctionReturn(0); 36234a97f8cSStefano Zampini } 36334a97f8cSStefano Zampini 36434a97f8cSStefano Zampini #undef __FUNCT__ 36534a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCAdjGetNextLayer_Private" 3662a155e38SStefano Zampini PETSC_STATIC_INLINE PetscErrorCode PCBDDCAdjGetNextLayer_Private(PetscInt* queue_tip,PetscInt n_prev,PetscBT touched,PetscInt* xadj,PetscInt* adjncy,PetscInt* n_added) 36734a97f8cSStefano Zampini { 36834a97f8cSStefano Zampini PetscInt i,j,n; 36934a97f8cSStefano Zampini PetscErrorCode ierr; 37034a97f8cSStefano Zampini 37134a97f8cSStefano Zampini PetscFunctionBegin; 37234a97f8cSStefano Zampini n = 0; 37334a97f8cSStefano Zampini for (i=-n_prev;i<0;i++) { 37434a97f8cSStefano Zampini PetscInt start_dof = queue_tip[i]; 37534a97f8cSStefano Zampini for (j=xadj[start_dof];j<xadj[start_dof+1];j++) { 37634a97f8cSStefano Zampini PetscInt dof = adjncy[j]; 37734a97f8cSStefano Zampini if (!PetscBTLookup(touched,dof)) { 37834a97f8cSStefano Zampini ierr = PetscBTSet(touched,dof);CHKERRQ(ierr); 37934a97f8cSStefano Zampini queue_tip[n] = dof; 38034a97f8cSStefano Zampini n++; 38134a97f8cSStefano Zampini } 38234a97f8cSStefano Zampini } 38334a97f8cSStefano Zampini } 38434a97f8cSStefano Zampini *n_added = n; 38534a97f8cSStefano Zampini PetscFunctionReturn(0); 38634a97f8cSStefano Zampini } 38734a97f8cSStefano Zampini 38834a97f8cSStefano Zampini #undef __FUNCT__ 38934a97f8cSStefano Zampini #define __FUNCT__ "PCBDDCSubSchursSetUp" 3907821e9e7SStefano 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) 39134a97f8cSStefano Zampini { 39234a97f8cSStefano Zampini Mat A_II,A_IB,A_BI,A_BB; 3932a155e38SStefano Zampini Mat AE_II,*AE_IE,*AE_EI,*AE_EE; 3942a155e38SStefano Zampini IS is_I,*is_subset_B; 3952a155e38SStefano Zampini ISLocalToGlobalMapping BtoNmap; 3962a155e38SStefano Zampini PetscInt i; 39734a97f8cSStefano Zampini PetscBool is_sorted; 39834a97f8cSStefano Zampini PetscErrorCode ierr; 39934a97f8cSStefano Zampini 40034a97f8cSStefano Zampini PetscFunctionBegin; 40134a97f8cSStefano Zampini ierr = ISSorted(is_A_I,&is_sorted);CHKERRQ(ierr); 40234a97f8cSStefano Zampini if (!is_sorted) { 40334a97f8cSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)is_A_I),PETSC_ERR_PLIB,"IS for I dofs should be shorted"); 40434a97f8cSStefano Zampini } 40534a97f8cSStefano Zampini ierr = ISSorted(is_A_B,&is_sorted);CHKERRQ(ierr); 40634a97f8cSStefano Zampini if (!is_sorted) { 40734a97f8cSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)is_A_B),PETSC_ERR_PLIB,"IS for B dofs should be shorted"); 40834a97f8cSStefano Zampini } 40934a97f8cSStefano Zampini 41034a97f8cSStefano Zampini /* get Schur complement matrices */ 41134a97f8cSStefano Zampini ierr = MatSchurComplementGetSubMatrices(S,&A_II,NULL,&A_IB,&A_BI,&A_BB);CHKERRQ(ierr); 41234a97f8cSStefano Zampini 41334a97f8cSStefano Zampini /* allocate space for schur complements */ 414*41c3ba1bSStefano Zampini ierr = PetscMalloc5(sub_schurs->n_subs,&sub_schurs->is_AEj_I, 415*41c3ba1bSStefano Zampini sub_schurs->n_subs,&sub_schurs->is_AEj_B, 416*41c3ba1bSStefano Zampini sub_schurs->n_subs,&sub_schurs->S_Ej, 417*41c3ba1bSStefano Zampini sub_schurs->n_subs,&sub_schurs->work1, 418*41c3ba1bSStefano Zampini sub_schurs->n_subs,&sub_schurs->work2);CHKERRQ(ierr); 4192a155e38SStefano Zampini ierr = PetscMalloc4(ncc,&is_subset_B,ncc,&AE_IE,ncc,&AE_EI,ncc,&AE_EE);CHKERRQ(ierr); 42034a97f8cSStefano Zampini sub_schurs->n_subs = ncc; 42134a97f8cSStefano Zampini 4222a155e38SStefano Zampini /* maps */ 4232a155e38SStefano Zampini if (sub_schurs->n_subs && nlayers >= 0 && xadj != NULL && adjncy != NULL) { /* Interior problems can be different from the original one */ 4242a155e38SStefano Zampini ISLocalToGlobalMapping ItoNmap; 4252a155e38SStefano Zampini PetscBT touched; 42634a97f8cSStefano Zampini const PetscInt* idx_B; 4272a155e38SStefano Zampini PetscInt n_I,n_B,n_local_dofs,n_prev_added,j,layer,*local_numbering; 4282a155e38SStefano Zampini 4292a155e38SStefano Zampini /* get sizes */ 4302a155e38SStefano Zampini ierr = ISGetLocalSize(is_A_I,&n_I);CHKERRQ(ierr); 4312a155e38SStefano Zampini ierr = ISGetLocalSize(is_A_B,&n_B);CHKERRQ(ierr); 4322a155e38SStefano Zampini 4332a155e38SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_A_I,&ItoNmap);CHKERRQ(ierr); 4342a155e38SStefano Zampini ierr = PetscMalloc1(n_I+n_B,&local_numbering);CHKERRQ(ierr); 4352a155e38SStefano Zampini ierr = PetscBTCreate(n_I+n_B,&touched);CHKERRQ(ierr); 4362a155e38SStefano Zampini ierr = PetscBTMemzero(n_I+n_B,touched);CHKERRQ(ierr); 43734a97f8cSStefano Zampini 43834a97f8cSStefano Zampini /* all boundary dofs must be skipped when adding layers */ 43934a97f8cSStefano Zampini ierr = ISGetIndices(is_A_B,&idx_B);CHKERRQ(ierr); 44034a97f8cSStefano Zampini for (j=0;j<n_B;j++) { 44134a97f8cSStefano Zampini ierr = PetscBTSet(touched,idx_B[j]);CHKERRQ(ierr); 44234a97f8cSStefano Zampini } 4432a155e38SStefano Zampini ierr = PetscMemcpy(local_numbering,idx_B,n_B*sizeof(PetscInt));CHKERRQ(ierr); 44434a97f8cSStefano Zampini ierr = ISRestoreIndices(is_A_B,&idx_B);CHKERRQ(ierr); 44534a97f8cSStefano Zampini 44634a97f8cSStefano Zampini /* add next layers of dofs */ 4472a155e38SStefano Zampini n_local_dofs = n_B; 4482a155e38SStefano Zampini n_prev_added = n_B; 44934a97f8cSStefano Zampini for (layer=0;layer<nlayers;layer++) { 45034a97f8cSStefano Zampini PetscInt n_added; 4512a155e38SStefano Zampini if (n_local_dofs == n_I+n_B) break; 4522a155e38SStefano Zampini if (n_local_dofs > n_I+n_B) { 4532a155e38SStefano 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); 45434a97f8cSStefano Zampini } 45534a97f8cSStefano Zampini ierr = PCBDDCAdjGetNextLayer_Private(local_numbering+n_local_dofs,n_prev_added,touched,xadj,adjncy,&n_added);CHKERRQ(ierr); 45634a97f8cSStefano Zampini n_prev_added = n_added; 45734a97f8cSStefano Zampini n_local_dofs += n_added; 4589b0e569cSStefano Zampini if (!n_added) break; 45934a97f8cSStefano Zampini } 4602a155e38SStefano Zampini ierr = PetscBTDestroy(&touched);CHKERRQ(ierr); 46134a97f8cSStefano Zampini 46234a97f8cSStefano Zampini /* IS for I dofs in original numbering and in I numbering */ 4632a155e38SStefano 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); 4642a155e38SStefano Zampini ierr = PetscFree(local_numbering);CHKERRQ(ierr); 4652a155e38SStefano Zampini ierr = ISSort(sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 4662a155e38SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(ItoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_I[0],&is_I);CHKERRQ(ierr); 4672a155e38SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&ItoNmap);CHKERRQ(ierr); 46834a97f8cSStefano Zampini 46934a97f8cSStefano Zampini /* II block */ 47034a97f8cSStefano Zampini ierr = MatGetSubMatrix(A_II,is_I,is_I,MAT_INITIAL_MATRIX,&AE_II);CHKERRQ(ierr); 4712a155e38SStefano Zampini } else { 4722a155e38SStefano Zampini PetscInt n_I; 4732a155e38SStefano Zampini 47434a97f8cSStefano Zampini /* IS for I dofs in original numbering */ 47534a97f8cSStefano Zampini ierr = PetscObjectReference((PetscObject)is_A_I);CHKERRQ(ierr); 4762a155e38SStefano Zampini sub_schurs->is_AEj_I[0] = is_A_I; 47734a97f8cSStefano Zampini 4782a155e38SStefano Zampini /* IS for I dofs in I numbering (strided 1) */ 4792a155e38SStefano Zampini ierr = ISGetSize(is_A_I,&n_I);CHKERRQ(ierr); 48034a97f8cSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)is_A_I),n_I,0,1,&is_I);CHKERRQ(ierr); 48134a97f8cSStefano Zampini 48234a97f8cSStefano Zampini /* II block is the same */ 48334a97f8cSStefano Zampini ierr = PetscObjectReference((PetscObject)A_II);CHKERRQ(ierr); 48434a97f8cSStefano Zampini AE_II = A_II; 48534a97f8cSStefano Zampini } 48634a97f8cSStefano Zampini 4872a155e38SStefano Zampini /* TODO: just for compatibility with the previous version, needs to be fixed */ 4882a155e38SStefano Zampini for (i=1;i<sub_schurs->n_subs;i++) { 4892a155e38SStefano Zampini ierr = PetscObjectReference((PetscObject)sub_schurs->is_AEj_I[0]);CHKERRQ(ierr); 4902a155e38SStefano Zampini sub_schurs->is_AEj_I[i] = sub_schurs->is_AEj_I[0]; 4912a155e38SStefano Zampini } 49234a97f8cSStefano Zampini 4932a155e38SStefano Zampini /* subsets in original and boundary numbering */ 4942a155e38SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_A_B,&BtoNmap);CHKERRQ(ierr); 4952a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 4962a155e38SStefano Zampini ierr = ISDuplicate(is_cc[i],&sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 4972a155e38SStefano Zampini ierr = ISSort(sub_schurs->is_AEj_B[i]);CHKERRQ(ierr); 4982a155e38SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(BtoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_B[i],&is_subset_B[i]);CHKERRQ(ierr); 4992a155e38SStefano Zampini } 5002a155e38SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&BtoNmap);CHKERRQ(ierr); 5012a155e38SStefano Zampini 5022a155e38SStefano Zampini /* EE block */ 5032a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5042a155e38SStefano Zampini ierr = MatGetSubMatrix(A_BB,is_subset_B[i],is_subset_B[i],MAT_INITIAL_MATRIX,&AE_EE[i]);CHKERRQ(ierr); 5052a155e38SStefano Zampini } 5062a155e38SStefano Zampini /* IE block */ 5072a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5082a155e38SStefano Zampini ierr = MatGetSubMatrix(A_IB,is_I,is_subset_B[i],MAT_INITIAL_MATRIX,&AE_IE[i]);CHKERRQ(ierr); 5092a155e38SStefano Zampini } 51034a97f8cSStefano Zampini /* EI block */ 5112a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5122a155e38SStefano Zampini ierr = MatGetSubMatrix(A_BI,is_subset_B[i],is_I,MAT_INITIAL_MATRIX,&AE_EI[i]);CHKERRQ(ierr); 5132a155e38SStefano Zampini } 51434a97f8cSStefano Zampini 51534a97f8cSStefano Zampini /* setup Schur complements on subset */ 5162a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5172a155e38SStefano Zampini ierr = MatCreateSchurComplement(AE_II,AE_II,AE_IE[i],AE_EI[i],AE_EE[i],&sub_schurs->S_Ej[i]);CHKERRQ(ierr); 5188a26ef87SStefano Zampini ierr = MatCreateVecs(sub_schurs->S_Ej[i],&sub_schurs->work1[i],&sub_schurs->work2[i]);CHKERRQ(ierr); 51934a97f8cSStefano Zampini if (AE_II == A_II) { /* we can reuse the same ksp */ 52034a97f8cSStefano Zampini KSP ksp; 52134a97f8cSStefano Zampini ierr = MatSchurComplementGetKSP(S,&ksp);CHKERRQ(ierr); 52234a97f8cSStefano Zampini ierr = MatSchurComplementSetKSP(sub_schurs->S_Ej[i],ksp);CHKERRQ(ierr); 52334a97f8cSStefano Zampini } else { /* build new ksp object which inherits ksp and pc types from the original one */ 52434a97f8cSStefano Zampini KSP origksp,schurksp; 52534a97f8cSStefano Zampini PC origpc,schurpc; 52634a97f8cSStefano Zampini KSPType ksp_type; 52734a97f8cSStefano Zampini PCType pc_type; 52834a97f8cSStefano Zampini PetscInt n_internal; 52934a97f8cSStefano Zampini 53034a97f8cSStefano Zampini ierr = MatSchurComplementGetKSP(S,&origksp);CHKERRQ(ierr); 53134a97f8cSStefano Zampini ierr = MatSchurComplementGetKSP(sub_schurs->S_Ej[i],&schurksp);CHKERRQ(ierr); 53234a97f8cSStefano Zampini ierr = KSPGetType(origksp,&ksp_type);CHKERRQ(ierr); 53334a97f8cSStefano Zampini ierr = KSPSetType(schurksp,ksp_type);CHKERRQ(ierr); 53434a97f8cSStefano Zampini ierr = KSPGetPC(schurksp,&schurpc);CHKERRQ(ierr); 53534a97f8cSStefano Zampini ierr = KSPGetPC(origksp,&origpc);CHKERRQ(ierr); 53634a97f8cSStefano Zampini ierr = PCGetType(origpc,&pc_type);CHKERRQ(ierr); 53734a97f8cSStefano Zampini ierr = PCSetType(schurpc,pc_type);CHKERRQ(ierr); 53834a97f8cSStefano Zampini ierr = ISGetSize(is_I,&n_internal);CHKERRQ(ierr); 53934a97f8cSStefano Zampini if (n_internal) { /* UMFPACK gives error with 0 sized problems */ 54034a97f8cSStefano Zampini MatSolverPackage solver=NULL; 54134a97f8cSStefano Zampini ierr = PCFactorGetMatSolverPackage(origpc,(const MatSolverPackage*)&solver);CHKERRQ(ierr); 54234a97f8cSStefano Zampini if (solver) { 54334a97f8cSStefano Zampini ierr = PCFactorSetMatSolverPackage(schurpc,solver);CHKERRQ(ierr); 54434a97f8cSStefano Zampini } 54534a97f8cSStefano Zampini } 54634a97f8cSStefano Zampini ierr = KSPSetUp(schurksp);CHKERRQ(ierr); 54734a97f8cSStefano Zampini } 54834a97f8cSStefano Zampini } 54934a97f8cSStefano Zampini /* free */ 5502a155e38SStefano Zampini ierr = ISDestroy(&is_I);CHKERRQ(ierr); 5512a155e38SStefano Zampini ierr = MatDestroy(&AE_II);CHKERRQ(ierr); 5522a155e38SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 5532a155e38SStefano Zampini ierr = MatDestroy(&AE_EE[i]);CHKERRQ(ierr); 5542a155e38SStefano Zampini ierr = MatDestroy(&AE_IE[i]);CHKERRQ(ierr); 5552a155e38SStefano Zampini ierr = MatDestroy(&AE_EI[i]);CHKERRQ(ierr); 5562a155e38SStefano Zampini ierr = ISDestroy(&is_subset_B[i]);CHKERRQ(ierr); 5572a155e38SStefano Zampini } 5582a155e38SStefano Zampini ierr = PetscFree4(is_subset_B,AE_IE,AE_EI,AE_EE);CHKERRQ(ierr); 55934a97f8cSStefano Zampini PetscFunctionReturn(0); 56034a97f8cSStefano Zampini } 561