153cdbc3dSStefano Zampini /* TODOLIST 2eb97c9d2SStefano Zampini 3eb97c9d2SStefano Zampini Solvers 4a0d3c3abSStefano Zampini - Add support for cholesky for coarse solver (similar to local solvers) 5eb97c9d2SStefano Zampini - Propagate ksp prefixes for solvers to mat objects? 6eb97c9d2SStefano Zampini 7eb97c9d2SStefano Zampini User interface 80f202f7eSStefano Zampini - ** DM attached to pc? 9eb97c9d2SStefano Zampini 10eb97c9d2SStefano Zampini Debugging output 11b9b85e73SStefano Zampini - * Better management of verbosity levels of debugging output 12eb97c9d2SStefano Zampini 13eb97c9d2SStefano Zampini Extra 14b9b85e73SStefano Zampini - *** Is it possible to work with PCBDDCGraph on boundary indices only (less memory consumed)? 15eb97c9d2SStefano Zampini - BDDC with MG framework? 16eb97c9d2SStefano Zampini 17eb97c9d2SStefano Zampini FETIDP 18eb97c9d2SStefano Zampini - Move FETIDP code to its own classes 19eb97c9d2SStefano Zampini 20eb97c9d2SStefano Zampini MATIS related operations contained in BDDC code 21eb97c9d2SStefano Zampini - Provide general case for subassembling 22eb97c9d2SStefano Zampini 2353cdbc3dSStefano Zampini */ 240c7d97c5SJed Brown 25ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 26ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 273b03a366Sstefano_zampini #include <petscblaslapack.h> 28674ae819SStefano Zampini 290369aaf7SStefano Zampini /* temporarily declare it */ 300369aaf7SStefano Zampini PetscErrorCode PCApply_BDDC(PC,Vec,Vec); 310369aaf7SStefano Zampini 320c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 330c7d97c5SJed Brown #undef __FUNCT__ 340c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 358c34d3f5SBarry Smith PetscErrorCode PCSetFromOptions_BDDC(PetscOptions *PetscOptionsObject,PC pc) 360c7d97c5SJed Brown { 370c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 380c7d97c5SJed Brown PetscErrorCode ierr; 390c7d97c5SJed Brown 400c7d97c5SJed Brown PetscFunctionBegin; 41e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"BDDC options");CHKERRQ(ierr); 428eeda7d8SStefano Zampini /* Verbose debugging */ 438eeda7d8SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 448eeda7d8SStefano Zampini /* Primal space cumstomization */ 4508a5cf49SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_local_mat_graph","Use or not adjacency graph of local mat for interface analysis","none",pcbddc->use_local_adj,&pcbddc->use_local_adj,NULL);CHKERRQ(ierr); 468eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_vertices","Use or not corner dofs in coarse space","none",pcbddc->use_vertices,&pcbddc->use_vertices,NULL);CHKERRQ(ierr); 478eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_edges","Use or not edge constraints in coarse space","none",pcbddc->use_edges,&pcbddc->use_edges,NULL);CHKERRQ(ierr); 488eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_faces","Use or not face constraints in coarse space","none",pcbddc->use_faces,&pcbddc->use_faces,NULL);CHKERRQ(ierr); 49*14f95afaSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_vertex_size","Connected components smaller or equal to vertex size will be considered as primal vertices","none",pcbddc->vertex_size,&pcbddc->vertex_size,NULL);CHKERRQ(ierr); 506661aa1dSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_true_nnsp","Use near null space attached to the matrix without modifications","none",pcbddc->use_nnsp_true,&pcbddc->use_nnsp_true,NULL);CHKERRQ(ierr); 51*14f95afaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_qr_single","Use QR factorization for single constraints on cc (QR is always used when multiple constraints are present)","none",pcbddc->use_qr_single,&pcbddc->use_qr_single,NULL);CHKERRQ(ierr); 528eeda7d8SStefano Zampini /* Change of basis */ 53b9b85e73SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_of_basis","Use or not internal change of basis on local edge nodes","none",pcbddc->use_change_of_basis,&pcbddc->use_change_of_basis,NULL);CHKERRQ(ierr); 54b9b85e73SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_on_faces","Use or not internal change of basis on local face nodes","none",pcbddc->use_change_on_faces,&pcbddc->use_change_on_faces,NULL);CHKERRQ(ierr); 55674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 56674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 57674ae819SStefano Zampini } 588eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 598eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_switch_static","Switch on static condensation ops around the interface preconditioner","none",pcbddc->switch_static,&pcbddc->switch_static,NULL);CHKERRQ(ierr); 6074e2c79eSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_redistribute","Number of procs where to redistribute coarse problem","none",pcbddc->redistribute_coarse,&pcbddc->redistribute_coarse,NULL);CHKERRQ(ierr); 610298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 622b510759SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 63323d395dSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_coarse_estimates","Use estimated eigenvalues for coarse problem","none",pcbddc->use_coarse_estimates,&pcbddc->use_coarse_estimates,NULL);CHKERRQ(ierr); 64674ae819SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_deluxe_scaling","Use deluxe scaling for BDDC","none",pcbddc->use_deluxe_scaling,&pcbddc->use_deluxe_scaling,NULL);CHKERRQ(ierr); 65b96c3477SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_schur_rebuild","Whether or not the interface graph for Schur principal minors has to be rebuilt (i.e. define the interface without any adjacency)","none",pcbddc->sub_schurs_rebuild,&pcbddc->sub_schurs_rebuild,NULL);CHKERRQ(ierr); 66b96c3477SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_schur_layers","Number of dofs' layers for the computation of principal minors (i.e. -1 uses all dofs)","none",pcbddc->sub_schurs_layers,&pcbddc->sub_schurs_layers,NULL);CHKERRQ(ierr); 67b96c3477SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_schur_use_useradj","Whether or not the CSR graph specified by the user should be used for computing successive layers (default is to use adj of local mat)","none",pcbddc->sub_schurs_use_useradj,&pcbddc->sub_schurs_use_useradj,NULL);CHKERRQ(ierr); 68683d3df6SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_schur_exact","Whether or not to use the exact Schur complement instead of the reduced one (which excludes size 1 cc)","none",pcbddc->sub_schurs_exact_schur,&pcbddc->sub_schurs_exact_schur,NULL);CHKERRQ(ierr); 69bf3a8328SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_deluxe_zerorows","Zero rows and columns of deluxe operators associated with primal dofs","none",pcbddc->deluxe_zerorows,&pcbddc->deluxe_zerorows,NULL);CHKERRQ(ierr); 70ac632422SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_deluxe_faster","Faster application of deluxe scaling (requires extra work during setup)","none",pcbddc->faster_deluxe,&pcbddc->faster_deluxe,NULL);CHKERRQ(ierr); 71bf3a8328SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_adaptive_userdefined","Use user-defined constraints (should be attached via MatSetNearNullSpace to pmat) in addition to those adaptively generated","none",pcbddc->adaptive_userdefined,&pcbddc->adaptive_userdefined,NULL);CHKERRQ(ierr); 724c6709b3SStefano Zampini ierr = PetscOptionsReal("-pc_bddc_adaptive_threshold","Threshold to be used for adaptive selection of constraints","none",pcbddc->adaptive_threshold,&pcbddc->adaptive_threshold,NULL);CHKERRQ(ierr); 7308122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 7408122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 753301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 76b0c7d250SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_coarse_adj","Number of processors where to map the coarse adjacency list","none",pcbddc->coarse_adj_red,&pcbddc->coarse_adj_red,NULL);CHKERRQ(ierr); 7706a4e24aSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_benign_trick","Apply the benign subspace trick to a class of saddle point problems","none",pcbddc->benign_saddle_point,&pcbddc->benign_saddle_point,NULL);CHKERRQ(ierr); 784f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 790c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 800c7d97c5SJed Brown PetscFunctionReturn(0); 810c7d97c5SJed Brown } 820c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 83674ae819SStefano Zampini #undef __FUNCT__ 84906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat_BDDC" 85906d46d4SStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change) 86b9b85e73SStefano Zampini { 87b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 88b9b85e73SStefano Zampini PetscErrorCode ierr; 89b9b85e73SStefano Zampini 90b9b85e73SStefano Zampini PetscFunctionBegin; 91b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 9256282151SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 93b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 94b9b85e73SStefano Zampini PetscFunctionReturn(0); 95b9b85e73SStefano Zampini } 96b9b85e73SStefano Zampini #undef __FUNCT__ 97906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat" 98b9b85e73SStefano Zampini /*@ 99906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 100b9b85e73SStefano Zampini 101b9b85e73SStefano Zampini Collective on PC 102b9b85e73SStefano Zampini 103b9b85e73SStefano Zampini Input Parameters: 104b9b85e73SStefano Zampini + pc - the preconditioning context 105906d46d4SStefano Zampini - change - the change of basis matrix 106b9b85e73SStefano Zampini 107b9b85e73SStefano Zampini Level: intermediate 108b9b85e73SStefano Zampini 109b9b85e73SStefano Zampini Notes: 110b9b85e73SStefano Zampini 111b9b85e73SStefano Zampini .seealso: PCBDDC 112b9b85e73SStefano Zampini @*/ 113906d46d4SStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change) 114b9b85e73SStefano Zampini { 115b9b85e73SStefano Zampini PetscErrorCode ierr; 116b9b85e73SStefano Zampini 117b9b85e73SStefano Zampini PetscFunctionBegin; 118b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 119b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 120906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 121906d46d4SStefano Zampini if (pc->mat) { 122906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 123906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 124906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 125906d46d4SStefano Zampini if (rows_c != rows) { 126906d46d4SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of rows for change of basis matrix! %d != %d",rows_c,rows); 127906d46d4SStefano Zampini } 128906d46d4SStefano Zampini if (cols_c != cols) { 129906d46d4SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of columns for change of basis matrix! %d != %d",cols_c,cols); 130906d46d4SStefano Zampini } 131906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 132906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 133906d46d4SStefano Zampini if (rows_c != rows) { 134906d46d4SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local rows for change of basis matrix! %d != %d",rows_c,rows); 135906d46d4SStefano Zampini } 136906d46d4SStefano Zampini if (cols_c != cols) { 137906d46d4SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local columns for change of basis matrix! %d != %d",cols_c,cols); 138906d46d4SStefano Zampini } 139906d46d4SStefano Zampini } 140906d46d4SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat),(pc,change));CHKERRQ(ierr); 141b9b85e73SStefano Zampini PetscFunctionReturn(0); 142b9b85e73SStefano Zampini } 143b9b85e73SStefano Zampini /* -------------------------------------------------------------------------- */ 144b9b85e73SStefano Zampini #undef __FUNCT__ 14530368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS_BDDC" 14630368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 14730368db7SStefano Zampini { 14830368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 14956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 15030368db7SStefano Zampini PetscErrorCode ierr; 15130368db7SStefano Zampini 15230368db7SStefano Zampini PetscFunctionBegin; 15356282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 15456282151SStefano Zampini if (pcbddc->user_primal_vertices) { 15556282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices,&isequal);CHKERRQ(ierr); 15656282151SStefano Zampini } 15730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 15830368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 15930368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 16056282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 16130368db7SStefano Zampini PetscFunctionReturn(0); 16230368db7SStefano Zampini } 16330368db7SStefano Zampini #undef __FUNCT__ 16430368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS" 16530368db7SStefano Zampini /*@ 16630368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 16730368db7SStefano Zampini 16830368db7SStefano Zampini Collective 16930368db7SStefano Zampini 17030368db7SStefano Zampini Input Parameters: 17130368db7SStefano Zampini + pc - the preconditioning context 17230368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 17330368db7SStefano Zampini 17430368db7SStefano Zampini Level: intermediate 17530368db7SStefano Zampini 17630368db7SStefano Zampini Notes: 17730368db7SStefano Zampini Any process can list any global node 17830368db7SStefano Zampini 17930368db7SStefano Zampini .seealso: PCBDDC 18030368db7SStefano Zampini @*/ 18130368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 18230368db7SStefano Zampini { 18330368db7SStefano Zampini PetscErrorCode ierr; 18430368db7SStefano Zampini 18530368db7SStefano Zampini PetscFunctionBegin; 18630368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 18730368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 18830368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 18930368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 19030368db7SStefano Zampini PetscFunctionReturn(0); 19130368db7SStefano Zampini } 19230368db7SStefano Zampini /* -------------------------------------------------------------------------- */ 19330368db7SStefano Zampini #undef __FUNCT__ 194674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 195674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 196674ae819SStefano Zampini { 197674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 19856282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 199674ae819SStefano Zampini PetscErrorCode ierr; 2001e6b0712SBarry Smith 201674ae819SStefano Zampini PetscFunctionBegin; 20256282151SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 20356282151SStefano Zampini if (pcbddc->user_primal_vertices_local) { 20456282151SStefano Zampini ierr = ISEqual(PrimalVertices,pcbddc->user_primal_vertices_local,&isequal);CHKERRQ(ierr); 20556282151SStefano Zampini } 206674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 20730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 20830368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 20956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 210674ae819SStefano Zampini PetscFunctionReturn(0); 211674ae819SStefano Zampini } 212674ae819SStefano Zampini #undef __FUNCT__ 213674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 214674ae819SStefano Zampini /*@ 21528509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 216674ae819SStefano Zampini 21717eb1463SStefano Zampini Collective 218674ae819SStefano Zampini 219674ae819SStefano Zampini Input Parameters: 220674ae819SStefano Zampini + pc - the preconditioning context 22117eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 222674ae819SStefano Zampini 223674ae819SStefano Zampini Level: intermediate 224674ae819SStefano Zampini 225674ae819SStefano Zampini Notes: 226674ae819SStefano Zampini 227674ae819SStefano Zampini .seealso: PCBDDC 228674ae819SStefano Zampini @*/ 229674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 230674ae819SStefano Zampini { 231674ae819SStefano Zampini PetscErrorCode ierr; 232674ae819SStefano Zampini 233674ae819SStefano Zampini PetscFunctionBegin; 234674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 235674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 23617eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 237674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 238674ae819SStefano Zampini PetscFunctionReturn(0); 239674ae819SStefano Zampini } 240674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 2410c7d97c5SJed Brown #undef __FUNCT__ 2424fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 2434fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 2444fad6a16SStefano Zampini { 2454fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2464fad6a16SStefano Zampini 2474fad6a16SStefano Zampini PetscFunctionBegin; 2484fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 2494fad6a16SStefano Zampini PetscFunctionReturn(0); 2504fad6a16SStefano Zampini } 2511e6b0712SBarry Smith 2524fad6a16SStefano Zampini #undef __FUNCT__ 2534fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 2544fad6a16SStefano Zampini /*@ 25528509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 2564fad6a16SStefano Zampini 2574fad6a16SStefano Zampini Logically collective on PC 2584fad6a16SStefano Zampini 2594fad6a16SStefano Zampini Input Parameters: 2604fad6a16SStefano Zampini + pc - the preconditioning context 26128509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 2624fad6a16SStefano Zampini 2630f202f7eSStefano Zampini Options Database Keys: 2640f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 2654fad6a16SStefano Zampini 2664fad6a16SStefano Zampini Level: intermediate 2674fad6a16SStefano Zampini 2684fad6a16SStefano Zampini Notes: 2690f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 2704fad6a16SStefano Zampini 2710f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 2724fad6a16SStefano Zampini @*/ 2734fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 2744fad6a16SStefano Zampini { 2754fad6a16SStefano Zampini PetscErrorCode ierr; 2764fad6a16SStefano Zampini 2774fad6a16SStefano Zampini PetscFunctionBegin; 2784fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2792b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 2804fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 2814fad6a16SStefano Zampini PetscFunctionReturn(0); 2824fad6a16SStefano Zampini } 2832b510759SStefano Zampini 284b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 2852b510759SStefano Zampini #undef __FUNCT__ 286b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet_BDDC" 287b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 288b8ffe317SStefano Zampini { 289b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 290b8ffe317SStefano Zampini 291b8ffe317SStefano Zampini PetscFunctionBegin; 29285c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 293b8ffe317SStefano Zampini PetscFunctionReturn(0); 294b8ffe317SStefano Zampini } 295b8ffe317SStefano Zampini 296b8ffe317SStefano Zampini #undef __FUNCT__ 297b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet" 298b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 2992b510759SStefano Zampini { 3002b510759SStefano Zampini PetscErrorCode ierr; 3012b510759SStefano Zampini 3022b510759SStefano Zampini PetscFunctionBegin; 3032b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 304b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 305b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 3062b510759SStefano Zampini PetscFunctionReturn(0); 3072b510759SStefano Zampini } 3081e6b0712SBarry Smith 3094fad6a16SStefano Zampini #undef __FUNCT__ 3102b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel_BDDC" 3112b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 3124fad6a16SStefano Zampini { 3134fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3144fad6a16SStefano Zampini 3154fad6a16SStefano Zampini PetscFunctionBegin; 3162b510759SStefano Zampini pcbddc->current_level = level; 3174fad6a16SStefano Zampini PetscFunctionReturn(0); 3184fad6a16SStefano Zampini } 3191e6b0712SBarry Smith 3204fad6a16SStefano Zampini #undef __FUNCT__ 321b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 322b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 323b8ffe317SStefano Zampini { 324b8ffe317SStefano Zampini PetscErrorCode ierr; 325b8ffe317SStefano Zampini 326b8ffe317SStefano Zampini PetscFunctionBegin; 327b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 328b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 329b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 330b8ffe317SStefano Zampini PetscFunctionReturn(0); 331b8ffe317SStefano Zampini } 332b8ffe317SStefano Zampini 333b8ffe317SStefano Zampini #undef __FUNCT__ 3342b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels_BDDC" 3352b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 3362b510759SStefano Zampini { 3372b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3382b510759SStefano Zampini 3392b510759SStefano Zampini PetscFunctionBegin; 3402b510759SStefano Zampini pcbddc->max_levels = levels; 3412b510759SStefano Zampini PetscFunctionReturn(0); 3422b510759SStefano Zampini } 3432b510759SStefano Zampini 3442b510759SStefano Zampini #undef __FUNCT__ 3452b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels" 3464fad6a16SStefano Zampini /*@ 34728509bceSStefano Zampini PCBDDCSetLevels - Sets the maximum number of levels for multilevel 3484fad6a16SStefano Zampini 3494fad6a16SStefano Zampini Logically collective on PC 3504fad6a16SStefano Zampini 3514fad6a16SStefano Zampini Input Parameters: 3524fad6a16SStefano Zampini + pc - the preconditioning context 35328509bceSStefano Zampini - levels - the maximum number of levels (max 9) 3544fad6a16SStefano Zampini 3550f202f7eSStefano Zampini Options Database Keys: 3560f202f7eSStefano Zampini . -pc_bddc_levels 3574fad6a16SStefano Zampini 3584fad6a16SStefano Zampini Level: intermediate 3594fad6a16SStefano Zampini 3604fad6a16SStefano Zampini Notes: 3610f202f7eSStefano Zampini Default value is 0, i.e. traditional one-level BDDC 3624fad6a16SStefano Zampini 3630f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 3644fad6a16SStefano Zampini @*/ 3652b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 3664fad6a16SStefano Zampini { 3674fad6a16SStefano Zampini PetscErrorCode ierr; 3684fad6a16SStefano Zampini 3694fad6a16SStefano Zampini PetscFunctionBegin; 3704fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 3712b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 372312be037SStefano Zampini if (levels > 99) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of levels for bddc is 99\n"); 3732b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 3744fad6a16SStefano Zampini PetscFunctionReturn(0); 3754fad6a16SStefano Zampini } 3764fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 3771e6b0712SBarry Smith 3784fad6a16SStefano Zampini #undef __FUNCT__ 3790bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 3800bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 3810bdf917eSStefano Zampini { 3820bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3830bdf917eSStefano Zampini PetscErrorCode ierr; 3840bdf917eSStefano Zampini 3850bdf917eSStefano Zampini PetscFunctionBegin; 3860bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 3870bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 3880bdf917eSStefano Zampini pcbddc->NullSpace = NullSpace; 3890bdf917eSStefano Zampini PetscFunctionReturn(0); 3900bdf917eSStefano Zampini } 3911e6b0712SBarry Smith 3920bdf917eSStefano Zampini #undef __FUNCT__ 3930bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 3940bdf917eSStefano Zampini /*@ 39528509bceSStefano Zampini PCBDDCSetNullSpace - Set nullspace for BDDC operator 3960bdf917eSStefano Zampini 3970bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 3980bdf917eSStefano Zampini 3990bdf917eSStefano Zampini Input Parameters: 4000bdf917eSStefano Zampini + pc - the preconditioning context 40128509bceSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned (Pmat) 4020bdf917eSStefano Zampini 4030bdf917eSStefano Zampini Level: intermediate 4040bdf917eSStefano Zampini 4050bdf917eSStefano Zampini Notes: 4060bdf917eSStefano Zampini 4070bdf917eSStefano Zampini .seealso: PCBDDC 4080bdf917eSStefano Zampini @*/ 4090bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 4100bdf917eSStefano Zampini { 4110bdf917eSStefano Zampini PetscErrorCode ierr; 4120bdf917eSStefano Zampini 4130bdf917eSStefano Zampini PetscFunctionBegin; 4140bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 415674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 4162b510759SStefano Zampini PetscCheckSameComm(pc,1,NullSpace,2); 4170bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 4180bdf917eSStefano Zampini PetscFunctionReturn(0); 4190bdf917eSStefano Zampini } 4200bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 4211e6b0712SBarry Smith 4220bdf917eSStefano Zampini #undef __FUNCT__ 4233b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 4243b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 4253b03a366Sstefano_zampini { 4263b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 42756282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 4283b03a366Sstefano_zampini PetscErrorCode ierr; 4293b03a366Sstefano_zampini 4303b03a366Sstefano_zampini PetscFunctionBegin; 43156282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 43256282151SStefano Zampini if (pcbddc->DirichletBoundaries) { 43356282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundaries,&isequal);CHKERRQ(ierr); 43456282151SStefano Zampini } 435785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 436785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 4373b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 43836e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 43956282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 4403b03a366Sstefano_zampini PetscFunctionReturn(0); 4413b03a366Sstefano_zampini } 4421e6b0712SBarry Smith 4433b03a366Sstefano_zampini #undef __FUNCT__ 4443b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 4453b03a366Sstefano_zampini /*@ 44628509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 4473b03a366Sstefano_zampini 448785d1243SStefano Zampini Collective 4493b03a366Sstefano_zampini 4503b03a366Sstefano_zampini Input Parameters: 4513b03a366Sstefano_zampini + pc - the preconditioning context 452785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 4533b03a366Sstefano_zampini 4543b03a366Sstefano_zampini Level: intermediate 4553b03a366Sstefano_zampini 4560f202f7eSStefano Zampini Notes: 4570f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 4583b03a366Sstefano_zampini 4590f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 4603b03a366Sstefano_zampini @*/ 4613b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 4623b03a366Sstefano_zampini { 4633b03a366Sstefano_zampini PetscErrorCode ierr; 4643b03a366Sstefano_zampini 4653b03a366Sstefano_zampini PetscFunctionBegin; 4663b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 467674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 468785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 4693b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 4703b03a366Sstefano_zampini PetscFunctionReturn(0); 4713b03a366Sstefano_zampini } 4723b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 4731e6b0712SBarry Smith 4743b03a366Sstefano_zampini #undef __FUNCT__ 47582ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal_BDDC" 47682ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 4770c7d97c5SJed Brown { 4780c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 47956282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 4800c7d97c5SJed Brown PetscErrorCode ierr; 4810c7d97c5SJed Brown 4820c7d97c5SJed Brown PetscFunctionBegin; 48356282151SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 48456282151SStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 48556282151SStefano Zampini ierr = ISEqual(DirichletBoundaries,pcbddc->DirichletBoundariesLocal,&isequal);CHKERRQ(ierr); 48656282151SStefano Zampini } 487785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 488785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 4890c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 490785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 49156282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 4920c7d97c5SJed Brown PetscFunctionReturn(0); 4930c7d97c5SJed Brown } 4940c7d97c5SJed Brown 4950c7d97c5SJed Brown #undef __FUNCT__ 49682ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal" 4979c0446d6SStefano Zampini /*@ 49882ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 4999c0446d6SStefano Zampini 500785d1243SStefano Zampini Collective 50153cdbc3dSStefano Zampini 50253cdbc3dSStefano Zampini Input Parameters: 50353cdbc3dSStefano Zampini + pc - the preconditioning context 50482ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 50553cdbc3dSStefano Zampini 50653cdbc3dSStefano Zampini Level: intermediate 50753cdbc3dSStefano Zampini 5089c0446d6SStefano Zampini Notes: 50953cdbc3dSStefano Zampini 5100f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 51153cdbc3dSStefano Zampini @*/ 51282ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 5130c7d97c5SJed Brown { 5140c7d97c5SJed Brown PetscErrorCode ierr; 5150c7d97c5SJed Brown 5160c7d97c5SJed Brown PetscFunctionBegin; 5170c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5180c7d97c5SJed Brown PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 51982ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 52082ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 5210c7d97c5SJed Brown PetscFunctionReturn(0); 5220c7d97c5SJed Brown } 5230c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5240c7d97c5SJed Brown 5250c7d97c5SJed Brown #undef __FUNCT__ 5260c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 52753cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 5280c7d97c5SJed Brown { 5290c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 53056282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 53153cdbc3dSStefano Zampini PetscErrorCode ierr; 5320c7d97c5SJed Brown 5330c7d97c5SJed Brown PetscFunctionBegin; 53456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 53556282151SStefano Zampini if (pcbddc->NeumannBoundaries) { 53656282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundaries,&isequal);CHKERRQ(ierr); 53756282151SStefano Zampini } 538785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 539785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 54053cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 54136e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 54256282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 5430c7d97c5SJed Brown PetscFunctionReturn(0); 5440c7d97c5SJed Brown } 5451e6b0712SBarry Smith 5460c7d97c5SJed Brown #undef __FUNCT__ 5470c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 54857527edcSJed Brown /*@ 54928509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 55057527edcSJed Brown 551785d1243SStefano Zampini Collective 55257527edcSJed Brown 55357527edcSJed Brown Input Parameters: 55457527edcSJed Brown + pc - the preconditioning context 555785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 55657527edcSJed Brown 55757527edcSJed Brown Level: intermediate 55857527edcSJed Brown 5590f202f7eSStefano Zampini Notes: 5600f202f7eSStefano Zampini Any process can list any global node 56157527edcSJed Brown 5620f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 56357527edcSJed Brown @*/ 56453cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 5650c7d97c5SJed Brown { 5660c7d97c5SJed Brown PetscErrorCode ierr; 5670c7d97c5SJed Brown 5680c7d97c5SJed Brown PetscFunctionBegin; 5690c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 570674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 571785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 57253cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 57353cdbc3dSStefano Zampini PetscFunctionReturn(0); 57453cdbc3dSStefano Zampini } 57553cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 5761e6b0712SBarry Smith 57753cdbc3dSStefano Zampini #undef __FUNCT__ 57882ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal_BDDC" 57982ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 5800c7d97c5SJed Brown { 5810c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 58256282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 5830c7d97c5SJed Brown PetscErrorCode ierr; 5840c7d97c5SJed Brown 5850c7d97c5SJed Brown PetscFunctionBegin; 58656282151SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 58756282151SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 58856282151SStefano Zampini ierr = ISEqual(NeumannBoundaries,pcbddc->NeumannBoundariesLocal,&isequal);CHKERRQ(ierr); 58956282151SStefano Zampini } 590785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 591785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 5920c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 593785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 59456282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 5950c7d97c5SJed Brown PetscFunctionReturn(0); 5960c7d97c5SJed Brown } 5970c7d97c5SJed Brown 5980c7d97c5SJed Brown #undef __FUNCT__ 59982ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal" 6000c7d97c5SJed Brown /*@ 60182ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 6020c7d97c5SJed Brown 603785d1243SStefano Zampini Collective 6040c7d97c5SJed Brown 6050c7d97c5SJed Brown Input Parameters: 6060c7d97c5SJed Brown + pc - the preconditioning context 60782ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 6080c7d97c5SJed Brown 6090c7d97c5SJed Brown Level: intermediate 6100c7d97c5SJed Brown 6110c7d97c5SJed Brown Notes: 6120c7d97c5SJed Brown 6130f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 6140c7d97c5SJed Brown @*/ 61582ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 6160c7d97c5SJed Brown { 6170c7d97c5SJed Brown PetscErrorCode ierr; 6180c7d97c5SJed Brown 6190c7d97c5SJed Brown PetscFunctionBegin; 6200c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 6210c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 62282ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 62382ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 62453cdbc3dSStefano Zampini PetscFunctionReturn(0); 62553cdbc3dSStefano Zampini } 62653cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 62753cdbc3dSStefano Zampini 62853cdbc3dSStefano Zampini #undef __FUNCT__ 629da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 630da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 631da1bb401SStefano Zampini { 632da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 633da1bb401SStefano Zampini 634da1bb401SStefano Zampini PetscFunctionBegin; 635da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 636da1bb401SStefano Zampini PetscFunctionReturn(0); 637da1bb401SStefano Zampini } 6381e6b0712SBarry Smith 639da1bb401SStefano Zampini #undef __FUNCT__ 640da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 641da1bb401SStefano Zampini /*@ 642785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 643da1bb401SStefano Zampini 644785d1243SStefano Zampini Collective 645785d1243SStefano Zampini 646785d1243SStefano Zampini Input Parameters: 647785d1243SStefano Zampini . pc - the preconditioning context 648785d1243SStefano Zampini 649785d1243SStefano Zampini Output Parameters: 650785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 651785d1243SStefano Zampini 652785d1243SStefano Zampini Level: intermediate 653785d1243SStefano Zampini 6540f202f7eSStefano Zampini Notes: 6550f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 656785d1243SStefano Zampini 657785d1243SStefano Zampini .seealso: PCBDDC 658785d1243SStefano Zampini @*/ 659785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 660785d1243SStefano Zampini { 661785d1243SStefano Zampini PetscErrorCode ierr; 662785d1243SStefano Zampini 663785d1243SStefano Zampini PetscFunctionBegin; 664785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 665785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 666785d1243SStefano Zampini PetscFunctionReturn(0); 667785d1243SStefano Zampini } 668785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 669785d1243SStefano Zampini 670785d1243SStefano Zampini #undef __FUNCT__ 671785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal_BDDC" 672785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 673785d1243SStefano Zampini { 674785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 675785d1243SStefano Zampini 676785d1243SStefano Zampini PetscFunctionBegin; 677785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 678785d1243SStefano Zampini PetscFunctionReturn(0); 679785d1243SStefano Zampini } 680785d1243SStefano Zampini 681785d1243SStefano Zampini #undef __FUNCT__ 68282ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal" 683da1bb401SStefano Zampini /*@ 68482ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 685da1bb401SStefano Zampini 686785d1243SStefano Zampini Collective 687da1bb401SStefano Zampini 688da1bb401SStefano Zampini Input Parameters: 68928509bceSStefano Zampini . pc - the preconditioning context 690da1bb401SStefano Zampini 691da1bb401SStefano Zampini Output Parameters: 69228509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 693da1bb401SStefano Zampini 694da1bb401SStefano Zampini Level: intermediate 695da1bb401SStefano Zampini 696da1bb401SStefano Zampini Notes: 6970f202f7eSStefano Zampini The IS returned could be the same passed in earlier by the user (if provided with PCBDDCSetDirichletBoundariesLocal) or a global-to-local map of the global IS (if provided with PCBDDCSetDirichletBoundaries). 6980f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 699da1bb401SStefano Zampini 700da1bb401SStefano Zampini .seealso: PCBDDC 701da1bb401SStefano Zampini @*/ 70282ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 703da1bb401SStefano Zampini { 704da1bb401SStefano Zampini PetscErrorCode ierr; 705da1bb401SStefano Zampini 706da1bb401SStefano Zampini PetscFunctionBegin; 707da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 70882ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 709da1bb401SStefano Zampini PetscFunctionReturn(0); 710da1bb401SStefano Zampini } 711da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 7121e6b0712SBarry Smith 713da1bb401SStefano Zampini #undef __FUNCT__ 71453cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 71553cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 71653cdbc3dSStefano Zampini { 71753cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 71853cdbc3dSStefano Zampini 71953cdbc3dSStefano Zampini PetscFunctionBegin; 72053cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 72153cdbc3dSStefano Zampini PetscFunctionReturn(0); 72253cdbc3dSStefano Zampini } 7231e6b0712SBarry Smith 72453cdbc3dSStefano Zampini #undef __FUNCT__ 72553cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 72653cdbc3dSStefano Zampini /*@ 727785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 72853cdbc3dSStefano Zampini 729785d1243SStefano Zampini Collective 730785d1243SStefano Zampini 731785d1243SStefano Zampini Input Parameters: 732785d1243SStefano Zampini . pc - the preconditioning context 733785d1243SStefano Zampini 734785d1243SStefano Zampini Output Parameters: 735785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 736785d1243SStefano Zampini 737785d1243SStefano Zampini Level: intermediate 738785d1243SStefano Zampini 7390f202f7eSStefano Zampini Notes: 7400f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 741785d1243SStefano Zampini 742785d1243SStefano Zampini .seealso: PCBDDC 743785d1243SStefano Zampini @*/ 744785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 745785d1243SStefano Zampini { 746785d1243SStefano Zampini PetscErrorCode ierr; 747785d1243SStefano Zampini 748785d1243SStefano Zampini PetscFunctionBegin; 749785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 750785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 751785d1243SStefano Zampini PetscFunctionReturn(0); 752785d1243SStefano Zampini } 753785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 754785d1243SStefano Zampini 755785d1243SStefano Zampini #undef __FUNCT__ 756785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal_BDDC" 757785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 758785d1243SStefano Zampini { 759785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 760785d1243SStefano Zampini 761785d1243SStefano Zampini PetscFunctionBegin; 762785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 763785d1243SStefano Zampini PetscFunctionReturn(0); 764785d1243SStefano Zampini } 765785d1243SStefano Zampini 766785d1243SStefano Zampini #undef __FUNCT__ 76782ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal" 76853cdbc3dSStefano Zampini /*@ 76982ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 77053cdbc3dSStefano Zampini 771785d1243SStefano Zampini Collective 77253cdbc3dSStefano Zampini 77353cdbc3dSStefano Zampini Input Parameters: 77428509bceSStefano Zampini . pc - the preconditioning context 77553cdbc3dSStefano Zampini 77653cdbc3dSStefano Zampini Output Parameters: 77728509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 77853cdbc3dSStefano Zampini 77953cdbc3dSStefano Zampini Level: intermediate 78053cdbc3dSStefano Zampini 78153cdbc3dSStefano Zampini Notes: 7820f202f7eSStefano Zampini The IS returned could be the same passed in earlier by the user (if provided with PCBDDCSetNeumannBoundariesLocal) or a global-to-local map of the global IS (if provided with PCBDDCSetNeumannBoundaries). 7830f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 78453cdbc3dSStefano Zampini 78553cdbc3dSStefano Zampini .seealso: PCBDDC 78653cdbc3dSStefano Zampini @*/ 78782ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 78853cdbc3dSStefano Zampini { 78953cdbc3dSStefano Zampini PetscErrorCode ierr; 79053cdbc3dSStefano Zampini 79153cdbc3dSStefano Zampini PetscFunctionBegin; 79253cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 79382ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 7940c7d97c5SJed Brown PetscFunctionReturn(0); 7950c7d97c5SJed Brown } 79636e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 7971e6b0712SBarry Smith 79836e030ebSStefano Zampini #undef __FUNCT__ 799da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 8001a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 80136e030ebSStefano Zampini { 80236e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 803da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 80456282151SStefano Zampini PetscBool same_data = PETSC_FALSE; 805da1bb401SStefano Zampini PetscErrorCode ierr; 80636e030ebSStefano Zampini 80736e030ebSStefano Zampini PetscFunctionBegin; 80856282151SStefano Zampini if (mat_graph->nvtxs_csr == nvtxs) { 80956282151SStefano Zampini if (mat_graph->xadj == xadj && mat_graph->adjncy == adjncy) same_data = PETSC_TRUE; 81056282151SStefano Zampini if (!same_data && mat_graph->xadj[nvtxs] == xadj[nvtxs]) { 81156282151SStefano Zampini ierr = PetscMemcmp(adjncy,mat_graph->adjncy,nvtxs*sizeof(PetscInt),&same_data);CHKERRQ(ierr); 81256282151SStefano Zampini } 81356282151SStefano Zampini } 81456282151SStefano Zampini if (!same_data) { 815674ae819SStefano Zampini /* free old CSR */ 816674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 817674ae819SStefano Zampini /* get CSR into graph structure */ 818da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 819854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 820785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 821674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 822674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 823da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 8241a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 8251a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 826674ae819SStefano Zampini } 827575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 82856282151SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 82956282151SStefano Zampini } 83036e030ebSStefano Zampini PetscFunctionReturn(0); 83136e030ebSStefano Zampini } 8321e6b0712SBarry Smith 83336e030ebSStefano Zampini #undef __FUNCT__ 834da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 83536e030ebSStefano Zampini /*@ 8360f202f7eSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local matrix 83736e030ebSStefano Zampini 83836e030ebSStefano Zampini Not collective 83936e030ebSStefano Zampini 84036e030ebSStefano Zampini Input Parameters: 84136e030ebSStefano Zampini + pc - the preconditioning context 8420f202f7eSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the size of the local problem) 84328509bceSStefano Zampini . xadj, adjncy - the CSR graph 84428509bceSStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. 84536e030ebSStefano Zampini 84636e030ebSStefano Zampini Level: intermediate 84736e030ebSStefano Zampini 84836e030ebSStefano Zampini Notes: 84936e030ebSStefano Zampini 85028509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 85136e030ebSStefano Zampini @*/ 8521a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 85336e030ebSStefano Zampini { 854575ad6abSStefano Zampini void (*f)(void) = 0; 85536e030ebSStefano Zampini PetscErrorCode ierr; 85636e030ebSStefano Zampini 85736e030ebSStefano Zampini PetscFunctionBegin; 85836e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 859674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 860d7de1dd9SStefano Zampini PetscValidIntPointer(adjncy,4); 861674ae819SStefano Zampini if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) { 862674ae819SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 863da1bb401SStefano Zampini } 86436e030ebSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 865575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 866575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 867575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 868575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 869575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 87036e030ebSStefano Zampini } 87136e030ebSStefano Zampini PetscFunctionReturn(0); 87236e030ebSStefano Zampini } 8739c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 8741e6b0712SBarry Smith 8759c0446d6SStefano Zampini #undef __FUNCT__ 87663602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal_BDDC" 87763602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 87863602bcaSStefano Zampini { 87963602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 88063602bcaSStefano Zampini PetscInt i; 88156282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 88263602bcaSStefano Zampini PetscErrorCode ierr; 88363602bcaSStefano Zampini 88463602bcaSStefano Zampini PetscFunctionBegin; 88556282151SStefano Zampini if (pcbddc->n_ISForDofsLocal == n_is) { 88656282151SStefano Zampini for (i=0;i<n_is;i++) { 88756282151SStefano Zampini PetscBool isequalt; 88856282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofsLocal[i],&isequalt);CHKERRQ(ierr); 88956282151SStefano Zampini if (!isequalt) break; 89056282151SStefano Zampini } 89156282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 89256282151SStefano Zampini } 89356282151SStefano Zampini for (i=0;i<n_is;i++) { 89456282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 89556282151SStefano Zampini } 89663602bcaSStefano Zampini /* Destroy ISes if they were already set */ 89763602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 89863602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 89963602bcaSStefano Zampini } 90063602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 90163602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 90263602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 90363602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 90463602bcaSStefano Zampini } 90563602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 90663602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 90763602bcaSStefano Zampini /* allocate space then set */ 908d02579f5SStefano Zampini if (n_is) { 909d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 910d02579f5SStefano Zampini } 91163602bcaSStefano Zampini for (i=0;i<n_is;i++) { 91263602bcaSStefano Zampini pcbddc->ISForDofsLocal[i] = ISForDofs[i]; 91363602bcaSStefano Zampini } 91463602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = n_is; 91563602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 91656282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 91763602bcaSStefano Zampini PetscFunctionReturn(0); 91863602bcaSStefano Zampini } 91963602bcaSStefano Zampini 92063602bcaSStefano Zampini #undef __FUNCT__ 92163602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal" 92263602bcaSStefano Zampini /*@ 92363602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 92463602bcaSStefano Zampini 92563602bcaSStefano Zampini Collective 92663602bcaSStefano Zampini 92763602bcaSStefano Zampini Input Parameters: 92863602bcaSStefano Zampini + pc - the preconditioning context 9290f202f7eSStefano Zampini . n_is - number of index sets defining the fields 9300f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 93163602bcaSStefano Zampini 93263602bcaSStefano Zampini Level: intermediate 93363602bcaSStefano Zampini 9340f202f7eSStefano Zampini Notes: 9350f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 93663602bcaSStefano Zampini 93763602bcaSStefano Zampini .seealso: PCBDDC 93863602bcaSStefano Zampini @*/ 93963602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 94063602bcaSStefano Zampini { 94163602bcaSStefano Zampini PetscInt i; 94263602bcaSStefano Zampini PetscErrorCode ierr; 94363602bcaSStefano Zampini 94463602bcaSStefano Zampini PetscFunctionBegin; 94563602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 94663602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 94763602bcaSStefano Zampini for (i=0;i<n_is;i++) { 94863602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 94963602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 95063602bcaSStefano Zampini } 951e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 95263602bcaSStefano Zampini PetscFunctionReturn(0); 95363602bcaSStefano Zampini } 95463602bcaSStefano Zampini /* -------------------------------------------------------------------------- */ 95563602bcaSStefano Zampini 95663602bcaSStefano Zampini #undef __FUNCT__ 9579c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 9589c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 9599c0446d6SStefano Zampini { 9609c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 9619c0446d6SStefano Zampini PetscInt i; 96256282151SStefano Zampini PetscBool isequal = PETSC_FALSE; 9639c0446d6SStefano Zampini PetscErrorCode ierr; 9649c0446d6SStefano Zampini 9659c0446d6SStefano Zampini PetscFunctionBegin; 96656282151SStefano Zampini if (pcbddc->n_ISForDofs == n_is) { 96756282151SStefano Zampini for (i=0;i<n_is;i++) { 96856282151SStefano Zampini PetscBool isequalt; 96956282151SStefano Zampini ierr = ISEqual(ISForDofs[i],pcbddc->ISForDofs[i],&isequalt);CHKERRQ(ierr); 97056282151SStefano Zampini if (!isequalt) break; 97156282151SStefano Zampini } 97256282151SStefano Zampini if (i == n_is) isequal = PETSC_TRUE; 97356282151SStefano Zampini } 97456282151SStefano Zampini for (i=0;i<n_is;i++) { 97556282151SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 97656282151SStefano Zampini } 977da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 9789c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 9799c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 9809c0446d6SStefano Zampini } 981d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 98263602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 98363602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 98463602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 98563602bcaSStefano Zampini } 98663602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 98763602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 988da1bb401SStefano Zampini /* allocate space then set */ 989d02579f5SStefano Zampini if (n_is) { 990785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 991d02579f5SStefano Zampini } 9929c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 993da1bb401SStefano Zampini pcbddc->ISForDofs[i] = ISForDofs[i]; 9949c0446d6SStefano Zampini } 9959c0446d6SStefano Zampini pcbddc->n_ISForDofs = n_is; 99663602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 99756282151SStefano Zampini if (!isequal) pcbddc->recompute_topography = PETSC_TRUE; 9989c0446d6SStefano Zampini PetscFunctionReturn(0); 9999c0446d6SStefano Zampini } 10001e6b0712SBarry Smith 10019c0446d6SStefano Zampini #undef __FUNCT__ 10029c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 10039c0446d6SStefano Zampini /*@ 100463602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 10059c0446d6SStefano Zampini 100663602bcaSStefano Zampini Collective 10079c0446d6SStefano Zampini 10089c0446d6SStefano Zampini Input Parameters: 10099c0446d6SStefano Zampini + pc - the preconditioning context 10100f202f7eSStefano Zampini . n_is - number of index sets defining the fields 10110f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 10129c0446d6SStefano Zampini 10139c0446d6SStefano Zampini Level: intermediate 10149c0446d6SStefano Zampini 10150f202f7eSStefano Zampini Notes: 10160f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 10179c0446d6SStefano Zampini 10189c0446d6SStefano Zampini .seealso: PCBDDC 10199c0446d6SStefano Zampini @*/ 10209c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 10219c0446d6SStefano Zampini { 10222b510759SStefano Zampini PetscInt i; 10239c0446d6SStefano Zampini PetscErrorCode ierr; 10249c0446d6SStefano Zampini 10259c0446d6SStefano Zampini PetscFunctionBegin; 10269c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 102763602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 10282b510759SStefano Zampini for (i=0;i<n_is;i++) { 102963602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 103063602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 10312b510759SStefano Zampini } 10329c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 10339c0446d6SStefano Zampini PetscFunctionReturn(0); 10349c0446d6SStefano Zampini } 1035906d46d4SStefano Zampini 1036da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1037534831adSStefano Zampini #undef __FUNCT__ 1038534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 1039534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1040534831adSStefano Zampini /* 1041534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 1042534831adSStefano Zampini guess if a transformation of basis approach has been selected. 10439c0446d6SStefano Zampini 1044534831adSStefano Zampini Input Parameter: 1045534831adSStefano Zampini + pc - the preconditioner contex 1046534831adSStefano Zampini 1047534831adSStefano Zampini Application Interface Routine: PCPreSolve() 1048534831adSStefano Zampini 1049534831adSStefano Zampini Notes: 1050534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 1051534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1052534831adSStefano Zampini */ 1053534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1054534831adSStefano Zampini { 1055534831adSStefano Zampini PetscErrorCode ierr; 1056534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1057534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 10583972b0daSStefano Zampini Vec used_vec; 10598d00608fSStefano Zampini PetscBool copy_rhs = PETSC_TRUE; 106051694757SStefano Zampini PetscBool benign_correction_is_zero = PETSC_FALSE; 1061a3df083aSStefano Zampini PetscBool iscg = PETSC_FALSE; 1062534831adSStefano Zampini 1063534831adSStefano Zampini PetscFunctionBegin; 106485c4d303SStefano Zampini /* if we are working with cg, one dirichlet solve can be avoided during Krylov iterations */ 106585c4d303SStefano Zampini if (ksp) { 106685c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 106785c4d303SStefano Zampini if (!iscg) { 106885c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 106985c4d303SStefano Zampini } 107085c4d303SStefano Zampini } 107185c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 107262a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 107362a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 107462a6ff1dSStefano Zampini } 107562a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 107662a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 107762a6ff1dSStefano Zampini } 10788d00608fSStefano Zampini 10793972b0daSStefano Zampini if (x) { 10803972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 10813972b0daSStefano Zampini used_vec = x; 10828d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 10833972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 10843972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 10853972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 10863972b0daSStefano Zampini } 10878efcfb23SStefano Zampini 10888efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 10893972b0daSStefano Zampini if (ksp) { 1090a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 10918efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 10928efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 10933972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 10943972b0daSStefano Zampini } 10953972b0daSStefano Zampini } 10963308cffdSStefano Zampini 10978d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 10983972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 1099a07ea27aSStefano Zampini if (rhs) { 11003975b054SStefano Zampini IS dirIS = NULL; 11013975b054SStefano Zampini 1102a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 11033975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 11043975b054SStefano Zampini if (dirIS) { 1105906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1106785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 11072b095fd8SStefano Zampini PetscScalar *array_x; 11082b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1109785d1243SStefano Zampini 11103972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 11113972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1112e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1113e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1114e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1115e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 111682ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 11173972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 11182b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 11193972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 11202fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 11213972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 11222b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 11233972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1124e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1125e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11268d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 11271b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 11288efcfb23SStefano Zampini } 1129a07ea27aSStefano Zampini } 1130b76ba322SStefano Zampini 11318efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 11328d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 11338d00608fSStefano Zampini /* store the original rhs */ 11348d00608fSStefano Zampini if (copy_rhs) { 11358d00608fSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 11368d00608fSStefano Zampini copy_rhs = PETSC_FALSE; 11378d00608fSStefano Zampini } 11388d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 11393972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 11400369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,rhs,rhs);CHKERRQ(ierr); 11413972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 11428efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 11437acc28cbSStefano Zampini if (ksp) { 11447acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 11457acc28cbSStefano Zampini } 11463308cffdSStefano Zampini } 11478efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1148b76ba322SStefano Zampini 11490369aaf7SStefano Zampini /* When using the benign trick: (TODO: what about FETI-DP?) 11500369aaf7SStefano Zampini - change rhs on pressures (iteration matrix is surely of type MATIS) 11510369aaf7SStefano Zampini - compute initial vector in benign space 11520369aaf7SStefano Zampini */ 11530369aaf7SStefano Zampini if (rhs && pcbddc->benign_saddle_point) { 115406f24817SStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 11554f1b2e48SStefano Zampini PetscInt i; 115606f24817SStefano Zampini 115706f24817SStefano Zampini /* store the original rhs */ 115806f24817SStefano Zampini if (copy_rhs) { 115906f24817SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 116006f24817SStefano Zampini copy_rhs = PETSC_FALSE; 116106f24817SStefano Zampini } 116206f24817SStefano Zampini 116306f24817SStefano Zampini /* now change (locally) the basis */ 116406f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,rhs,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 116506f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,rhs,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 116606f24817SStefano Zampini if (pcbddc->benign_change) { 116706f24817SStefano Zampini ierr = MatMultTranspose(pcbddc->benign_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 116806f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 116906f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11705cfd9691SStefano Zampini /* swap local iteration matrix (with the benign trick, amat == pmat) */ 1171a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 1172a3df083aSStefano Zampini /* benign shell mat mult for matis->A and pcis->A_IB*/ 1173a3df083aSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 1174a3df083aSStefano Zampini } else { 11755cfd9691SStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_FALSE);CHKERRQ(ierr); 117606f24817SStefano Zampini pcbddc->benign_original_mat = matis->A; 117706f24817SStefano Zampini matis->A = pcbddc->local_mat; 1178a3df083aSStefano Zampini } 117906f24817SStefano Zampini } else { 118006f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 118106f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 118277a2de6eSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 118377a2de6eSStefano Zampini pcbddc->benign_original_mat = matis->A; 118477a2de6eSStefano Zampini matis->A = pcbddc->local_mat; 118577a2de6eSStefano Zampini } 118606f24817SStefano Zampini } 118706f24817SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 118806f24817SStefano Zampini 11890369aaf7SStefano Zampini /* compute u^*_h as in Xuemin Tu's thesis (see Section 4.8.1) */ 11900369aaf7SStefano Zampini /* TODO: what about Stokes? */ 11910369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 11920369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 11930369aaf7SStefano Zampini } 11944f1b2e48SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 11954f1b2e48SStefano Zampini if (pcbddc->benign_n) { 11960369aaf7SStefano Zampini const PetscScalar *array; 11970369aaf7SStefano Zampini 11980369aaf7SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array);CHKERRQ(ierr); 11994f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[pcbddc->benign_p0_lidx[i]]; 12000369aaf7SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array);CHKERRQ(ierr); 12010369aaf7SStefano Zampini } 120251694757SStefano Zampini if (pcbddc->benign_null && iscg) { /* this is a workaround, need to understand more */ 12034f1b2e48SStefano Zampini PetscBool iszero_l = PETSC_TRUE; 12044f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 12054f1b2e48SStefano Zampini iszero_l = (iszero_l && (PetscAbsScalar(pcbddc->benign_p0[i]) < PETSC_SMALL ? PETSC_TRUE : PETSC_FALSE)); 12064f1b2e48SStefano Zampini } 120751694757SStefano Zampini ierr = MPI_Allreduce(&iszero_l,&benign_correction_is_zero,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 120851694757SStefano Zampini } 12094fee134fSStefano Zampini if (!benign_correction_is_zero) { /* use the coarse solver only */ 1210015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 12114fee134fSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_TRUE; 12120369aaf7SStefano Zampini ierr = PCApply_BDDC(pc,pcis->vec1_global,pcbddc->benign_vec);CHKERRQ(ierr); 12134fee134fSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 12144f1b2e48SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 1215015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcbddc->benign_vec,PETSC_FALSE);CHKERRQ(ierr); 1216b76ba322SStefano Zampini } 121751694757SStefano Zampini } 1218b76ba322SStefano Zampini 12190369aaf7SStefano Zampini /* change rhs and iteration matrix if using the change of basis */ 1220b9b85e73SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1221906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 1222906d46d4SStefano Zampini 1223906d46d4SStefano Zampini /* get change ctx */ 1224906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 1225906d46d4SStefano Zampini 1226906d46d4SStefano Zampini /* set current iteration matrix inside change context (change of basis has been already set into the ctx during PCSetUp) */ 122777a2de6eSStefano Zampini if (!pcbddc->benign_original_mat) { 1228906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->original_mat);CHKERRQ(ierr); 1229906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pc->mat);CHKERRQ(ierr); 1230906d46d4SStefano Zampini change_ctx->original_mat = pc->mat; 1231906d46d4SStefano Zampini 1232906d46d4SStefano Zampini /* change iteration matrix */ 1233906d46d4SStefano Zampini ierr = MatDestroy(&pc->mat);CHKERRQ(ierr); 1234906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->new_global_mat);CHKERRQ(ierr); 1235906d46d4SStefano Zampini pc->mat = pcbddc->new_global_mat; 12369bd2e3c7SStefano Zampini } 12378d00608fSStefano Zampini /* store the original rhs */ 12388d00608fSStefano Zampini if (copy_rhs) { 12398d00608fSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 12408d00608fSStefano Zampini copy_rhs = PETSC_FALSE; 12418d00608fSStefano Zampini } 12428d00608fSStefano Zampini 1243906d46d4SStefano Zampini /* change rhs */ 1244906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,rhs,pcis->vec1_global);CHKERRQ(ierr); 1245906d46d4SStefano Zampini ierr = VecCopy(pcis->vec1_global,rhs);CHKERRQ(ierr); 12468d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 124792e3dcfbSStefano Zampini } 124892e3dcfbSStefano Zampini 12490369aaf7SStefano Zampini /* remove non-benign solution from the rhs */ 12500369aaf7SStefano Zampini if (pcbddc->benign_saddle_point) { 12510369aaf7SStefano Zampini /* store the original rhs */ 12520369aaf7SStefano Zampini if (copy_rhs) { 12530369aaf7SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 12540369aaf7SStefano Zampini copy_rhs = PETSC_FALSE; 12550369aaf7SStefano Zampini } 125651694757SStefano Zampini if (benign_correction_is_zero) { /* still need to understand why it works great */ 125751694757SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 125851694757SStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 125951694757SStefano Zampini } 12600369aaf7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 12610369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 12620369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 12630369aaf7SStefano Zampini } 12640369aaf7SStefano Zampini 12650369aaf7SStefano Zampini /* set initial guess if using PCG */ 12660369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 12670369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 12680369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12690369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12700369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 12710369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12720369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12730369aaf7SStefano Zampini if (ksp) { 12740369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 12750369aaf7SStefano Zampini } 12760369aaf7SStefano Zampini } 1277b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 1278b0f5fe93SStefano Zampini MatNullSpace null_space; 1279b0f5fe93SStefano Zampini Vec nullv; 1280b0f5fe93SStefano Zampini PetscBool isnull; 12814f1b2e48SStefano Zampini PetscInt i; 1282b0f5fe93SStefano Zampini 12834f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1.; 1284b0f5fe93SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&nullv);CHKERRQ(ierr); 1285b0f5fe93SStefano Zampini ierr = VecSet(nullv,0.);CHKERRQ(ierr); 1286b0f5fe93SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,nullv,PETSC_FALSE);CHKERRQ(ierr); 1287b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 1288b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)pc),PETSC_FALSE,1,&nullv,&null_space);CHKERRQ(ierr); 1289b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(null_space,pc->mat,&isnull);CHKERRQ(ierr); 12904f1b2e48SStefano Zampini if (isnull) { 1291b0f5fe93SStefano Zampini ierr = MatSetNullSpace(pc->mat,null_space);CHKERRQ(ierr); 12924f1b2e48SStefano Zampini } 1293b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&null_space);CHKERRQ(ierr); 1294b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 1295b0f5fe93SStefano Zampini } 1296b0f5fe93SStefano Zampini 129792e3dcfbSStefano Zampini /* remove nullspace if present */ 12988efcfb23SStefano Zampini if (ksp && x && pcbddc->NullSpace) { 12998efcfb23SStefano Zampini ierr = MatNullSpaceRemove(pcbddc->NullSpace,x);CHKERRQ(ierr); 13008d00608fSStefano Zampini /* store the original rhs */ 13018d00608fSStefano Zampini if (copy_rhs) { 13028d00608fSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 13038d00608fSStefano Zampini copy_rhs = PETSC_FALSE; 13048d00608fSStefano Zampini } 13058d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 1306d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs);CHKERRQ(ierr); 1307b76ba322SStefano Zampini } 1308534831adSStefano Zampini PetscFunctionReturn(0); 1309534831adSStefano Zampini } 1310906d46d4SStefano Zampini 1311534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1312534831adSStefano Zampini #undef __FUNCT__ 1313534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 1314534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1315534831adSStefano Zampini /* 1316534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1317534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1318534831adSStefano Zampini 1319534831adSStefano Zampini Input Parameter: 1320534831adSStefano Zampini + pc - the preconditioner contex 1321534831adSStefano Zampini 1322534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1323534831adSStefano Zampini 1324534831adSStefano Zampini Notes: 1325534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1326534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1327534831adSStefano Zampini */ 1328534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1329534831adSStefano Zampini { 1330534831adSStefano Zampini PetscErrorCode ierr; 1331534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1332534831adSStefano Zampini 1333534831adSStefano Zampini PetscFunctionBegin; 133477a2de6eSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && !pcbddc->benign_original_mat) { 1335906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 1336906d46d4SStefano Zampini 1337906d46d4SStefano Zampini /* get change ctx */ 1338906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 1339906d46d4SStefano Zampini 1340906d46d4SStefano Zampini /* restore iteration matrix */ 1341906d46d4SStefano Zampini ierr = MatDestroy(&pc->mat);CHKERRQ(ierr); 1342906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)change_ctx->original_mat);CHKERRQ(ierr); 1343906d46d4SStefano Zampini pc->mat = change_ctx->original_mat; 13449c6a02ceSStefano Zampini } 1345906d46d4SStefano Zampini 13468666afb4SStefano Zampini /* need to restore the local matrices */ 134777a2de6eSStefano Zampini if (pcbddc->benign_original_mat) { 13488666afb4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->mat->data; 13498666afb4SStefano Zampini 1350a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 1351a3df083aSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1352a3df083aSStefano Zampini } else { 13535cfd9691SStefano Zampini pcbddc->local_mat = matis->A; 13548666afb4SStefano Zampini matis->A = pcbddc->benign_original_mat; 13555cfd9691SStefano Zampini pcbddc->benign_original_mat = NULL; 13568666afb4SStefano Zampini } 1357a3df083aSStefano Zampini } 13588666afb4SStefano Zampini 1359906d46d4SStefano Zampini /* get solution in original basis */ 1360906d46d4SStefano Zampini if (x) { 1361906d46d4SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 136206f24817SStefano Zampini 13632d3346b4SStefano Zampini /* restore solution on pressures */ 136406a4e24aSStefano Zampini if (pcbddc->benign_saddle_point) { 13652d3346b4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->mat->data; 13662d3346b4SStefano Zampini 13670369aaf7SStefano Zampini /* add non-benign solution */ 13688666afb4SStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 13690369aaf7SStefano Zampini 13700369aaf7SStefano Zampini /* change basis on pressures for x */ 137106f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 137206f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13732d3346b4SStefano Zampini if (pcbddc->benign_change) { 13742d3346b4SStefano Zampini ierr = MatMult(pcbddc->benign_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 137506f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 137606f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13772d3346b4SStefano Zampini } else { 137806f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 137906f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13802d3346b4SStefano Zampini } 13812d3346b4SStefano Zampini } 13829c6a02ceSStefano Zampini 13830369aaf7SStefano Zampini /* change basis on x */ 13849c6a02ceSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 13859c6a02ceSStefano Zampini PCBDDCChange_ctx change_ctx; 13869c6a02ceSStefano Zampini 13879c6a02ceSStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 13880369aaf7SStefano Zampini ierr = MatMult(change_ctx->global_change,x,pcis->vec1_global);CHKERRQ(ierr); 1389906d46d4SStefano Zampini ierr = VecCopy(pcis->vec1_global,x);CHKERRQ(ierr); 13903425bc38SStefano Zampini } 1391534831adSStefano Zampini } 1392906d46d4SStefano Zampini 13933972b0daSStefano Zampini /* add solution removed in presolve */ 13946bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 13953425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 13963425bc38SStefano Zampini } 1397906d46d4SStefano Zampini 1398fb223d50SStefano Zampini /* restore rhs to its original state */ 13998d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 1400fb223d50SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 1401fb223d50SStefano Zampini } 14028d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 14038efcfb23SStefano Zampini 14048efcfb23SStefano Zampini /* restore ksp guess state */ 14058efcfb23SStefano Zampini if (ksp) { 14068efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 14078efcfb23SStefano Zampini } 1408534831adSStefano Zampini PetscFunctionReturn(0); 1409534831adSStefano Zampini } 1410534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 141153cdbc3dSStefano Zampini #undef __FUNCT__ 141253cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 14130c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 14140c7d97c5SJed Brown /* 14150c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 14160c7d97c5SJed Brown by setting data structures and options. 14170c7d97c5SJed Brown 14180c7d97c5SJed Brown Input Parameter: 141953cdbc3dSStefano Zampini + pc - the preconditioner context 14200c7d97c5SJed Brown 14210c7d97c5SJed Brown Application Interface Routine: PCSetUp() 14220c7d97c5SJed Brown 14230c7d97c5SJed Brown Notes: 14240c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 14250c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 14260c7d97c5SJed Brown */ 142753cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 14280c7d97c5SJed Brown { 14290c7d97c5SJed Brown PetscErrorCode ierr; 14300c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 14315e8657edSStefano Zampini Mat_IS* matis; 143208122e43SStefano Zampini MatNullSpace nearnullspace; 1433c9ed8603SStefano Zampini IS zerodiag = NULL; 143491e8d312SStefano Zampini PetscInt nrows,ncols; 143508122e43SStefano Zampini PetscBool computetopography,computesolvers,computesubschurs; 14368de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 14375e8657edSStefano Zampini PetscBool new_nearnullspace_provided,ismatis; 14380c7d97c5SJed Brown 14390c7d97c5SJed Brown PetscFunctionBegin; 14405e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 14415e8657edSStefano Zampini if (!ismatis) { 14425e8657edSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 14435e8657edSStefano Zampini } 144491e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 144591e8d312SStefano Zampini if (nrows != ncols) { 144691e8d312SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 144791e8d312SStefano Zampini } 14485e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1449f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 14503b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 1451fcd409f5SStefano Zampini Also, BDDC directly build the Dirichlet problem */ 1452f4ddd8eeSStefano Zampini /* split work */ 1453674ae819SStefano Zampini if (pc->setupcalled) { 1454d1e9a80fSBarry Smith if (pc->flag == SAME_NONZERO_PATTERN) { 1455674ae819SStefano Zampini computetopography = PETSC_FALSE; 1456674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1457674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 1458674ae819SStefano Zampini computetopography = PETSC_TRUE; 1459674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1460674ae819SStefano Zampini } 1461674ae819SStefano Zampini } else { 1462674ae819SStefano Zampini computetopography = PETSC_TRUE; 1463674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1464674ae819SStefano Zampini } 1465fb180af4SStefano Zampini if (pcbddc->recompute_topography) { 1466fb180af4SStefano Zampini computetopography = PETSC_TRUE; 1467fb180af4SStefano Zampini } 146856282151SStefano Zampini pcbddc->recompute_topography = computetopography; 14698de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1470b087196eSStefano Zampini 1471b087196eSStefano Zampini /* check parameters' compatibility */ 14725a95e1ceSStefano Zampini if (pcbddc->adaptive_threshold > 0.0 && !pcbddc->use_deluxe_scaling) { 14735a95e1ceSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute adaptive constraints without deluxe scaling. Rerun with -pc_bddc_use_deluxe_scaling"); 14745a95e1ceSStefano Zampini } 14755a95e1ceSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold > 0.0 && pcbddc->use_deluxe_scaling); 1476bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1477862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1478862806e4SStefano Zampini 14795a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 14806816873aSStefano Zampini if (pcbddc->faster_deluxe && pcbddc->adaptive_selection && pcbddc->use_change_of_basis) { 14816816873aSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute faster deluxe if adaptivity and change of basis are both requested. Rerun with -pc_bddc_deluxe_faster false"); 14826816873aSStefano Zampini } 1483*14f95afaSStefano Zampini if (pcbddc->benign_saddle_point && pcbddc->switch_static) { 1484*14f95afaSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Benign subspace trick cannot be used with M_3"); 1485*14f95afaSStefano Zampini } 14862d3346b4SStefano Zampini 14872d3346b4SStefano Zampini /* check if the iteration matrix is of type MATIS in case the benign trick has been requested */ 14882d3346b4SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr); 148906a4e24aSStefano Zampini if (pcbddc->benign_saddle_point && !ismatis) { 14902d3346b4SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner with benign subspace trick requires the iteration matrix to be of type MATIS"); 14912d3346b4SStefano Zampini } 14925cfd9691SStefano Zampini if (pcbddc->benign_saddle_point && pc->mat != pc->pmat) { 149316e386b8SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner with benign subspace trick requires Amat == Pmat"); 14945cfd9691SStefano Zampini } 14952d3346b4SStefano Zampini 1496f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 149770cf5478SStefano Zampini if (pcbddc->dbg_flag) { 149870cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 149958a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 15001575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1501f4ddd8eeSStefano Zampini } 150258a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1503f4ddd8eeSStefano Zampini } 1504f4ddd8eeSStefano Zampini 15055e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 15065e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 15075e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 15085e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 15095e8657edSStefano Zampini } else { 1510b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 15115e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 15125e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1513d16cbb6bSStefano Zampini } 1514d16cbb6bSStefano Zampini 15154f1b2e48SStefano Zampini /* detect local disconnected subdomains if requested and not done before */ 15164f1b2e48SStefano Zampini if (pcbddc->detect_disconnected && !pcbddc->n_local_subs) { 15174f1b2e48SStefano Zampini ierr = MatDetectDisconnectedComponents(pcbddc->local_mat,PETSC_FALSE,&pcbddc->n_local_subs,&pcbddc->local_subs);CHKERRQ(ierr); 15184f1b2e48SStefano Zampini } 15194f1b2e48SStefano Zampini 15204f1b2e48SStefano Zampini /* 15214f1b2e48SStefano Zampini change basis on local pressures (aka zerodiag dofs) 15224f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 15234f1b2e48SStefano Zampini */ 1524d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 15259f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 15269f47a83aSStefano Zampini 152705b28244SStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis || !computesubschurs) pcbddc->benign_change_explicit = PETSC_TRUE; 1528339f8db1SStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat */ 1529339f8db1SStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,&zerodiag);CHKERRQ(ierr); 1530a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1531c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 15329f47a83aSStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 1533a3df083aSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcbddc->benign_n && !pcbddc->benign_change_explicit && !pcbddc->dbg_flag) { 1534a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 1535a3df083aSStefano Zampini } else { 15369f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1537674ae819SStefano Zampini } 1538a3df083aSStefano Zampini } 1539f1a72664SStefano Zampini /* propagate relevant information */ 15404f1b2e48SStefano Zampini #if !defined(PETSC_USE_COMPLEX) /* workaround for reals */ 15413301b35fSStefano Zampini if (matis->A->symmetric_set) { 15423301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 15433301b35fSStefano Zampini } 1544e496cd5dSStefano Zampini #endif 154506a4e24aSStefano Zampini if (matis->A->symmetric_set) { 154606a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 154706a4e24aSStefano Zampini } 154806a4e24aSStefano Zampini if (matis->A->spd_set) { 154906a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 155006a4e24aSStefano Zampini } 1551e496cd5dSStefano Zampini 15525e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 15535e8657edSStefano Zampini { 15545e8657edSStefano Zampini Mat temp_mat; 15555e8657edSStefano Zampini 15565e8657edSStefano Zampini temp_mat = matis->A; 15575e8657edSStefano Zampini matis->A = pcbddc->local_mat; 15585e8657edSStefano Zampini ierr = PCISSetUp(pc,PETSC_FALSE);CHKERRQ(ierr); 15595e8657edSStefano Zampini pcbddc->local_mat = matis->A; 15605e8657edSStefano Zampini matis->A = temp_mat; 15615e8657edSStefano Zampini } 1562684f6988SStefano Zampini 156381d14e9dSStefano Zampini /* Analyze interface */ 1564674ae819SStefano Zampini if (computetopography) { 1565674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 15668de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1567674ae819SStefano Zampini } 1568fb8d54d4SStefano Zampini 15695408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 15705408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 15715408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 15725408967cSStefano Zampini #if defined(PETSC_USE_DEBUG) 157309f581a4SStefano Zampini if (pcbddc->benign_saddle_point) { 15745408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 157509f581a4SStefano Zampini } 15765408967cSStefano Zampini #endif 15774f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 157806f24817SStefano Zampini 1579b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1580684f6988SStefano Zampini if (computesolvers) { 1581d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 1582d5574798SStefano Zampini 1583d5574798SStefano Zampini if (computesubschurs && computetopography) { 158408122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1585b1b3d7a2SStefano Zampini } 1586df4d28bfSStefano Zampini if (sub_schurs->schur_explicit) { 15872070dbb6SStefano Zampini if (computesubschurs) { 158808122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 15892070dbb6SStefano Zampini } 1590d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1591d5574798SStefano Zampini } else { 1592d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 15932070dbb6SStefano Zampini if (computesubschurs) { 1594d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1595d5574798SStefano Zampini } 15962070dbb6SStefano Zampini } 159708122e43SStefano Zampini if (pcbddc->adaptive_selection) { 159808122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 15998de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1600b7eb3628SStefano Zampini } 1601b1b3d7a2SStefano Zampini } 1602684f6988SStefano Zampini 1603f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1604fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1605f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1606f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1607f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1608f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1609f4ddd8eeSStefano Zampini } else { 1610f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1611f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1612f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1613165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1614f4ddd8eeSStefano Zampini PetscInt i; 1615165b64e2SStefano Zampini const Vec *nearnullvecs; 1616165b64e2SStefano Zampini PetscObjectState state; 1617165b64e2SStefano Zampini PetscInt nnsp_size; 1618165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1619f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1620f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1621165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1622f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1623f4ddd8eeSStefano Zampini break; 1624f4ddd8eeSStefano Zampini } 1625f4ddd8eeSStefano Zampini } 1626f4ddd8eeSStefano Zampini } 1627f4ddd8eeSStefano Zampini } 1628f4ddd8eeSStefano Zampini } else { 1629f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1630f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1631f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1632f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1633f4ddd8eeSStefano Zampini } 1634f4ddd8eeSStefano Zampini } 1635f4ddd8eeSStefano Zampini 1636f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1637727cdba6SStefano Zampini /* reset primal space flags */ 1638f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1639727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 16408de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1641727cdba6SStefano Zampini /* It also sets the primal space flags */ 1642674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 1643e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1644f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 16453975b054SStefano Zampini } 16465e8657edSStefano Zampini 16473975b054SStefano Zampini if (computesolvers || pcbddc->new_primal_space) { 16485e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 16495e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 1650c263805aSStefano Zampini Mat temp_mat = NULL; 16515e8657edSStefano Zampini 16524f1b2e48SStefano Zampini if (pcbddc->benign_change) { 1653c263805aSStefano Zampini /* insert B0 in pcbddc->local_mat */ 1654c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_FALSE);CHKERRQ(ierr); 1655f1a72664SStefano Zampini /* swap local matrices */ 1656f1a72664SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&temp_mat);CHKERRQ(ierr); 1657f1a72664SStefano Zampini ierr = PetscObjectReference((PetscObject)temp_mat);CHKERRQ(ierr); 1658f1a72664SStefano Zampini ierr = MatISSetLocalMat(pc->pmat,pcbddc->local_mat);CHKERRQ(ierr); 1659f1a72664SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1660c263805aSStefano Zampini } 16615e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 16624f1b2e48SStefano Zampini if (pcbddc->benign_change) { 1663c263805aSStefano Zampini /* restore original matrix */ 1664f1a72664SStefano Zampini ierr = MatISSetLocalMat(pc->pmat,temp_mat);CHKERRQ(ierr); 1665f1a72664SStefano Zampini ierr = PetscObjectDereference((PetscObject)temp_mat);CHKERRQ(ierr); 1666c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1667c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1668c263805aSStefano Zampini } 16695e8657edSStefano Zampini /* get submatrices */ 16705e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 16715e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 16725e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 16735e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 16745e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 16755e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 16763975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 16773975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16789c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1679b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16805e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 16815e8657edSStefano Zampini pcbddc->local_mat = matis->A; 16825e8657edSStefano Zampini } 1683b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 168499cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1685b96c3477SStefano Zampini /* SetUp Scaling operator */ 1686674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 16870c7d97c5SJed Brown } 168856282151SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 16890369aaf7SStefano Zampini 169058a03d70SStefano Zampini if (pcbddc->dbg_flag) { 169158a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 16922b510759SStefano Zampini } 16930c7d97c5SJed Brown PetscFunctionReturn(0); 16940c7d97c5SJed Brown } 16950c7d97c5SJed Brown 16960c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 16970c7d97c5SJed Brown /* 169850efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 16990c7d97c5SJed Brown 17000c7d97c5SJed Brown Input Parameters: 17010f202f7eSStefano Zampini + pc - the preconditioner context 17020f202f7eSStefano Zampini - r - input vector (global) 17030c7d97c5SJed Brown 17040c7d97c5SJed Brown Output Parameter: 17050c7d97c5SJed Brown . z - output vector (global) 17060c7d97c5SJed Brown 17070c7d97c5SJed Brown Application Interface Routine: PCApply() 17080c7d97c5SJed Brown */ 17090c7d97c5SJed Brown #undef __FUNCT__ 17100c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 171153cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 17120c7d97c5SJed Brown { 17130c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 17140c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1715b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 17160c7d97c5SJed Brown PetscErrorCode ierr; 17173b03a366Sstefano_zampini const PetscScalar one = 1.0; 17183b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 17192617d88aSStefano Zampini const PetscScalar zero = 0.0; 17200c7d97c5SJed Brown 17210c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 17220c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1723b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 17240c7d97c5SJed Brown 17250c7d97c5SJed Brown PetscFunctionBegin; 1726015636ebSStefano Zampini if (pcbddc->benign_saddle_point) { /* get p0 from r */ 1727015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1728efc2fbd9SStefano Zampini } 172985c4d303SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1730b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 17310c7d97c5SJed Brown /* First Dirichlet solve */ 17320c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17330c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17340c7d97c5SJed Brown /* 17350c7d97c5SJed Brown Assembling right hand side for BDDC operator 1736b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1737674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 17380c7d97c5SJed Brown */ 1739b097fa66SStefano Zampini if (n_D) { 1740b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 17410c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 17428eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1743b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 1744b097fa66SStefano Zampini } else { 1745b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1746b097fa66SStefano Zampini } 17470c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17480c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1749674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1750b76ba322SStefano Zampini } else { 17514fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1752b097fa66SStefano Zampini if (pcbddc->switch_static) { 17530bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 1754b097fa66SStefano Zampini } 1755674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1756b76ba322SStefano Zampini } 17574fee134fSStefano Zampini } 1758b76ba322SStefano Zampini 17592617d88aSStefano Zampini /* Apply interface preconditioner 17602617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1761dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 17622617d88aSStefano Zampini 1763674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1764674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 17650c7d97c5SJed Brown 17663b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 17670c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17680c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1769b097fa66SStefano Zampini if (n_B) { 17700c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 17718eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 1772b097fa66SStefano Zampini } else if (pcbddc->switch_static) { 1773b097fa66SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 1774b097fa66SStefano Zampini } 1775df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1776efc2fbd9SStefano Zampini 1777b097fa66SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1778b097fa66SStefano Zampini if (pcbddc->switch_static) { 1779b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1780b097fa66SStefano Zampini } else { 1781b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1782b097fa66SStefano Zampini } 17830c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17840c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1785b097fa66SStefano Zampini } else { 1786b097fa66SStefano Zampini if (pcbddc->switch_static) { 1787b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1788b097fa66SStefano Zampini } else { 1789b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1790b097fa66SStefano Zampini } 1791b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1792b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1793b097fa66SStefano Zampini } 1794efc2fbd9SStefano Zampini 1795015636ebSStefano Zampini if (pcbddc->benign_saddle_point) { /* set p0 (computed in PCBDDCApplyInterface) */ 1796015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1797efc2fbd9SStefano Zampini } 17980c7d97c5SJed Brown PetscFunctionReturn(0); 17990c7d97c5SJed Brown } 180050efa1b5SStefano Zampini 180150efa1b5SStefano Zampini /* -------------------------------------------------------------------------- */ 180250efa1b5SStefano Zampini /* 180350efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 180450efa1b5SStefano Zampini 180550efa1b5SStefano Zampini Input Parameters: 18060f202f7eSStefano Zampini + pc - the preconditioner context 18070f202f7eSStefano Zampini - r - input vector (global) 180850efa1b5SStefano Zampini 180950efa1b5SStefano Zampini Output Parameter: 181050efa1b5SStefano Zampini . z - output vector (global) 181150efa1b5SStefano Zampini 181250efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 181350efa1b5SStefano Zampini */ 181450efa1b5SStefano Zampini #undef __FUNCT__ 181550efa1b5SStefano Zampini #define __FUNCT__ "PCApplyTranspose_BDDC" 181650efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 181750efa1b5SStefano Zampini { 181850efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 181950efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1820b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 182150efa1b5SStefano Zampini PetscErrorCode ierr; 182250efa1b5SStefano Zampini const PetscScalar one = 1.0; 182350efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 182450efa1b5SStefano Zampini const PetscScalar zero = 0.0; 182550efa1b5SStefano Zampini 182650efa1b5SStefano Zampini PetscFunctionBegin; 1827537c1cdfSStefano Zampini if (pcbddc->benign_saddle_point) { /* get p0 from r */ 1828537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1829537c1cdfSStefano Zampini } 183050efa1b5SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1831b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 183250efa1b5SStefano Zampini /* First Dirichlet solve */ 183350efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 183450efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 183550efa1b5SStefano Zampini /* 183650efa1b5SStefano Zampini Assembling right hand side for BDDC operator 1837b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 183850efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 183950efa1b5SStefano Zampini */ 1840b097fa66SStefano Zampini if (n_D) { 1841b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 184250efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 184350efa1b5SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1844b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 1845b097fa66SStefano Zampini } else { 1846b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1847b097fa66SStefano Zampini } 184850efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 184950efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 185050efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 185150efa1b5SStefano Zampini } else { 1852b097fa66SStefano Zampini if (pcbddc->switch_static) { 185350efa1b5SStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 1854b097fa66SStefano Zampini } 185550efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 185650efa1b5SStefano Zampini } 185750efa1b5SStefano Zampini 185850efa1b5SStefano Zampini /* Apply interface preconditioner 185950efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1860dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 186150efa1b5SStefano Zampini 186250efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 186350efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 186450efa1b5SStefano Zampini 186550efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 186650efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 186750efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1868b097fa66SStefano Zampini if (n_B) { 186950efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 187050efa1b5SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 1871b097fa66SStefano Zampini } else if (pcbddc->switch_static) { 1872b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_II,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 1873b097fa66SStefano Zampini } 1874b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1875b097fa66SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1876b097fa66SStefano Zampini if (pcbddc->switch_static) { 1877b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1878b097fa66SStefano Zampini } else { 1879b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1880b097fa66SStefano Zampini } 188150efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 188250efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1883b097fa66SStefano Zampini } else { 1884b097fa66SStefano Zampini if (pcbddc->switch_static) { 1885b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1886b097fa66SStefano Zampini } else { 1887b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1888b097fa66SStefano Zampini } 1889b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1890b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1891b097fa66SStefano Zampini } 1892537c1cdfSStefano Zampini if (pcbddc->benign_saddle_point) { /* set p0 (computed in PCBDDCApplyInterface) */ 1893537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1894537c1cdfSStefano Zampini } 189550efa1b5SStefano Zampini PetscFunctionReturn(0); 189650efa1b5SStefano Zampini } 1897da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1898674ae819SStefano Zampini 1899da1bb401SStefano Zampini #undef __FUNCT__ 1900da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 1901da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 1902da1bb401SStefano Zampini { 1903da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1904da1bb401SStefano Zampini PetscErrorCode ierr; 1905da1bb401SStefano Zampini 1906da1bb401SStefano Zampini PetscFunctionBegin; 1907da1bb401SStefano Zampini /* free data created by PCIS */ 1908da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 1909674ae819SStefano Zampini /* free BDDC custom data */ 1910674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 1911674ae819SStefano Zampini /* destroy objects related to topography */ 1912674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 1913674ae819SStefano Zampini /* free allocated graph structure */ 1914da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 1915b96c3477SStefano Zampini /* free allocated sub schurs structure */ 1916b96c3477SStefano Zampini ierr = PetscFree(pcbddc->sub_schurs);CHKERRQ(ierr); 191734a97f8cSStefano Zampini /* destroy objects for scaling operator */ 1918674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 191934a97f8cSStefano Zampini ierr = PetscFree(pcbddc->deluxe_ctx);CHKERRQ(ierr); 1920674ae819SStefano Zampini /* free solvers stuff */ 1921674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 192262a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 192362a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 192462a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 1925906d46d4SStefano Zampini /* free stuff for change of basis hooks */ 1926906d46d4SStefano Zampini if (pcbddc->new_global_mat) { 1927906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 1928906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 1929906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->original_mat);CHKERRQ(ierr); 1930906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 1931906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 1932906d46d4SStefano Zampini ierr = PetscFree(change_ctx);CHKERRQ(ierr); 1933906d46d4SStefano Zampini } 1934906d46d4SStefano Zampini ierr = MatDestroy(&pcbddc->new_global_mat);CHKERRQ(ierr); 19353425bc38SStefano Zampini /* remove functions */ 1936906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 1937674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 193830368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 1939bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 19402b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 1941b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 19422b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 1943bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 1944bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 194582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 1946bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 194782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 1948bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 194982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 1950bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 1951785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 1952bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 195363602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 1954bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 1955bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 1956bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 1957bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 1958674ae819SStefano Zampini /* Free the private data structure */ 1959674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 1960da1bb401SStefano Zampini PetscFunctionReturn(0); 1961da1bb401SStefano Zampini } 19623425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 19631e6b0712SBarry Smith 19643425bc38SStefano Zampini #undef __FUNCT__ 19653425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 19663425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 19673425bc38SStefano Zampini { 1968674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 1969c08af4c6SStefano Zampini Vec copy_standard_rhs; 19703425bc38SStefano Zampini PC_IS* pcis; 19713425bc38SStefano Zampini PC_BDDC* pcbddc; 19723425bc38SStefano Zampini PetscErrorCode ierr; 19730c7d97c5SJed Brown 19743425bc38SStefano Zampini PetscFunctionBegin; 19753425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 19763425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 19773425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 19783425bc38SStefano Zampini 1979c08af4c6SStefano Zampini /* 1980c08af4c6SStefano Zampini change of basis for physical rhs if needed 1981c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 1982c08af4c6SStefano Zampini TODO: better management when FETIDP will have its own class 1983c08af4c6SStefano Zampini */ 1984c08af4c6SStefano Zampini ierr = VecDuplicate(standard_rhs,©_standard_rhs);CHKERRQ(ierr); 1985c08af4c6SStefano Zampini ierr = VecCopy(standard_rhs,copy_standard_rhs);CHKERRQ(ierr); 1986c08af4c6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,copy_standard_rhs,NULL);CHKERRQ(ierr); 19873425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 1988c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,copy_standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1989c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,copy_standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1990fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 1991fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 1992c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1993c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1994674ae819SStefano Zampini /* Apply partition of unity */ 19953425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 1996c08af4c6SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,copy_standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 19978eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 19983425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 19993425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20003425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 20013425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 2002c08af4c6SStefano Zampini ierr = VecSet(copy_standard_rhs,0.0);CHKERRQ(ierr); 2003c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,copy_standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2004c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,copy_standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2005c08af4c6SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,copy_standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 2006c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2007c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20083425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 20093425bc38SStefano Zampini } 2010c08af4c6SStefano Zampini ierr = VecDestroy(©_standard_rhs);CHKERRQ(ierr); 20113425bc38SStefano Zampini /* BDDC rhs */ 20123425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 20138eeda7d8SStefano Zampini if (pcbddc->switch_static) { 20143425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20153425bc38SStefano Zampini } 20163425bc38SStefano Zampini /* apply BDDC */ 2017dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 20183425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 20193425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 20203425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 20213425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20223425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 20233425bc38SStefano Zampini PetscFunctionReturn(0); 20243425bc38SStefano Zampini } 20251e6b0712SBarry Smith 20263425bc38SStefano Zampini #undef __FUNCT__ 20273425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 20283425bc38SStefano Zampini /*@ 20290f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 20303425bc38SStefano Zampini 20313425bc38SStefano Zampini Collective 20323425bc38SStefano Zampini 20333425bc38SStefano Zampini Input Parameters: 20340f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 20350f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 20363425bc38SStefano Zampini 20373425bc38SStefano Zampini Output Parameters: 20380f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 20393425bc38SStefano Zampini 20403425bc38SStefano Zampini Level: developer 20413425bc38SStefano Zampini 20423425bc38SStefano Zampini Notes: 20433425bc38SStefano Zampini 20440f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 20453425bc38SStefano Zampini @*/ 20463425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 20473425bc38SStefano Zampini { 2048674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 20493425bc38SStefano Zampini PetscErrorCode ierr; 20503425bc38SStefano Zampini 20513425bc38SStefano Zampini PetscFunctionBegin; 20523425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 20533425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 20543425bc38SStefano Zampini PetscFunctionReturn(0); 20553425bc38SStefano Zampini } 20563425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 20571e6b0712SBarry Smith 20583425bc38SStefano Zampini #undef __FUNCT__ 20593425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 20603425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 20613425bc38SStefano Zampini { 2062674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 20633425bc38SStefano Zampini PC_IS* pcis; 20643425bc38SStefano Zampini PC_BDDC* pcbddc; 20653425bc38SStefano Zampini PetscErrorCode ierr; 20663425bc38SStefano Zampini 20673425bc38SStefano Zampini PetscFunctionBegin; 20683425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 20693425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 20703425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 20713425bc38SStefano Zampini 20723425bc38SStefano Zampini /* apply B_delta^T */ 20733425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20743425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20753425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 20763425bc38SStefano Zampini /* compute rhs for BDDC application */ 20773425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 20788eeda7d8SStefano Zampini if (pcbddc->switch_static) { 20793425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20803425bc38SStefano Zampini } 20813425bc38SStefano Zampini /* apply BDDC */ 2082dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 20833425bc38SStefano Zampini /* put values into standard global vector */ 20843425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20853425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20868eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 20873425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 20883425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 20893425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 20903425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20913425bc38SStefano Zampini } 20923425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20933425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20943425bc38SStefano Zampini /* final change of basis if needed 20953425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 20963308cffdSStefano Zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 20973425bc38SStefano Zampini PetscFunctionReturn(0); 20983425bc38SStefano Zampini } 20991e6b0712SBarry Smith 21003425bc38SStefano Zampini #undef __FUNCT__ 21013425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 21023425bc38SStefano Zampini /*@ 21030f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 21043425bc38SStefano Zampini 21053425bc38SStefano Zampini Collective 21063425bc38SStefano Zampini 21073425bc38SStefano Zampini Input Parameters: 21080f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 21090f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 21103425bc38SStefano Zampini 21113425bc38SStefano Zampini Output Parameters: 21120f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 21133425bc38SStefano Zampini 21143425bc38SStefano Zampini Level: developer 21153425bc38SStefano Zampini 21163425bc38SStefano Zampini Notes: 21173425bc38SStefano Zampini 21180f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 21193425bc38SStefano Zampini @*/ 21203425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 21213425bc38SStefano Zampini { 2122674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 21233425bc38SStefano Zampini PetscErrorCode ierr; 21243425bc38SStefano Zampini 21253425bc38SStefano Zampini PetscFunctionBegin; 21263425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 21273425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 21283425bc38SStefano Zampini PetscFunctionReturn(0); 21293425bc38SStefano Zampini } 21303425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 21311e6b0712SBarry Smith 2132f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 2133edf7251bSStefano Zampini extern PetscErrorCode FETIDPMatMultTranspose(Mat,Vec,Vec); 2134f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 2135f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 2136edf7251bSStefano Zampini extern PetscErrorCode FETIDPPCApplyTranspose(PC,Vec,Vec); 2137f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 2138674ae819SStefano Zampini 21393425bc38SStefano Zampini #undef __FUNCT__ 21403425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 21413425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 21423425bc38SStefano Zampini { 2143674ae819SStefano Zampini 2144674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 21453425bc38SStefano Zampini Mat newmat; 2146674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 21473425bc38SStefano Zampini PC newpc; 2148ce94432eSBarry Smith MPI_Comm comm; 21493425bc38SStefano Zampini PetscErrorCode ierr; 21503425bc38SStefano Zampini 21513425bc38SStefano Zampini PetscFunctionBegin; 2152ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 21533425bc38SStefano Zampini /* FETIDP linear matrix */ 21543425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 21553425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 21563425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 21573425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2158edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 21593425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 21603425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 21613425bc38SStefano Zampini /* FETIDP preconditioner */ 21623425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 21633425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 21643425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 21653425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 21663425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 21673425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2168edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 21693425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 217023ee1639SBarry Smith ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 21713425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 21723425bc38SStefano Zampini /* return pointers for objects created */ 21733425bc38SStefano Zampini *fetidp_mat=newmat; 21743425bc38SStefano Zampini *fetidp_pc=newpc; 21753425bc38SStefano Zampini PetscFunctionReturn(0); 21763425bc38SStefano Zampini } 21771e6b0712SBarry Smith 21783425bc38SStefano Zampini #undef __FUNCT__ 21793425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 21803425bc38SStefano Zampini /*@ 21810f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 21823425bc38SStefano Zampini 21833425bc38SStefano Zampini Collective 21843425bc38SStefano Zampini 21853425bc38SStefano Zampini Input Parameters: 21860f202f7eSStefano Zampini . pc - the BDDC preconditioning context (setup should have been called before) 218728509bceSStefano Zampini 218828509bceSStefano Zampini Output Parameters: 21890f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 21900f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 219128509bceSStefano Zampini 219228509bceSStefano Zampini Options Database Keys: 21930f202f7eSStefano Zampini . -fetidp_fullyredundant <false> - use or not a fully redundant set of Lagrange multipliers 21943425bc38SStefano Zampini 21953425bc38SStefano Zampini Level: developer 21963425bc38SStefano Zampini 21973425bc38SStefano Zampini Notes: 21980f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 21993425bc38SStefano Zampini 22000f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 22013425bc38SStefano Zampini @*/ 22023425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 22033425bc38SStefano Zampini { 22043425bc38SStefano Zampini PetscErrorCode ierr; 22053425bc38SStefano Zampini 22063425bc38SStefano Zampini PetscFunctionBegin; 22073425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 22083425bc38SStefano Zampini if (pc->setupcalled) { 2209516d51a7SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 2210f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 22113425bc38SStefano Zampini PetscFunctionReturn(0); 22123425bc38SStefano Zampini } 22130c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2214da1bb401SStefano Zampini /*MC 2215da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 22160c7d97c5SJed Brown 221728509bceSStefano Zampini An implementation of the BDDC preconditioner based on 221828509bceSStefano Zampini 221928509bceSStefano Zampini .vb 222028509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 222128509bceSStefano Zampini [2] A. Klawonn and O. B. Widlund. "Dual-Primal FETI Methods for Linear Elasticity", http://cs.nyu.edu/csweb/Research/TechReports/TR2004-855/TR2004-855.pdf 222228509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 22230f202f7eSStefano Zampini [4] C. Pechstein and C. R. Dohrmann. "Modern domain decomposition methods BDDC, deluxe scaling, and an algebraic approach", Seminar talk, Linz, December 2013, http://people.ricam.oeaw.ac.at/c.pechstein/pechstein-bddc2013.pdf 222428509bceSStefano Zampini .ve 222528509bceSStefano Zampini 222628509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 222728509bceSStefano Zampini 22280f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 222928509bceSStefano Zampini 223028509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 223128509bceSStefano Zampini 2232b6fdb6dfSStefano Zampini Unlike 'conventional' interface preconditioners, PCBDDC iterates over all degrees of freedom, not just those on the interface. This allows the use of approximate solvers on the subdomains. 2233b6fdb6dfSStefano Zampini 22340f202f7eSStefano Zampini Approximate local solvers are automatically adapted for singular linear problems (see [1]) if the user has provided the nullspace using PCBDDCSetNullSpace() 223528509bceSStefano Zampini 22360f202f7eSStefano Zampini Boundary nodes are split in vertices, edges and faces classes using information from the local to global mapping of dofs and the local connectivity graph of nodes. The latter can be customized by using PCBDDCSetLocalAdjacencyGraph() 223730368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 223828509bceSStefano Zampini 22390f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 224028509bceSStefano Zampini 22410f202f7eSStefano Zampini Change of basis is performed similarly to [2] when requested. When more than one constraint is present on a single connected component (i.e. an edge or a face), a robust method based on local QR factorizations is used. 22420f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 224328509bceSStefano Zampini 22440f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 224528509bceSStefano Zampini 2246df4d28bfSStefano Zampini Adaptive selection of primal constraints [4] is supported for SPD systems with high-contrast in the coefficients if MUMPS or MKL_PARDISO are present. Future versions of the code will also consider using PASTIX. 224728509bceSStefano Zampini 22480f202f7eSStefano Zampini An experimental interface to the FETI-DP method is available. FETI-DP operators could be created using PCBDDCCreateFETIDPOperators(). A stand-alone class for the FETI-DP method will be provided in the next releases. 22490f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 22500f202f7eSStefano Zampini 22510f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 22520f202f7eSStefano Zampini 22530f202f7eSStefano Zampini . -pc_bddc_use_vertices <true> - use or not vertices in primal space 22540f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 22550f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 22560f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 22570f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 22580f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 22590f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 226028509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 22610f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio <8> - number of subdomains which will be aggregated together at the coarser level (e.g. H/h ratio at the coarser level, significative only in the multilevel case) 22620f202f7eSStefano Zampini . -pc_bddc_redistribute <0> - size of a subset of processors where the coarse problem will be remapped (the value is ignored if not at the coarsest level) 22630f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 22640f202f7eSStefano Zampini . -pc_bddc_schur_layers <-1> - select the economic version of deluxe scaling by specifying the number of layers (-1 corresponds to the original deluxe scaling) 2265df4d28bfSStefano Zampini . -pc_bddc_adaptive_threshold <0.0> - when a value greater than one is specified, adaptive selection of constraints is performed on edges and faces (requires deluxe scaling and MUMPS or MKL_PARDISO installed) 226628509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 226728509bceSStefano Zampini 226828509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 226928509bceSStefano Zampini .vb 227028509bceSStefano Zampini -pc_bddc_dirichlet_ 227128509bceSStefano Zampini -pc_bddc_neumann_ 227228509bceSStefano Zampini -pc_bddc_coarse_ 227328509bceSStefano Zampini .ve 22740f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 227528509bceSStefano Zampini 22760f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 227728509bceSStefano Zampini .vb 2278312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2279312be037SStefano Zampini -pc_bddc_neumann_lN_ 2280312be037SStefano Zampini -pc_bddc_coarse_lN_ 228128509bceSStefano Zampini .ve 22820f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 22830f202f7eSStefano Zampini In order to specify options for the BDDC operators at the coarser levels (and not for the solvers), prepend -pc_bddc_coarse_ or -pc_bddc_coarse_l to the option, e.g. 22840f202f7eSStefano Zampini .vb 22850f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 22860f202f7eSStefano Zampini .ve 22870f202f7eSStefano Zampini will use a threshold of 5 for constraints' selection at the first coarse level and will redistribute the coarse problem of the first coarse level on 3 processors 2288da1bb401SStefano Zampini 2289da1bb401SStefano Zampini Level: intermediate 2290da1bb401SStefano Zampini 2291b6fdb6dfSStefano Zampini Developer notes: 2292da1bb401SStefano Zampini 2293da1bb401SStefano Zampini Contributed by Stefano Zampini 2294da1bb401SStefano Zampini 2295da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2296da1bb401SStefano Zampini M*/ 2297b2573a8aSBarry Smith 2298da1bb401SStefano Zampini #undef __FUNCT__ 2299da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 23008cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2301da1bb401SStefano Zampini { 2302da1bb401SStefano Zampini PetscErrorCode ierr; 2303da1bb401SStefano Zampini PC_BDDC *pcbddc; 2304da1bb401SStefano Zampini 2305da1bb401SStefano Zampini PetscFunctionBegin; 2306da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 2307b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2308da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2309da1bb401SStefano Zampini 2310da1bb401SStefano Zampini /* create PCIS data structure */ 2311da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2312da1bb401SStefano Zampini 231347d04d0dSStefano Zampini /* BDDC customization */ 231408a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 231547d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 231647d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 231747d04d0dSStefano Zampini pcbddc->use_faces = PETSC_FALSE; 231847d04d0dSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 231947d04d0dSStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 232047d04d0dSStefano Zampini pcbddc->switch_static = PETSC_FALSE; 2321fa434743SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 2322fa434743SStefano Zampini pcbddc->use_qr_single = PETSC_FALSE; 23233301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 232406a4e24aSStefano Zampini pcbddc->benign_saddle_point = PETSC_FALSE; 2325*14f95afaSStefano Zampini pcbddc->vertex_size = 1; 232647d04d0dSStefano Zampini pcbddc->dbg_flag = 0; 2327b9d89cd5SStefano Zampini /* private */ 2328727cdba6SStefano Zampini pcbddc->local_primal_size = 0; 23290e6343abSStefano Zampini pcbddc->local_primal_size_cc = 0; 23300e6343abSStefano Zampini pcbddc->local_primal_ref_node = 0; 23310e6343abSStefano Zampini pcbddc->local_primal_ref_mult = 0; 2332e9189074SStefano Zampini pcbddc->n_vertices = 0; 2333727cdba6SStefano Zampini pcbddc->primal_indices_local_idxs = 0; 2334fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 233568457ee5SStefano Zampini pcbddc->coarse_size = -1; 2336f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 2337727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 2338f4ddd8eeSStefano Zampini pcbddc->global_primal_indices = 0; 2339f4ddd8eeSStefano Zampini pcbddc->onearnullspace = 0; 2340f4ddd8eeSStefano Zampini pcbddc->onearnullvecs_state = 0; 2341674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 234230368db7SStefano Zampini pcbddc->user_primal_vertices_local = 0; 23430bdf917eSStefano Zampini pcbddc->NullSpace = 0; 23443972b0daSStefano Zampini pcbddc->temp_solution = 0; 2345534831adSStefano Zampini pcbddc->original_rhs = 0; 2346534831adSStefano Zampini pcbddc->local_mat = 0; 2347534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 2348b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = 0; 2349906d46d4SStefano Zampini pcbddc->new_global_mat = 0; 2350da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 2351da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 2352da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 2353da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 235415aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 235515aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 2356da1bb401SStefano Zampini pcbddc->vec1_P = 0; 2357da1bb401SStefano Zampini pcbddc->vec1_R = 0; 2358da1bb401SStefano Zampini pcbddc->vec2_R = 0; 2359da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 2360da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 2361da1bb401SStefano Zampini pcbddc->R_to_B = 0; 2362da1bb401SStefano Zampini pcbddc->R_to_D = 0; 2363da1bb401SStefano Zampini pcbddc->ksp_D = 0; 2364da1bb401SStefano Zampini pcbddc->ksp_R = 0; 2365da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 2366785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = 0; 2367785d1243SStefano Zampini pcbddc->DirichletBoundaries = 0; 2368785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = 0; 236960d44989SStefano Zampini pcbddc->user_provided_isfordofs = PETSC_FALSE; 237060d44989SStefano Zampini pcbddc->n_ISForDofs = 0; 237163602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 2372da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 237363602bcaSStefano Zampini pcbddc->ISForDofsLocal = 0; 2374da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 237585c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 237647d04d0dSStefano Zampini pcbddc->coarse_loc_to_glob = 0; 237747d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 2378b0c7d250SStefano Zampini pcbddc->coarse_adj_red = 0; 23794fad6a16SStefano Zampini pcbddc->current_level = 0; 23802b510759SStefano Zampini pcbddc->max_levels = 0; 2381323d395dSStefano Zampini pcbddc->use_coarse_estimates = PETSC_FALSE; 238274e2c79eSStefano Zampini pcbddc->redistribute_coarse = 0; 2383f3bde8b3SStefano Zampini pcbddc->coarse_subassembling = 0; 2384323d395dSStefano Zampini pcbddc->coarse_subassembling_init = 0; 23854f1b2e48SStefano Zampini pcbddc->detect_disconnected = PETSC_FALSE; 23864f1b2e48SStefano Zampini pcbddc->n_local_subs = 0; 23874f1b2e48SStefano Zampini pcbddc->local_subs = NULL; 238881d14e9dSStefano Zampini 238981d14e9dSStefano Zampini /* benign subspace trick */ 239081d14e9dSStefano Zampini pcbddc->benign_change = 0; 23910369aaf7SStefano Zampini pcbddc->benign_vec = 0; 23920369aaf7SStefano Zampini pcbddc->benign_original_mat = 0; 23930369aaf7SStefano Zampini pcbddc->benign_sf = 0; 23944f1b2e48SStefano Zampini pcbddc->benign_B0 = 0; 23954f1b2e48SStefano Zampini pcbddc->benign_n = 0; 23964f1b2e48SStefano Zampini pcbddc->benign_p0 = NULL; 23974f1b2e48SStefano Zampini pcbddc->benign_p0_lidx = NULL; 23984f1b2e48SStefano Zampini pcbddc->benign_p0_gidx = NULL; 2399b0f5fe93SStefano Zampini pcbddc->benign_null = PETSC_FALSE; 240081d14e9dSStefano Zampini 2401674ae819SStefano Zampini /* create local graph structure */ 2402674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 2403674ae819SStefano Zampini 2404674ae819SStefano Zampini /* scaling */ 2405674ae819SStefano Zampini pcbddc->work_scaling = 0; 240634a97f8cSStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 2407ac632422SStefano Zampini pcbddc->faster_deluxe = PETSC_FALSE; 2408b96c3477SStefano Zampini 2409b96c3477SStefano Zampini /* create sub schurs structure */ 2410b96c3477SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 2411b96c3477SStefano Zampini pcbddc->sub_schurs_rebuild = PETSC_FALSE; 2412b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 2413b96c3477SStefano Zampini pcbddc->sub_schurs_use_useradj = PETSC_FALSE; 2414b96c3477SStefano Zampini 2415b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_FALSE; 2416da1bb401SStefano Zampini 2417b7eb3628SStefano Zampini /* adaptivity */ 2418f6f667cfSStefano Zampini pcbddc->adaptive_threshold = 0.0; 241908122e43SStefano Zampini pcbddc->adaptive_nmax = 0; 2420f6f667cfSStefano Zampini pcbddc->adaptive_nmin = 0; 2421b7eb3628SStefano Zampini 2422da1bb401SStefano Zampini /* function pointers */ 2423da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 242493bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 2425da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 2426da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 2427da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 2428da1bb401SStefano Zampini pc->ops->view = 0; 2429da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 2430da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 2431da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 2432534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 2433534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 2434da1bb401SStefano Zampini 2435da1bb401SStefano Zampini /* composing function */ 2436906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 2437674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 243830368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 2439bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 24402b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 2441b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 24422b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 2443bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 2444bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 244582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2446bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 244782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2448bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 244982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2450bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 245182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2452bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 245363602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 2454bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 2455bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 2456bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 2457bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 2458da1bb401SStefano Zampini PetscFunctionReturn(0); 2459da1bb401SStefano Zampini } 24603425bc38SStefano Zampini 2461