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); 496661aa1dSStefano 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); 50ac632422SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_qr_single","Use QR factorization for single constraints on cc (QR is used when multiple constraints are present)","none",pcbddc->use_qr_single,&pcbddc->use_qr_single,NULL);CHKERRQ(ierr); 518eeda7d8SStefano Zampini /* Change of basis */ 52b9b85e73SStefano 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); 53b9b85e73SStefano 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); 54674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 55674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 56674ae819SStefano Zampini } 578eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 588eeda7d8SStefano 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); 5974e2c79eSStefano 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); 600298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 612b510759SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 62323d395dSStefano 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); 63674ae819SStefano 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); 64b96c3477SStefano 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); 65b96c3477SStefano 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); 66b96c3477SStefano 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); 67683d3df6SStefano 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); 68*bf3a8328SStefano 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); 69ac632422SStefano 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); 70*bf3a8328SStefano 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); 714c6709b3SStefano 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); 7208122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmin","Minimum number of constraints per connected components","none",pcbddc->adaptive_nmin,&pcbddc->adaptive_nmin,NULL);CHKERRQ(ierr); 7308122e43SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_adaptive_nmax","Maximum number of constraints per connected components","none",pcbddc->adaptive_nmax,&pcbddc->adaptive_nmax,NULL);CHKERRQ(ierr); 743301b35fSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_symmetric","Symmetric computation of primal basis functions","none",pcbddc->symmetric_primal,&pcbddc->symmetric_primal,NULL);CHKERRQ(ierr); 75b0c7d250SStefano 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); 7606a4e24aSStefano 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); 774f1b2e48SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_detect_disconnected","Detects disconnected subdomains","none",pcbddc->detect_disconnected,&pcbddc->detect_disconnected,NULL);CHKERRQ(ierr); 780c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 790c7d97c5SJed Brown PetscFunctionReturn(0); 800c7d97c5SJed Brown } 810c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 82674ae819SStefano Zampini #undef __FUNCT__ 83906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat_BDDC" 84906d46d4SStefano Zampini static PetscErrorCode PCBDDCSetChangeOfBasisMat_BDDC(PC pc, Mat change) 85b9b85e73SStefano Zampini { 86b9b85e73SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 87b9b85e73SStefano Zampini PetscErrorCode ierr; 88b9b85e73SStefano Zampini 89b9b85e73SStefano Zampini PetscFunctionBegin; 90b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 91b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)change);CHKERRQ(ierr); 92b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = change; 93b9b85e73SStefano Zampini PetscFunctionReturn(0); 94b9b85e73SStefano Zampini } 95b9b85e73SStefano Zampini #undef __FUNCT__ 96906d46d4SStefano Zampini #define __FUNCT__ "PCBDDCSetChangeOfBasisMat" 97b9b85e73SStefano Zampini /*@ 98906d46d4SStefano Zampini PCBDDCSetChangeOfBasisMat - Set user defined change of basis for dofs 99b9b85e73SStefano Zampini 100b9b85e73SStefano Zampini Collective on PC 101b9b85e73SStefano Zampini 102b9b85e73SStefano Zampini Input Parameters: 103b9b85e73SStefano Zampini + pc - the preconditioning context 104906d46d4SStefano Zampini - change - the change of basis matrix 105b9b85e73SStefano Zampini 106b9b85e73SStefano Zampini Level: intermediate 107b9b85e73SStefano Zampini 108b9b85e73SStefano Zampini Notes: 109b9b85e73SStefano Zampini 110b9b85e73SStefano Zampini .seealso: PCBDDC 111b9b85e73SStefano Zampini @*/ 112906d46d4SStefano Zampini PetscErrorCode PCBDDCSetChangeOfBasisMat(PC pc, Mat change) 113b9b85e73SStefano Zampini { 114b9b85e73SStefano Zampini PetscErrorCode ierr; 115b9b85e73SStefano Zampini 116b9b85e73SStefano Zampini PetscFunctionBegin; 117b9b85e73SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 118b9b85e73SStefano Zampini PetscValidHeaderSpecific(change,MAT_CLASSID,2); 119906d46d4SStefano Zampini PetscCheckSameComm(pc,1,change,2); 120906d46d4SStefano Zampini if (pc->mat) { 121906d46d4SStefano Zampini PetscInt rows_c,cols_c,rows,cols; 122906d46d4SStefano Zampini ierr = MatGetSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 123906d46d4SStefano Zampini ierr = MatGetSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 124906d46d4SStefano Zampini if (rows_c != rows) { 125906d46d4SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of rows for change of basis matrix! %d != %d",rows_c,rows); 126906d46d4SStefano Zampini } 127906d46d4SStefano Zampini if (cols_c != cols) { 128906d46d4SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of columns for change of basis matrix! %d != %d",cols_c,cols); 129906d46d4SStefano Zampini } 130906d46d4SStefano Zampini ierr = MatGetLocalSize(pc->mat,&rows,&cols);CHKERRQ(ierr); 131906d46d4SStefano Zampini ierr = MatGetLocalSize(change,&rows_c,&cols_c);CHKERRQ(ierr); 132906d46d4SStefano Zampini if (rows_c != rows) { 133906d46d4SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local rows for change of basis matrix! %d != %d",rows_c,rows); 134906d46d4SStefano Zampini } 135906d46d4SStefano Zampini if (cols_c != cols) { 136906d46d4SStefano Zampini SETERRQ2(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Invalid number of local columns for change of basis matrix! %d != %d",cols_c,cols); 137906d46d4SStefano Zampini } 138906d46d4SStefano Zampini } 139906d46d4SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetChangeOfBasisMat_C",(PC,Mat),(pc,change));CHKERRQ(ierr); 140b9b85e73SStefano Zampini PetscFunctionReturn(0); 141b9b85e73SStefano Zampini } 142b9b85e73SStefano Zampini /* -------------------------------------------------------------------------- */ 143b9b85e73SStefano Zampini #undef __FUNCT__ 14430368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS_BDDC" 14530368db7SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesIS_BDDC(PC pc, IS PrimalVertices) 14630368db7SStefano Zampini { 14730368db7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 14830368db7SStefano Zampini PetscErrorCode ierr; 14930368db7SStefano Zampini 15030368db7SStefano Zampini PetscFunctionBegin; 15130368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 15230368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 15330368db7SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 15430368db7SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 15530368db7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 15630368db7SStefano Zampini PetscFunctionReturn(0); 15730368db7SStefano Zampini } 15830368db7SStefano Zampini #undef __FUNCT__ 15930368db7SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesIS" 16030368db7SStefano Zampini /*@ 16130368db7SStefano Zampini PCBDDCSetPrimalVerticesIS - Set additional user defined primal vertices in PCBDDC 16230368db7SStefano Zampini 16330368db7SStefano Zampini Collective 16430368db7SStefano Zampini 16530368db7SStefano Zampini Input Parameters: 16630368db7SStefano Zampini + pc - the preconditioning context 16730368db7SStefano Zampini - PrimalVertices - index set of primal vertices in global numbering (can be empty) 16830368db7SStefano Zampini 16930368db7SStefano Zampini Level: intermediate 17030368db7SStefano Zampini 17130368db7SStefano Zampini Notes: 17230368db7SStefano Zampini Any process can list any global node 17330368db7SStefano Zampini 17430368db7SStefano Zampini .seealso: PCBDDC 17530368db7SStefano Zampini @*/ 17630368db7SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesIS(PC pc, IS PrimalVertices) 17730368db7SStefano Zampini { 17830368db7SStefano Zampini PetscErrorCode ierr; 17930368db7SStefano Zampini 18030368db7SStefano Zampini PetscFunctionBegin; 18130368db7SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 18230368db7SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 18330368db7SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 18430368db7SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 18530368db7SStefano Zampini PetscFunctionReturn(0); 18630368db7SStefano Zampini } 18730368db7SStefano Zampini /* -------------------------------------------------------------------------- */ 18830368db7SStefano Zampini #undef __FUNCT__ 189674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 190674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 191674ae819SStefano Zampini { 192674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 193674ae819SStefano Zampini PetscErrorCode ierr; 1941e6b0712SBarry Smith 195674ae819SStefano Zampini PetscFunctionBegin; 196674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 19730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 198674ae819SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 19930368db7SStefano Zampini pcbddc->user_primal_vertices_local = PrimalVertices; 20030368db7SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 201674ae819SStefano Zampini PetscFunctionReturn(0); 202674ae819SStefano Zampini } 203674ae819SStefano Zampini #undef __FUNCT__ 204674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 205674ae819SStefano Zampini /*@ 20628509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 207674ae819SStefano Zampini 20817eb1463SStefano Zampini Collective 209674ae819SStefano Zampini 210674ae819SStefano Zampini Input Parameters: 211674ae819SStefano Zampini + pc - the preconditioning context 21217eb1463SStefano Zampini - PrimalVertices - index set of primal vertices in local numbering (can be empty) 213674ae819SStefano Zampini 214674ae819SStefano Zampini Level: intermediate 215674ae819SStefano Zampini 216674ae819SStefano Zampini Notes: 217674ae819SStefano Zampini 218674ae819SStefano Zampini .seealso: PCBDDC 219674ae819SStefano Zampini @*/ 220674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 221674ae819SStefano Zampini { 222674ae819SStefano Zampini PetscErrorCode ierr; 223674ae819SStefano Zampini 224674ae819SStefano Zampini PetscFunctionBegin; 225674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 226674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 22717eb1463SStefano Zampini PetscCheckSameComm(pc,1,PrimalVertices,2); 228674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 229674ae819SStefano Zampini PetscFunctionReturn(0); 230674ae819SStefano Zampini } 231674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 2320c7d97c5SJed Brown #undef __FUNCT__ 2334fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 2344fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 2354fad6a16SStefano Zampini { 2364fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2374fad6a16SStefano Zampini 2384fad6a16SStefano Zampini PetscFunctionBegin; 2394fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 2404fad6a16SStefano Zampini PetscFunctionReturn(0); 2414fad6a16SStefano Zampini } 2421e6b0712SBarry Smith 2434fad6a16SStefano Zampini #undef __FUNCT__ 2444fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 2454fad6a16SStefano Zampini /*@ 24628509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 2474fad6a16SStefano Zampini 2484fad6a16SStefano Zampini Logically collective on PC 2494fad6a16SStefano Zampini 2504fad6a16SStefano Zampini Input Parameters: 2514fad6a16SStefano Zampini + pc - the preconditioning context 25228509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 2534fad6a16SStefano Zampini 2540f202f7eSStefano Zampini Options Database Keys: 2550f202f7eSStefano Zampini . -pc_bddc_coarsening_ratio 2564fad6a16SStefano Zampini 2574fad6a16SStefano Zampini Level: intermediate 2584fad6a16SStefano Zampini 2594fad6a16SStefano Zampini Notes: 2600f202f7eSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 2614fad6a16SStefano Zampini 2620f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetLevels() 2634fad6a16SStefano Zampini @*/ 2644fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 2654fad6a16SStefano Zampini { 2664fad6a16SStefano Zampini PetscErrorCode ierr; 2674fad6a16SStefano Zampini 2684fad6a16SStefano Zampini PetscFunctionBegin; 2694fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2702b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 2714fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 2724fad6a16SStefano Zampini PetscFunctionReturn(0); 2734fad6a16SStefano Zampini } 2742b510759SStefano Zampini 275b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 2762b510759SStefano Zampini #undef __FUNCT__ 277b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet_BDDC" 278b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 279b8ffe317SStefano Zampini { 280b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 281b8ffe317SStefano Zampini 282b8ffe317SStefano Zampini PetscFunctionBegin; 28385c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 284b8ffe317SStefano Zampini PetscFunctionReturn(0); 285b8ffe317SStefano Zampini } 286b8ffe317SStefano Zampini 287b8ffe317SStefano Zampini #undef __FUNCT__ 288b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet" 289b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 2902b510759SStefano Zampini { 2912b510759SStefano Zampini PetscErrorCode ierr; 2922b510759SStefano Zampini 2932b510759SStefano Zampini PetscFunctionBegin; 2942b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 295b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 296b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 2972b510759SStefano Zampini PetscFunctionReturn(0); 2982b510759SStefano Zampini } 2991e6b0712SBarry Smith 3004fad6a16SStefano Zampini #undef __FUNCT__ 3012b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel_BDDC" 3022b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 3034fad6a16SStefano Zampini { 3044fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3054fad6a16SStefano Zampini 3064fad6a16SStefano Zampini PetscFunctionBegin; 3072b510759SStefano Zampini pcbddc->current_level = level; 3084fad6a16SStefano Zampini PetscFunctionReturn(0); 3094fad6a16SStefano Zampini } 3101e6b0712SBarry Smith 3114fad6a16SStefano Zampini #undef __FUNCT__ 312b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 313b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 314b8ffe317SStefano Zampini { 315b8ffe317SStefano Zampini PetscErrorCode ierr; 316b8ffe317SStefano Zampini 317b8ffe317SStefano Zampini PetscFunctionBegin; 318b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 319b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 320b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 321b8ffe317SStefano Zampini PetscFunctionReturn(0); 322b8ffe317SStefano Zampini } 323b8ffe317SStefano Zampini 324b8ffe317SStefano Zampini #undef __FUNCT__ 3252b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels_BDDC" 3262b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 3272b510759SStefano Zampini { 3282b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3292b510759SStefano Zampini 3302b510759SStefano Zampini PetscFunctionBegin; 3312b510759SStefano Zampini pcbddc->max_levels = levels; 3322b510759SStefano Zampini PetscFunctionReturn(0); 3332b510759SStefano Zampini } 3342b510759SStefano Zampini 3352b510759SStefano Zampini #undef __FUNCT__ 3362b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels" 3374fad6a16SStefano Zampini /*@ 33828509bceSStefano Zampini PCBDDCSetLevels - Sets the maximum number of levels for multilevel 3394fad6a16SStefano Zampini 3404fad6a16SStefano Zampini Logically collective on PC 3414fad6a16SStefano Zampini 3424fad6a16SStefano Zampini Input Parameters: 3434fad6a16SStefano Zampini + pc - the preconditioning context 34428509bceSStefano Zampini - levels - the maximum number of levels (max 9) 3454fad6a16SStefano Zampini 3460f202f7eSStefano Zampini Options Database Keys: 3470f202f7eSStefano Zampini . -pc_bddc_levels 3484fad6a16SStefano Zampini 3494fad6a16SStefano Zampini Level: intermediate 3504fad6a16SStefano Zampini 3514fad6a16SStefano Zampini Notes: 3520f202f7eSStefano Zampini Default value is 0, i.e. traditional one-level BDDC 3534fad6a16SStefano Zampini 3540f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetCoarseningRatio() 3554fad6a16SStefano Zampini @*/ 3562b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 3574fad6a16SStefano Zampini { 3584fad6a16SStefano Zampini PetscErrorCode ierr; 3594fad6a16SStefano Zampini 3604fad6a16SStefano Zampini PetscFunctionBegin; 3614fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 3622b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 363312be037SStefano Zampini if (levels > 99) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Maximum number of levels for bddc is 99\n"); 3642b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 3654fad6a16SStefano Zampini PetscFunctionReturn(0); 3664fad6a16SStefano Zampini } 3674fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 3681e6b0712SBarry Smith 3694fad6a16SStefano Zampini #undef __FUNCT__ 3700bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 3710bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 3720bdf917eSStefano Zampini { 3730bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3740bdf917eSStefano Zampini PetscErrorCode ierr; 3750bdf917eSStefano Zampini 3760bdf917eSStefano Zampini PetscFunctionBegin; 3770bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 3780bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 3790bdf917eSStefano Zampini pcbddc->NullSpace = NullSpace; 3800bdf917eSStefano Zampini PetscFunctionReturn(0); 3810bdf917eSStefano Zampini } 3821e6b0712SBarry Smith 3830bdf917eSStefano Zampini #undef __FUNCT__ 3840bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 3850bdf917eSStefano Zampini /*@ 38628509bceSStefano Zampini PCBDDCSetNullSpace - Set nullspace for BDDC operator 3870bdf917eSStefano Zampini 3880bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 3890bdf917eSStefano Zampini 3900bdf917eSStefano Zampini Input Parameters: 3910bdf917eSStefano Zampini + pc - the preconditioning context 39228509bceSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned (Pmat) 3930bdf917eSStefano Zampini 3940bdf917eSStefano Zampini Level: intermediate 3950bdf917eSStefano Zampini 3960bdf917eSStefano Zampini Notes: 3970bdf917eSStefano Zampini 3980bdf917eSStefano Zampini .seealso: PCBDDC 3990bdf917eSStefano Zampini @*/ 4000bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 4010bdf917eSStefano Zampini { 4020bdf917eSStefano Zampini PetscErrorCode ierr; 4030bdf917eSStefano Zampini 4040bdf917eSStefano Zampini PetscFunctionBegin; 4050bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 406674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 4072b510759SStefano Zampini PetscCheckSameComm(pc,1,NullSpace,2); 4080bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 4090bdf917eSStefano Zampini PetscFunctionReturn(0); 4100bdf917eSStefano Zampini } 4110bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 4121e6b0712SBarry Smith 4130bdf917eSStefano Zampini #undef __FUNCT__ 4143b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 4153b03a366Sstefano_zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 4163b03a366Sstefano_zampini { 4173b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4183b03a366Sstefano_zampini PetscErrorCode ierr; 4193b03a366Sstefano_zampini 4203b03a366Sstefano_zampini PetscFunctionBegin; 421785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 422785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 4233b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 42436e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 42536e030ebSStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 426fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 4273b03a366Sstefano_zampini PetscFunctionReturn(0); 4283b03a366Sstefano_zampini } 4291e6b0712SBarry Smith 4303b03a366Sstefano_zampini #undef __FUNCT__ 4313b03a366Sstefano_zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 4323b03a366Sstefano_zampini /*@ 43328509bceSStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 4343b03a366Sstefano_zampini 435785d1243SStefano Zampini Collective 4363b03a366Sstefano_zampini 4373b03a366Sstefano_zampini Input Parameters: 4383b03a366Sstefano_zampini + pc - the preconditioning context 439785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 4403b03a366Sstefano_zampini 4413b03a366Sstefano_zampini Level: intermediate 4423b03a366Sstefano_zampini 4430f202f7eSStefano Zampini Notes: 4440f202f7eSStefano Zampini Provide the information if you used MatZeroRows/Columns routines. Any process can list any global node 4453b03a366Sstefano_zampini 4460f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundariesLocal(), MatZeroRows(), MatZeroRowsColumns() 4473b03a366Sstefano_zampini @*/ 4483b03a366Sstefano_zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 4493b03a366Sstefano_zampini { 4503b03a366Sstefano_zampini PetscErrorCode ierr; 4513b03a366Sstefano_zampini 4523b03a366Sstefano_zampini PetscFunctionBegin; 4533b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 454674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 455785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 4563b03a366Sstefano_zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 4573b03a366Sstefano_zampini PetscFunctionReturn(0); 4583b03a366Sstefano_zampini } 4593b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 4601e6b0712SBarry Smith 4613b03a366Sstefano_zampini #undef __FUNCT__ 46282ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal_BDDC" 46382ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 4640c7d97c5SJed Brown { 4650c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4660c7d97c5SJed Brown PetscErrorCode ierr; 4670c7d97c5SJed Brown 4680c7d97c5SJed Brown PetscFunctionBegin; 469785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 470785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 4710c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 4720c7d97c5SJed Brown ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 473785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 4747d24d155SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 4750c7d97c5SJed Brown PetscFunctionReturn(0); 4760c7d97c5SJed Brown } 4770c7d97c5SJed Brown 4780c7d97c5SJed Brown #undef __FUNCT__ 47982ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal" 4809c0446d6SStefano Zampini /*@ 48182ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 4829c0446d6SStefano Zampini 483785d1243SStefano Zampini Collective 48453cdbc3dSStefano Zampini 48553cdbc3dSStefano Zampini Input Parameters: 48653cdbc3dSStefano Zampini + pc - the preconditioning context 48782ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 48853cdbc3dSStefano Zampini 48953cdbc3dSStefano Zampini Level: intermediate 49053cdbc3dSStefano Zampini 4919c0446d6SStefano Zampini Notes: 49253cdbc3dSStefano Zampini 4930f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetDirichletBoundaries(), MatZeroRows(), MatZeroRowsColumns() 49453cdbc3dSStefano Zampini @*/ 49582ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 4960c7d97c5SJed Brown { 4970c7d97c5SJed Brown PetscErrorCode ierr; 4980c7d97c5SJed Brown 4990c7d97c5SJed Brown PetscFunctionBegin; 5000c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5010c7d97c5SJed Brown PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 50282ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 50382ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 5040c7d97c5SJed Brown PetscFunctionReturn(0); 5050c7d97c5SJed Brown } 5060c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5070c7d97c5SJed Brown 5080c7d97c5SJed Brown #undef __FUNCT__ 5090c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 51053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 5110c7d97c5SJed Brown { 5120c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 51353cdbc3dSStefano Zampini PetscErrorCode ierr; 5140c7d97c5SJed Brown 5150c7d97c5SJed Brown PetscFunctionBegin; 516785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 517785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 51853cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 51936e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 52036e030ebSStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 521fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 5220c7d97c5SJed Brown PetscFunctionReturn(0); 5230c7d97c5SJed Brown } 5241e6b0712SBarry Smith 5250c7d97c5SJed Brown #undef __FUNCT__ 5260c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 52757527edcSJed Brown /*@ 52828509bceSStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 52957527edcSJed Brown 530785d1243SStefano Zampini Collective 53157527edcSJed Brown 53257527edcSJed Brown Input Parameters: 53357527edcSJed Brown + pc - the preconditioning context 534785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 53557527edcSJed Brown 53657527edcSJed Brown Level: intermediate 53757527edcSJed Brown 5380f202f7eSStefano Zampini Notes: 5390f202f7eSStefano Zampini Any process can list any global node 54057527edcSJed Brown 5410f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundariesLocal() 54257527edcSJed Brown @*/ 54353cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 5440c7d97c5SJed Brown { 5450c7d97c5SJed Brown PetscErrorCode ierr; 5460c7d97c5SJed Brown 5470c7d97c5SJed Brown PetscFunctionBegin; 5480c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 549674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 550785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 55153cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 55253cdbc3dSStefano Zampini PetscFunctionReturn(0); 55353cdbc3dSStefano Zampini } 55453cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 5551e6b0712SBarry Smith 55653cdbc3dSStefano Zampini #undef __FUNCT__ 55782ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal_BDDC" 55882ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 5590c7d97c5SJed Brown { 5600c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5610c7d97c5SJed Brown PetscErrorCode ierr; 5620c7d97c5SJed Brown 5630c7d97c5SJed Brown PetscFunctionBegin; 564785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 565785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 5660c7d97c5SJed Brown ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 5670c7d97c5SJed Brown ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 568785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 5697d24d155SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 5700c7d97c5SJed Brown PetscFunctionReturn(0); 5710c7d97c5SJed Brown } 5720c7d97c5SJed Brown 5730c7d97c5SJed Brown #undef __FUNCT__ 57482ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal" 5750c7d97c5SJed Brown /*@ 57682ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 5770c7d97c5SJed Brown 578785d1243SStefano Zampini Collective 5790c7d97c5SJed Brown 5800c7d97c5SJed Brown Input Parameters: 5810c7d97c5SJed Brown + pc - the preconditioning context 58282ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 5830c7d97c5SJed Brown 5840c7d97c5SJed Brown Level: intermediate 5850c7d97c5SJed Brown 5860c7d97c5SJed Brown Notes: 5870c7d97c5SJed Brown 5880f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCSetNeumannBoundaries() 5890c7d97c5SJed Brown @*/ 59082ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 5910c7d97c5SJed Brown { 5920c7d97c5SJed Brown PetscErrorCode ierr; 5930c7d97c5SJed Brown 5940c7d97c5SJed Brown PetscFunctionBegin; 5950c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 5960c7d97c5SJed Brown PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 59782ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 59882ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 59953cdbc3dSStefano Zampini PetscFunctionReturn(0); 60053cdbc3dSStefano Zampini } 60153cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 60253cdbc3dSStefano Zampini 60353cdbc3dSStefano Zampini #undef __FUNCT__ 604da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 605da1bb401SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 606da1bb401SStefano Zampini { 607da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 608da1bb401SStefano Zampini 609da1bb401SStefano Zampini PetscFunctionBegin; 610da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 611da1bb401SStefano Zampini PetscFunctionReturn(0); 612da1bb401SStefano Zampini } 6131e6b0712SBarry Smith 614da1bb401SStefano Zampini #undef __FUNCT__ 615da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 616da1bb401SStefano Zampini /*@ 617785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 618da1bb401SStefano Zampini 619785d1243SStefano Zampini Collective 620785d1243SStefano Zampini 621785d1243SStefano Zampini Input Parameters: 622785d1243SStefano Zampini . pc - the preconditioning context 623785d1243SStefano Zampini 624785d1243SStefano Zampini Output Parameters: 625785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 626785d1243SStefano Zampini 627785d1243SStefano Zampini Level: intermediate 628785d1243SStefano Zampini 6290f202f7eSStefano Zampini Notes: 6300f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 631785d1243SStefano Zampini 632785d1243SStefano Zampini .seealso: PCBDDC 633785d1243SStefano Zampini @*/ 634785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 635785d1243SStefano Zampini { 636785d1243SStefano Zampini PetscErrorCode ierr; 637785d1243SStefano Zampini 638785d1243SStefano Zampini PetscFunctionBegin; 639785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 640785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 641785d1243SStefano Zampini PetscFunctionReturn(0); 642785d1243SStefano Zampini } 643785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 644785d1243SStefano Zampini 645785d1243SStefano Zampini #undef __FUNCT__ 646785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal_BDDC" 647785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 648785d1243SStefano Zampini { 649785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 650785d1243SStefano Zampini 651785d1243SStefano Zampini PetscFunctionBegin; 652785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 653785d1243SStefano Zampini PetscFunctionReturn(0); 654785d1243SStefano Zampini } 655785d1243SStefano Zampini 656785d1243SStefano Zampini #undef __FUNCT__ 65782ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal" 658da1bb401SStefano Zampini /*@ 65982ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 660da1bb401SStefano Zampini 661785d1243SStefano Zampini Collective 662da1bb401SStefano Zampini 663da1bb401SStefano Zampini Input Parameters: 66428509bceSStefano Zampini . pc - the preconditioning context 665da1bb401SStefano Zampini 666da1bb401SStefano Zampini Output Parameters: 66728509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 668da1bb401SStefano Zampini 669da1bb401SStefano Zampini Level: intermediate 670da1bb401SStefano Zampini 671da1bb401SStefano Zampini Notes: 6720f202f7eSStefano 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). 6730f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 674da1bb401SStefano Zampini 675da1bb401SStefano Zampini .seealso: PCBDDC 676da1bb401SStefano Zampini @*/ 67782ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 678da1bb401SStefano Zampini { 679da1bb401SStefano Zampini PetscErrorCode ierr; 680da1bb401SStefano Zampini 681da1bb401SStefano Zampini PetscFunctionBegin; 682da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 68382ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 684da1bb401SStefano Zampini PetscFunctionReturn(0); 685da1bb401SStefano Zampini } 686da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 6871e6b0712SBarry Smith 688da1bb401SStefano Zampini #undef __FUNCT__ 68953cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 69053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 69153cdbc3dSStefano Zampini { 69253cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 69353cdbc3dSStefano Zampini 69453cdbc3dSStefano Zampini PetscFunctionBegin; 69553cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 69653cdbc3dSStefano Zampini PetscFunctionReturn(0); 69753cdbc3dSStefano Zampini } 6981e6b0712SBarry Smith 69953cdbc3dSStefano Zampini #undef __FUNCT__ 70053cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 70153cdbc3dSStefano Zampini /*@ 702785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 70353cdbc3dSStefano Zampini 704785d1243SStefano Zampini Collective 705785d1243SStefano Zampini 706785d1243SStefano Zampini Input Parameters: 707785d1243SStefano Zampini . pc - the preconditioning context 708785d1243SStefano Zampini 709785d1243SStefano Zampini Output Parameters: 710785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 711785d1243SStefano Zampini 712785d1243SStefano Zampini Level: intermediate 713785d1243SStefano Zampini 7140f202f7eSStefano Zampini Notes: 7150f202f7eSStefano Zampini The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 716785d1243SStefano Zampini 717785d1243SStefano Zampini .seealso: PCBDDC 718785d1243SStefano Zampini @*/ 719785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 720785d1243SStefano Zampini { 721785d1243SStefano Zampini PetscErrorCode ierr; 722785d1243SStefano Zampini 723785d1243SStefano Zampini PetscFunctionBegin; 724785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 725785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 726785d1243SStefano Zampini PetscFunctionReturn(0); 727785d1243SStefano Zampini } 728785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 729785d1243SStefano Zampini 730785d1243SStefano Zampini #undef __FUNCT__ 731785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal_BDDC" 732785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 733785d1243SStefano Zampini { 734785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 735785d1243SStefano Zampini 736785d1243SStefano Zampini PetscFunctionBegin; 737785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 738785d1243SStefano Zampini PetscFunctionReturn(0); 739785d1243SStefano Zampini } 740785d1243SStefano Zampini 741785d1243SStefano Zampini #undef __FUNCT__ 74282ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal" 74353cdbc3dSStefano Zampini /*@ 74482ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 74553cdbc3dSStefano Zampini 746785d1243SStefano Zampini Collective 74753cdbc3dSStefano Zampini 74853cdbc3dSStefano Zampini Input Parameters: 74928509bceSStefano Zampini . pc - the preconditioning context 75053cdbc3dSStefano Zampini 75153cdbc3dSStefano Zampini Output Parameters: 75228509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 75353cdbc3dSStefano Zampini 75453cdbc3dSStefano Zampini Level: intermediate 75553cdbc3dSStefano Zampini 75653cdbc3dSStefano Zampini Notes: 7570f202f7eSStefano 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). 7580f202f7eSStefano Zampini In the latter case, the IS will be available after PCSetUp. 75953cdbc3dSStefano Zampini 76053cdbc3dSStefano Zampini .seealso: PCBDDC 76153cdbc3dSStefano Zampini @*/ 76282ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 76353cdbc3dSStefano Zampini { 76453cdbc3dSStefano Zampini PetscErrorCode ierr; 76553cdbc3dSStefano Zampini 76653cdbc3dSStefano Zampini PetscFunctionBegin; 76753cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 76882ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 7690c7d97c5SJed Brown PetscFunctionReturn(0); 7700c7d97c5SJed Brown } 77136e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 7721e6b0712SBarry Smith 77336e030ebSStefano Zampini #undef __FUNCT__ 774da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 7751a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 77636e030ebSStefano Zampini { 77736e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 778da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 779da1bb401SStefano Zampini PetscErrorCode ierr; 78036e030ebSStefano Zampini 78136e030ebSStefano Zampini PetscFunctionBegin; 782674ae819SStefano Zampini /* free old CSR */ 783674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 784fb223d50SStefano Zampini /* TODO: PCBDDCGraphSetAdjacency */ 785674ae819SStefano Zampini /* get CSR into graph structure */ 786da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 787854ce69bSBarry Smith ierr = PetscMalloc1(nvtxs+1,&mat_graph->xadj);CHKERRQ(ierr); 788785e854fSJed Brown ierr = PetscMalloc1(xadj[nvtxs],&mat_graph->adjncy);CHKERRQ(ierr); 789674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 790674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 791da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 7921a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 7931a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 794674ae819SStefano Zampini } 795575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 79636e030ebSStefano Zampini PetscFunctionReturn(0); 79736e030ebSStefano Zampini } 7981e6b0712SBarry Smith 79936e030ebSStefano Zampini #undef __FUNCT__ 800da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 80136e030ebSStefano Zampini /*@ 8020f202f7eSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local matrix 80336e030ebSStefano Zampini 80436e030ebSStefano Zampini Not collective 80536e030ebSStefano Zampini 80636e030ebSStefano Zampini Input Parameters: 80736e030ebSStefano Zampini + pc - the preconditioning context 8080f202f7eSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the size of the local problem) 80928509bceSStefano Zampini . xadj, adjncy - the CSR graph 81028509bceSStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. 81136e030ebSStefano Zampini 81236e030ebSStefano Zampini Level: intermediate 81336e030ebSStefano Zampini 81436e030ebSStefano Zampini Notes: 81536e030ebSStefano Zampini 81628509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 81736e030ebSStefano Zampini @*/ 8181a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 81936e030ebSStefano Zampini { 820575ad6abSStefano Zampini void (*f)(void) = 0; 82136e030ebSStefano Zampini PetscErrorCode ierr; 82236e030ebSStefano Zampini 82336e030ebSStefano Zampini PetscFunctionBegin; 82436e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 825674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 826d7de1dd9SStefano Zampini PetscValidIntPointer(adjncy,4); 827674ae819SStefano Zampini if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) { 828674ae819SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 829da1bb401SStefano Zampini } 83036e030ebSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 831575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 832575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 833575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 834575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 835575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 83636e030ebSStefano Zampini } 83736e030ebSStefano Zampini PetscFunctionReturn(0); 83836e030ebSStefano Zampini } 8399c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 8401e6b0712SBarry Smith 8419c0446d6SStefano Zampini #undef __FUNCT__ 84263602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal_BDDC" 84363602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 84463602bcaSStefano Zampini { 84563602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 84663602bcaSStefano Zampini PetscInt i; 84763602bcaSStefano Zampini PetscErrorCode ierr; 84863602bcaSStefano Zampini 84963602bcaSStefano Zampini PetscFunctionBegin; 85063602bcaSStefano Zampini /* Destroy ISes if they were already set */ 85163602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 85263602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 85363602bcaSStefano Zampini } 85463602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 85563602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 85663602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 85763602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 85863602bcaSStefano Zampini } 85963602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 86063602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 86163602bcaSStefano Zampini /* allocate space then set */ 862d02579f5SStefano Zampini if (n_is) { 863d02579f5SStefano Zampini ierr = PetscMalloc1(n_is,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 864d02579f5SStefano Zampini } 86563602bcaSStefano Zampini for (i=0;i<n_is;i++) { 86663602bcaSStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 86763602bcaSStefano Zampini pcbddc->ISForDofsLocal[i]=ISForDofs[i]; 86863602bcaSStefano Zampini } 86963602bcaSStefano Zampini pcbddc->n_ISForDofsLocal=n_is; 87063602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 8711a8a16d1SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 87263602bcaSStefano Zampini PetscFunctionReturn(0); 87363602bcaSStefano Zampini } 87463602bcaSStefano Zampini 87563602bcaSStefano Zampini #undef __FUNCT__ 87663602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal" 87763602bcaSStefano Zampini /*@ 87863602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 87963602bcaSStefano Zampini 88063602bcaSStefano Zampini Collective 88163602bcaSStefano Zampini 88263602bcaSStefano Zampini Input Parameters: 88363602bcaSStefano Zampini + pc - the preconditioning context 8840f202f7eSStefano Zampini . n_is - number of index sets defining the fields 8850f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in local ordering 88663602bcaSStefano Zampini 88763602bcaSStefano Zampini Level: intermediate 88863602bcaSStefano Zampini 8890f202f7eSStefano Zampini Notes: 8900f202f7eSStefano Zampini n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 89163602bcaSStefano Zampini 89263602bcaSStefano Zampini .seealso: PCBDDC 89363602bcaSStefano Zampini @*/ 89463602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 89563602bcaSStefano Zampini { 89663602bcaSStefano Zampini PetscInt i; 89763602bcaSStefano Zampini PetscErrorCode ierr; 89863602bcaSStefano Zampini 89963602bcaSStefano Zampini PetscFunctionBegin; 90063602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 90163602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 90263602bcaSStefano Zampini for (i=0;i<n_is;i++) { 90363602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 90463602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 90563602bcaSStefano Zampini } 906e71e7a71SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplittingLocal_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 90763602bcaSStefano Zampini PetscFunctionReturn(0); 90863602bcaSStefano Zampini } 90963602bcaSStefano Zampini /* -------------------------------------------------------------------------- */ 91063602bcaSStefano Zampini 91163602bcaSStefano Zampini #undef __FUNCT__ 9129c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 9139c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 9149c0446d6SStefano Zampini { 9159c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 9169c0446d6SStefano Zampini PetscInt i; 9179c0446d6SStefano Zampini PetscErrorCode ierr; 9189c0446d6SStefano Zampini 9199c0446d6SStefano Zampini PetscFunctionBegin; 920da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 9219c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 9229c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 9239c0446d6SStefano Zampini } 924d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 92563602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 92663602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 92763602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 92863602bcaSStefano Zampini } 92963602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 93063602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 931da1bb401SStefano Zampini /* allocate space then set */ 932d02579f5SStefano Zampini if (n_is) { 933785e854fSJed Brown ierr = PetscMalloc1(n_is,&pcbddc->ISForDofs);CHKERRQ(ierr); 934d02579f5SStefano Zampini } 9359c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 936da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 937da1bb401SStefano Zampini pcbddc->ISForDofs[i]=ISForDofs[i]; 9389c0446d6SStefano Zampini } 9399c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 94063602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 9411a8a16d1SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 9429c0446d6SStefano Zampini PetscFunctionReturn(0); 9439c0446d6SStefano Zampini } 9441e6b0712SBarry Smith 9459c0446d6SStefano Zampini #undef __FUNCT__ 9469c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 9479c0446d6SStefano Zampini /*@ 94863602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 9499c0446d6SStefano Zampini 95063602bcaSStefano Zampini Collective 9519c0446d6SStefano Zampini 9529c0446d6SStefano Zampini Input Parameters: 9539c0446d6SStefano Zampini + pc - the preconditioning context 9540f202f7eSStefano Zampini . n_is - number of index sets defining the fields 9550f202f7eSStefano Zampini - ISForDofs - array of IS describing the fields in global ordering 9569c0446d6SStefano Zampini 9579c0446d6SStefano Zampini Level: intermediate 9589c0446d6SStefano Zampini 9590f202f7eSStefano Zampini Notes: 9600f202f7eSStefano Zampini Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to the complement field. 9619c0446d6SStefano Zampini 9629c0446d6SStefano Zampini .seealso: PCBDDC 9639c0446d6SStefano Zampini @*/ 9649c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 9659c0446d6SStefano Zampini { 9662b510759SStefano Zampini PetscInt i; 9679c0446d6SStefano Zampini PetscErrorCode ierr; 9689c0446d6SStefano Zampini 9699c0446d6SStefano Zampini PetscFunctionBegin; 9709c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 97163602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 9722b510759SStefano Zampini for (i=0;i<n_is;i++) { 97363602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 97463602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 9752b510759SStefano Zampini } 9769c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 9779c0446d6SStefano Zampini PetscFunctionReturn(0); 9789c0446d6SStefano Zampini } 979906d46d4SStefano Zampini 980da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 981534831adSStefano Zampini #undef __FUNCT__ 982534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 983534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 984534831adSStefano Zampini /* 985534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 986534831adSStefano Zampini guess if a transformation of basis approach has been selected. 9879c0446d6SStefano Zampini 988534831adSStefano Zampini Input Parameter: 989534831adSStefano Zampini + pc - the preconditioner contex 990534831adSStefano Zampini 991534831adSStefano Zampini Application Interface Routine: PCPreSolve() 992534831adSStefano Zampini 993534831adSStefano Zampini Notes: 994534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 995534831adSStefano Zampini the user, but instead is called by KSPSolve(). 996534831adSStefano Zampini */ 997534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 998534831adSStefano Zampini { 999534831adSStefano Zampini PetscErrorCode ierr; 1000534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1001534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 10023972b0daSStefano Zampini Vec used_vec; 10038d00608fSStefano Zampini PetscBool copy_rhs = PETSC_TRUE; 100451694757SStefano Zampini PetscBool benign_correction_is_zero = PETSC_FALSE; 1005a3df083aSStefano Zampini PetscBool iscg = PETSC_FALSE; 1006534831adSStefano Zampini 1007534831adSStefano Zampini PetscFunctionBegin; 100885c4d303SStefano Zampini /* if we are working with cg, one dirichlet solve can be avoided during Krylov iterations */ 100985c4d303SStefano Zampini if (ksp) { 101085c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 101185c4d303SStefano Zampini if (!iscg) { 101285c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 101385c4d303SStefano Zampini } 101485c4d303SStefano Zampini } 101585c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 101662a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 101762a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 101862a6ff1dSStefano Zampini } 101962a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 102062a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 102162a6ff1dSStefano Zampini } 10228d00608fSStefano Zampini 10233972b0daSStefano Zampini if (x) { 10243972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 10253972b0daSStefano Zampini used_vec = x; 10268d00608fSStefano Zampini } else { /* it can only happen when calling PCBDDCMatFETIDPGetRHS */ 10273972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 10283972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 10293972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 10303972b0daSStefano Zampini } 10318efcfb23SStefano Zampini 10328efcfb23SStefano Zampini /* hack into ksp data structure since PCPreSolve comes earlier than setting to zero the guess in src/ksp/ksp/interface/itfunc.c */ 10333972b0daSStefano Zampini if (ksp) { 1034a0cb1b98SStefano Zampini /* store the flag for the initial guess since it will be restored back during PCPostSolve_BDDC */ 10358efcfb23SStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 10368efcfb23SStefano Zampini if (!pcbddc->ksp_guess_nonzero) { 10373972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 10383972b0daSStefano Zampini } 10393972b0daSStefano Zampini } 10403308cffdSStefano Zampini 10418d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 10423972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 1043a07ea27aSStefano Zampini if (rhs) { 10443975b054SStefano Zampini IS dirIS = NULL; 10453975b054SStefano Zampini 1046a07ea27aSStefano Zampini /* DirichletBoundariesLocal may not be consistent among neighbours; gets a dirichlet dofs IS from graph (may be cached) */ 10473975b054SStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 10483975b054SStefano Zampini if (dirIS) { 1049906d46d4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1050785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 10512b095fd8SStefano Zampini PetscScalar *array_x; 10522b095fd8SStefano Zampini const PetscScalar *array_diagonal; 1053785d1243SStefano Zampini 10543972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 10553972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 1056e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1057e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1058e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1059e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 106082ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 10613972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 10622b095fd8SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 10633972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 10642fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 10653972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 10662b095fd8SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 10673972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 1068e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1069e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 10708d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 10711b968477SStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 10728efcfb23SStefano Zampini } 1073a07ea27aSStefano Zampini } 1074b76ba322SStefano Zampini 10758efcfb23SStefano Zampini /* remove the computed solution or the initial guess from the rhs */ 10768d00608fSStefano Zampini if (pcbddc->rhs_change || (ksp && pcbddc->ksp_guess_nonzero) ) { 10778d00608fSStefano Zampini /* store the original rhs */ 10788d00608fSStefano Zampini if (copy_rhs) { 10798d00608fSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 10808d00608fSStefano Zampini copy_rhs = PETSC_FALSE; 10818d00608fSStefano Zampini } 10828d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 10833972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 10840369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,used_vec,rhs,rhs);CHKERRQ(ierr); 10853972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 10868efcfb23SStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 10877acc28cbSStefano Zampini if (ksp) { 10887acc28cbSStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_FALSE);CHKERRQ(ierr); 10897acc28cbSStefano Zampini } 10903308cffdSStefano Zampini } 10918efcfb23SStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 1092b76ba322SStefano Zampini 10930369aaf7SStefano Zampini /* When using the benign trick: (TODO: what about FETI-DP?) 10940369aaf7SStefano Zampini - change rhs on pressures (iteration matrix is surely of type MATIS) 10950369aaf7SStefano Zampini - compute initial vector in benign space 10960369aaf7SStefano Zampini */ 10970369aaf7SStefano Zampini if (rhs && pcbddc->benign_saddle_point) { 109806f24817SStefano Zampini Mat_IS *matis = (Mat_IS*)(pc->mat->data); 10994f1b2e48SStefano Zampini PetscInt i; 110006f24817SStefano Zampini 110106f24817SStefano Zampini /* store the original rhs */ 110206f24817SStefano Zampini if (copy_rhs) { 110306f24817SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 110406f24817SStefano Zampini copy_rhs = PETSC_FALSE; 110506f24817SStefano Zampini } 110606f24817SStefano Zampini 110706f24817SStefano Zampini /* now change (locally) the basis */ 110806f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,rhs,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 110906f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,rhs,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 111006f24817SStefano Zampini if (pcbddc->benign_change) { 111106f24817SStefano Zampini ierr = MatMultTranspose(pcbddc->benign_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 111206f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 111306f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11145cfd9691SStefano Zampini /* swap local iteration matrix (with the benign trick, amat == pmat) */ 1115a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 1116a3df083aSStefano Zampini /* benign shell mat mult for matis->A and pcis->A_IB*/ 1117a3df083aSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_FALSE);CHKERRQ(ierr); 1118a3df083aSStefano Zampini } else { 11195cfd9691SStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_FALSE);CHKERRQ(ierr); 112006f24817SStefano Zampini pcbddc->benign_original_mat = matis->A; 112106f24817SStefano Zampini matis->A = pcbddc->local_mat; 1122a3df083aSStefano Zampini } 112306f24817SStefano Zampini } else { 112406f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 112506f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 112677a2de6eSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 112777a2de6eSStefano Zampini pcbddc->benign_original_mat = matis->A; 112877a2de6eSStefano Zampini matis->A = pcbddc->local_mat; 112977a2de6eSStefano Zampini } 113006f24817SStefano Zampini } 113106f24817SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 113206f24817SStefano Zampini 11330369aaf7SStefano Zampini /* compute u^*_h as in Xuemin Tu's thesis (see Section 4.8.1) */ 11340369aaf7SStefano Zampini /* TODO: what about Stokes? */ 11350369aaf7SStefano Zampini if (!pcbddc->benign_vec) { 11360369aaf7SStefano Zampini ierr = VecDuplicate(rhs,&pcbddc->benign_vec);CHKERRQ(ierr); 11370369aaf7SStefano Zampini } 11384f1b2e48SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 11394f1b2e48SStefano Zampini if (pcbddc->benign_n) { 11400369aaf7SStefano Zampini const PetscScalar *array; 11410369aaf7SStefano Zampini 11420369aaf7SStefano Zampini ierr = VecGetArrayRead(pcis->vec2_N,&array);CHKERRQ(ierr); 11434f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[pcbddc->benign_p0_lidx[i]]; 11440369aaf7SStefano Zampini ierr = VecRestoreArrayRead(pcis->vec2_N,&array);CHKERRQ(ierr); 11450369aaf7SStefano Zampini } 114651694757SStefano Zampini if (pcbddc->benign_null && iscg) { /* this is a workaround, need to understand more */ 11474f1b2e48SStefano Zampini PetscBool iszero_l = PETSC_TRUE; 11484f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 11494f1b2e48SStefano Zampini iszero_l = (iszero_l && (PetscAbsScalar(pcbddc->benign_p0[i]) < PETSC_SMALL ? PETSC_TRUE : PETSC_FALSE)); 11504f1b2e48SStefano Zampini } 115151694757SStefano Zampini ierr = MPI_Allreduce(&iszero_l,&benign_correction_is_zero,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 115251694757SStefano Zampini } 11534fee134fSStefano Zampini if (!benign_correction_is_zero) { /* use the coarse solver only */ 1154015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 11554fee134fSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_TRUE; 11560369aaf7SStefano Zampini ierr = PCApply_BDDC(pc,pcis->vec1_global,pcbddc->benign_vec);CHKERRQ(ierr); 11574fee134fSStefano Zampini pcbddc->benign_apply_coarse_only = PETSC_FALSE; 11584f1b2e48SStefano Zampini ierr = PetscMemzero(pcbddc->benign_p0,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 1159015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcbddc->benign_vec,PETSC_FALSE);CHKERRQ(ierr); 1160b76ba322SStefano Zampini } 116151694757SStefano Zampini } 1162b76ba322SStefano Zampini 11630369aaf7SStefano Zampini /* change rhs and iteration matrix if using the change of basis */ 1164b9b85e73SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1165906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 1166906d46d4SStefano Zampini 1167906d46d4SStefano Zampini /* get change ctx */ 1168906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 1169906d46d4SStefano Zampini 1170906d46d4SStefano Zampini /* set current iteration matrix inside change context (change of basis has been already set into the ctx during PCSetUp) */ 117177a2de6eSStefano Zampini if (!pcbddc->benign_original_mat) { 1172906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->original_mat);CHKERRQ(ierr); 1173906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pc->mat);CHKERRQ(ierr); 1174906d46d4SStefano Zampini change_ctx->original_mat = pc->mat; 1175906d46d4SStefano Zampini 1176906d46d4SStefano Zampini /* change iteration matrix */ 1177906d46d4SStefano Zampini ierr = MatDestroy(&pc->mat);CHKERRQ(ierr); 1178906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->new_global_mat);CHKERRQ(ierr); 1179906d46d4SStefano Zampini pc->mat = pcbddc->new_global_mat; 11809bd2e3c7SStefano Zampini } 11818d00608fSStefano Zampini /* store the original rhs */ 11828d00608fSStefano Zampini if (copy_rhs) { 11838d00608fSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 11848d00608fSStefano Zampini copy_rhs = PETSC_FALSE; 11858d00608fSStefano Zampini } 11868d00608fSStefano Zampini 1187906d46d4SStefano Zampini /* change rhs */ 1188906d46d4SStefano Zampini ierr = MatMultTranspose(change_ctx->global_change,rhs,pcis->vec1_global);CHKERRQ(ierr); 1189906d46d4SStefano Zampini ierr = VecCopy(pcis->vec1_global,rhs);CHKERRQ(ierr); 11908d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 119192e3dcfbSStefano Zampini } 119292e3dcfbSStefano Zampini 11930369aaf7SStefano Zampini /* remove non-benign solution from the rhs */ 11940369aaf7SStefano Zampini if (pcbddc->benign_saddle_point) { 11950369aaf7SStefano Zampini /* store the original rhs */ 11960369aaf7SStefano Zampini if (copy_rhs) { 11970369aaf7SStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 11980369aaf7SStefano Zampini copy_rhs = PETSC_FALSE; 11990369aaf7SStefano Zampini } 120051694757SStefano Zampini if (benign_correction_is_zero) { /* still need to understand why it works great */ 120151694757SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 120251694757SStefano Zampini ierr = PCApply_BDDC(pc,rhs,pcbddc->benign_vec);CHKERRQ(ierr); 120351694757SStefano Zampini } 12040369aaf7SStefano Zampini ierr = VecScale(pcbddc->benign_vec,-1.0);CHKERRQ(ierr); 12050369aaf7SStefano Zampini ierr = MatMultAdd(pc->mat,pcbddc->benign_vec,rhs,rhs);CHKERRQ(ierr); 12060369aaf7SStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 12070369aaf7SStefano Zampini } 12080369aaf7SStefano Zampini 12090369aaf7SStefano Zampini /* set initial guess if using PCG */ 12100369aaf7SStefano Zampini if (x && pcbddc->use_exact_dirichlet_trick) { 12110369aaf7SStefano Zampini ierr = VecSet(x,0.0);CHKERRQ(ierr); 12120369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12130369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12140369aaf7SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 12150369aaf7SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12160369aaf7SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12170369aaf7SStefano Zampini if (ksp) { 12180369aaf7SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 12190369aaf7SStefano Zampini } 12200369aaf7SStefano Zampini } 1221b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 1222b0f5fe93SStefano Zampini MatNullSpace null_space; 1223b0f5fe93SStefano Zampini Vec nullv; 1224b0f5fe93SStefano Zampini PetscBool isnull; 12254f1b2e48SStefano Zampini PetscInt i; 1226b0f5fe93SStefano Zampini 12274f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1.; 1228b0f5fe93SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&nullv);CHKERRQ(ierr); 1229b0f5fe93SStefano Zampini ierr = VecSet(nullv,0.);CHKERRQ(ierr); 1230b0f5fe93SStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,nullv,PETSC_FALSE);CHKERRQ(ierr); 1231b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 1232b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)pc),PETSC_FALSE,1,&nullv,&null_space);CHKERRQ(ierr); 1233b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(null_space,pc->mat,&isnull);CHKERRQ(ierr); 12344f1b2e48SStefano Zampini if (isnull) { 1235b0f5fe93SStefano Zampini ierr = MatSetNullSpace(pc->mat,null_space);CHKERRQ(ierr); 12364f1b2e48SStefano Zampini } 1237b0f5fe93SStefano Zampini ierr = MatNullSpaceDestroy(&null_space);CHKERRQ(ierr); 1238b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 1239b0f5fe93SStefano Zampini } 1240b0f5fe93SStefano Zampini 124192e3dcfbSStefano Zampini /* remove nullspace if present */ 12428efcfb23SStefano Zampini if (ksp && x && pcbddc->NullSpace) { 12438efcfb23SStefano Zampini ierr = MatNullSpaceRemove(pcbddc->NullSpace,x);CHKERRQ(ierr); 12448d00608fSStefano Zampini /* store the original rhs */ 12458d00608fSStefano Zampini if (copy_rhs) { 12468d00608fSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 12478d00608fSStefano Zampini copy_rhs = PETSC_FALSE; 12488d00608fSStefano Zampini } 12498d00608fSStefano Zampini pcbddc->rhs_change = PETSC_TRUE; 1250d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs);CHKERRQ(ierr); 1251b76ba322SStefano Zampini } 1252534831adSStefano Zampini PetscFunctionReturn(0); 1253534831adSStefano Zampini } 1254906d46d4SStefano Zampini 1255534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1256534831adSStefano Zampini #undef __FUNCT__ 1257534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 1258534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 1259534831adSStefano Zampini /* 1260534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 1261534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 1262534831adSStefano Zampini 1263534831adSStefano Zampini Input Parameter: 1264534831adSStefano Zampini + pc - the preconditioner contex 1265534831adSStefano Zampini 1266534831adSStefano Zampini Application Interface Routine: PCPostSolve() 1267534831adSStefano Zampini 1268534831adSStefano Zampini Notes: 1269534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 1270534831adSStefano Zampini the user, but instead is called by KSPSolve(). 1271534831adSStefano Zampini */ 1272534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1273534831adSStefano Zampini { 1274534831adSStefano Zampini PetscErrorCode ierr; 1275534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1276534831adSStefano Zampini 1277534831adSStefano Zampini PetscFunctionBegin; 127877a2de6eSStefano Zampini if (pcbddc->ChangeOfBasisMatrix && !pcbddc->benign_original_mat) { 1279906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 1280906d46d4SStefano Zampini 1281906d46d4SStefano Zampini /* get change ctx */ 1282906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 1283906d46d4SStefano Zampini 1284906d46d4SStefano Zampini /* restore iteration matrix */ 1285906d46d4SStefano Zampini ierr = MatDestroy(&pc->mat);CHKERRQ(ierr); 1286906d46d4SStefano Zampini ierr = PetscObjectReference((PetscObject)change_ctx->original_mat);CHKERRQ(ierr); 1287906d46d4SStefano Zampini pc->mat = change_ctx->original_mat; 12889c6a02ceSStefano Zampini } 1289906d46d4SStefano Zampini 12908666afb4SStefano Zampini /* need to restore the local matrices */ 129177a2de6eSStefano Zampini if (pcbddc->benign_original_mat) { 12928666afb4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->mat->data; 12938666afb4SStefano Zampini 1294a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 1295a3df083aSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 1296a3df083aSStefano Zampini } else { 12975cfd9691SStefano Zampini pcbddc->local_mat = matis->A; 12988666afb4SStefano Zampini matis->A = pcbddc->benign_original_mat; 12995cfd9691SStefano Zampini pcbddc->benign_original_mat = NULL; 13008666afb4SStefano Zampini } 1301a3df083aSStefano Zampini } 13028666afb4SStefano Zampini 1303906d46d4SStefano Zampini /* get solution in original basis */ 1304906d46d4SStefano Zampini if (x) { 1305906d46d4SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 130606f24817SStefano Zampini 13072d3346b4SStefano Zampini /* restore solution on pressures */ 130806a4e24aSStefano Zampini if (pcbddc->benign_saddle_point) { 13092d3346b4SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->mat->data; 13102d3346b4SStefano Zampini 13110369aaf7SStefano Zampini /* add non-benign solution */ 13128666afb4SStefano Zampini ierr = VecAXPY(x,-1.0,pcbddc->benign_vec);CHKERRQ(ierr); 13130369aaf7SStefano Zampini 13140369aaf7SStefano Zampini /* change basis on pressures for x */ 131506f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 131606f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13172d3346b4SStefano Zampini if (pcbddc->benign_change) { 13182d3346b4SStefano Zampini ierr = MatMult(pcbddc->benign_change,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 131906f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 132006f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13212d3346b4SStefano Zampini } else { 132206f24817SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 132306f24817SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13242d3346b4SStefano Zampini } 13252d3346b4SStefano Zampini } 13269c6a02ceSStefano Zampini 13270369aaf7SStefano Zampini /* change basis on x */ 13289c6a02ceSStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 13299c6a02ceSStefano Zampini PCBDDCChange_ctx change_ctx; 13309c6a02ceSStefano Zampini 13319c6a02ceSStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 13320369aaf7SStefano Zampini ierr = MatMult(change_ctx->global_change,x,pcis->vec1_global);CHKERRQ(ierr); 1333906d46d4SStefano Zampini ierr = VecCopy(pcis->vec1_global,x);CHKERRQ(ierr); 13343425bc38SStefano Zampini } 1335534831adSStefano Zampini } 1336906d46d4SStefano Zampini 13373972b0daSStefano Zampini /* add solution removed in presolve */ 13386bcfc461SStefano Zampini if (x && pcbddc->rhs_change) { 13393425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 13403425bc38SStefano Zampini } 1341906d46d4SStefano Zampini 1342fb223d50SStefano Zampini /* restore rhs to its original state */ 13438d00608fSStefano Zampini if (rhs && pcbddc->rhs_change) { 1344fb223d50SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 1345fb223d50SStefano Zampini } 13468d00608fSStefano Zampini pcbddc->rhs_change = PETSC_FALSE; 13478efcfb23SStefano Zampini 13488efcfb23SStefano Zampini /* restore ksp guess state */ 13498efcfb23SStefano Zampini if (ksp) { 13508efcfb23SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,pcbddc->ksp_guess_nonzero);CHKERRQ(ierr); 13518efcfb23SStefano Zampini } 1352534831adSStefano Zampini PetscFunctionReturn(0); 1353534831adSStefano Zampini } 1354534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 135553cdbc3dSStefano Zampini #undef __FUNCT__ 135653cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 13570c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 13580c7d97c5SJed Brown /* 13590c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 13600c7d97c5SJed Brown by setting data structures and options. 13610c7d97c5SJed Brown 13620c7d97c5SJed Brown Input Parameter: 136353cdbc3dSStefano Zampini + pc - the preconditioner context 13640c7d97c5SJed Brown 13650c7d97c5SJed Brown Application Interface Routine: PCSetUp() 13660c7d97c5SJed Brown 13670c7d97c5SJed Brown Notes: 13680c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 13690c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 13700c7d97c5SJed Brown */ 137153cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 13720c7d97c5SJed Brown { 13730c7d97c5SJed Brown PetscErrorCode ierr; 13740c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 13755e8657edSStefano Zampini Mat_IS* matis; 137608122e43SStefano Zampini MatNullSpace nearnullspace; 1377c9ed8603SStefano Zampini IS zerodiag = NULL; 137891e8d312SStefano Zampini PetscInt nrows,ncols; 137908122e43SStefano Zampini PetscBool computetopography,computesolvers,computesubschurs; 13808de1fae6SStefano Zampini PetscBool computeconstraintsmatrix; 13815e8657edSStefano Zampini PetscBool new_nearnullspace_provided,ismatis; 13820c7d97c5SJed Brown 13830c7d97c5SJed Brown PetscFunctionBegin; 13845e8657edSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATIS,&ismatis);CHKERRQ(ierr); 13855e8657edSStefano Zampini if (!ismatis) { 13865e8657edSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner requires matrix of type MATIS"); 13875e8657edSStefano Zampini } 138891e8d312SStefano Zampini ierr = MatGetSize(pc->pmat,&nrows,&ncols);CHKERRQ(ierr); 138991e8d312SStefano Zampini if (nrows != ncols) { 139091e8d312SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCBDDC preconditioner requires a square preconditioning matrix"); 139191e8d312SStefano Zampini } 13925e8657edSStefano Zampini matis = (Mat_IS*)pc->pmat->data; 1393f4ddd8eeSStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other future nonoverlapping preconditioners */ 13943b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 1395fcd409f5SStefano Zampini Also, BDDC directly build the Dirichlet problem */ 1396f4ddd8eeSStefano Zampini /* split work */ 1397674ae819SStefano Zampini if (pc->setupcalled) { 1398d1e9a80fSBarry Smith if (pc->flag == SAME_NONZERO_PATTERN) { 1399674ae819SStefano Zampini computetopography = PETSC_FALSE; 1400674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1401674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 1402674ae819SStefano Zampini computetopography = PETSC_TRUE; 1403674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1404674ae819SStefano Zampini } 1405674ae819SStefano Zampini } else { 1406674ae819SStefano Zampini computetopography = PETSC_TRUE; 1407674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1408674ae819SStefano Zampini } 1409fb180af4SStefano Zampini if (pcbddc->recompute_topography) { 1410fb180af4SStefano Zampini computetopography = PETSC_TRUE; 1411fb180af4SStefano Zampini } 14128de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_FALSE; 1413b087196eSStefano Zampini 1414b087196eSStefano Zampini /* check parameters' compatibility */ 14155a95e1ceSStefano Zampini if (pcbddc->adaptive_threshold > 0.0 && !pcbddc->use_deluxe_scaling) { 14165a95e1ceSStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot compute adaptive constraints without deluxe scaling. Rerun with -pc_bddc_use_deluxe_scaling"); 14175a95e1ceSStefano Zampini } 14185a95e1ceSStefano Zampini pcbddc->adaptive_selection = (PetscBool)(pcbddc->adaptive_threshold > 0.0 && pcbddc->use_deluxe_scaling); 1419*bf3a8328SStefano Zampini pcbddc->adaptive_userdefined = (PetscBool)(pcbddc->adaptive_selection && pcbddc->adaptive_userdefined); 1420862806e4SStefano Zampini if (pcbddc->adaptive_selection) pcbddc->use_faces = PETSC_TRUE; 1421862806e4SStefano Zampini 14225a95e1ceSStefano Zampini computesubschurs = (PetscBool)(pcbddc->adaptive_selection || pcbddc->use_deluxe_scaling); 14236816873aSStefano Zampini if (pcbddc->faster_deluxe && pcbddc->adaptive_selection && pcbddc->use_change_of_basis) { 14246816873aSStefano 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"); 14256816873aSStefano Zampini } 14262d3346b4SStefano Zampini 14272d3346b4SStefano Zampini /* check if the iteration matrix is of type MATIS in case the benign trick has been requested */ 14282d3346b4SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&ismatis);CHKERRQ(ierr); 142906a4e24aSStefano Zampini if (pcbddc->benign_saddle_point && !ismatis) { 14302d3346b4SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner with benign subspace trick requires the iteration matrix to be of type MATIS"); 14312d3346b4SStefano Zampini } 14325cfd9691SStefano Zampini if (pcbddc->benign_saddle_point && pc->mat != pc->pmat) { 143316e386b8SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"PCBDDC preconditioner with benign subspace trick requires Amat == Pmat"); 14345cfd9691SStefano Zampini } 14352d3346b4SStefano Zampini 1436f4ddd8eeSStefano Zampini /* Get stdout for dbg */ 143770cf5478SStefano Zampini if (pcbddc->dbg_flag) { 143870cf5478SStefano Zampini if (!pcbddc->dbg_viewer) { 143958a03d70SStefano Zampini pcbddc->dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pc)); 14401575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 1441f4ddd8eeSStefano Zampini } 144258a03d70SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 1443f4ddd8eeSStefano Zampini } 1444f4ddd8eeSStefano Zampini 14455e8657edSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 14465e8657edSStefano Zampini /* use_change_of_basis flag is used to automatically compute a change of basis from constraints */ 14475e8657edSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 14485e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 14495e8657edSStefano Zampini } else { 1450b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 14515e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 14525e8657edSStefano Zampini pcbddc->local_mat = matis->A; 1453d16cbb6bSStefano Zampini } 1454d16cbb6bSStefano Zampini 14554f1b2e48SStefano Zampini /* detect local disconnected subdomains if requested and not done before */ 14564f1b2e48SStefano Zampini if (pcbddc->detect_disconnected && !pcbddc->n_local_subs) { 14574f1b2e48SStefano Zampini ierr = MatDetectDisconnectedComponents(pcbddc->local_mat,PETSC_FALSE,&pcbddc->n_local_subs,&pcbddc->local_subs);CHKERRQ(ierr); 14584f1b2e48SStefano Zampini } 14594f1b2e48SStefano Zampini 14604f1b2e48SStefano Zampini /* 14614f1b2e48SStefano Zampini change basis on local pressures (aka zerodiag dofs) 14624f1b2e48SStefano Zampini This should come earlier then PCISSetUp for extracting the correct subdomain matrices 14634f1b2e48SStefano Zampini */ 1464d16cbb6bSStefano Zampini if (pcbddc->benign_saddle_point) { 14659f47a83aSStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 14669f47a83aSStefano Zampini 1467a3df083aSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->use_change_of_basis) pcbddc->benign_change_explicit = PETSC_TRUE; 1468339f8db1SStefano Zampini /* detect local saddle point and change the basis in pcbddc->local_mat */ 1469339f8db1SStefano Zampini ierr = PCBDDCBenignDetectSaddlePoint(pc,&zerodiag);CHKERRQ(ierr); 1470a3df083aSStefano Zampini /* pop B0 mat from local mat */ 1471c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 14729f47a83aSStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 1473a3df083aSStefano Zampini if (pc->flag == SAME_NONZERO_PATTERN && pcbddc->benign_n && !pcbddc->benign_change_explicit && !pcbddc->dbg_flag) { 1474a3df083aSStefano Zampini pcis->reusesubmatrices = PETSC_TRUE; 1475a3df083aSStefano Zampini } else { 14769f47a83aSStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 1477674ae819SStefano Zampini } 1478a3df083aSStefano Zampini } 1479f1a72664SStefano Zampini /* propagate relevant information */ 14804f1b2e48SStefano Zampini #if !defined(PETSC_USE_COMPLEX) /* workaround for reals */ 14813301b35fSStefano Zampini if (matis->A->symmetric_set) { 14823301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 14833301b35fSStefano Zampini } 1484e496cd5dSStefano Zampini #endif 148506a4e24aSStefano Zampini if (matis->A->symmetric_set) { 148606a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 148706a4e24aSStefano Zampini } 148806a4e24aSStefano Zampini if (matis->A->spd_set) { 148906a4e24aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SPD,matis->A->spd);CHKERRQ(ierr); 149006a4e24aSStefano Zampini } 1491e496cd5dSStefano Zampini 14925e8657edSStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 14935e8657edSStefano Zampini { 14945e8657edSStefano Zampini Mat temp_mat; 14955e8657edSStefano Zampini 14965e8657edSStefano Zampini temp_mat = matis->A; 14975e8657edSStefano Zampini matis->A = pcbddc->local_mat; 14985e8657edSStefano Zampini ierr = PCISSetUp(pc,PETSC_FALSE);CHKERRQ(ierr); 14995e8657edSStefano Zampini pcbddc->local_mat = matis->A; 15005e8657edSStefano Zampini matis->A = temp_mat; 15015e8657edSStefano Zampini } 1502684f6988SStefano Zampini 150381d14e9dSStefano Zampini /* Analyze interface */ 1504674ae819SStefano Zampini if (computetopography) { 1505674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 15068de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1507674ae819SStefano Zampini } 1508fb8d54d4SStefano Zampini 15095408967cSStefano Zampini /* check existence of a divergence free extension, i.e. 15105408967cSStefano Zampini b(v_I,p_0) = 0 for all v_I (raise error if not). 15115408967cSStefano Zampini Also, check that PCBDDCBenignGetOrSetP0 works */ 15125408967cSStefano Zampini #if defined(PETSC_USE_DEBUG) 151309f581a4SStefano Zampini if (pcbddc->benign_saddle_point) { 15145408967cSStefano Zampini ierr = PCBDDCBenignCheck(pc,zerodiag);CHKERRQ(ierr); 151509f581a4SStefano Zampini } 15165408967cSStefano Zampini #endif 15174f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 151806f24817SStefano Zampini 1519b96c3477SStefano Zampini /* Setup local dirichlet solver ksp_D and sub_schurs solvers */ 1520684f6988SStefano Zampini if (computesolvers) { 1521d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 1522d5574798SStefano Zampini 1523d5574798SStefano Zampini if (computesubschurs && computetopography) { 152408122e43SStefano Zampini ierr = PCBDDCInitSubSchurs(pc);CHKERRQ(ierr); 1525b1b3d7a2SStefano Zampini } 1526df4d28bfSStefano Zampini if (sub_schurs->schur_explicit) { 15272070dbb6SStefano Zampini if (computesubschurs) { 152808122e43SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 15292070dbb6SStefano Zampini } 1530d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 1531d5574798SStefano Zampini } else { 1532d5574798SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_TRUE,PETSC_FALSE);CHKERRQ(ierr); 15332070dbb6SStefano Zampini if (computesubschurs) { 1534d5574798SStefano Zampini ierr = PCBDDCSetUpSubSchurs(pc);CHKERRQ(ierr); 1535d5574798SStefano Zampini } 15362070dbb6SStefano Zampini } 153708122e43SStefano Zampini if (pcbddc->adaptive_selection) { 153808122e43SStefano Zampini ierr = PCBDDCAdaptiveSelection(pc);CHKERRQ(ierr); 15398de1fae6SStefano Zampini computeconstraintsmatrix = PETSC_TRUE; 1540b7eb3628SStefano Zampini } 1541b1b3d7a2SStefano Zampini } 1542684f6988SStefano Zampini 1543f4ddd8eeSStefano Zampini /* infer if NullSpace object attached to Mat via MatSetNearNullSpace has changed */ 1544fb8d54d4SStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1545f4ddd8eeSStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullspace);CHKERRQ(ierr); 1546f4ddd8eeSStefano Zampini if (pcbddc->onearnullspace) { /* already used nearnullspace */ 1547f4ddd8eeSStefano Zampini if (!nearnullspace) { /* near null space attached to mat has been destroyed */ 1548f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1549f4ddd8eeSStefano Zampini } else { 1550f4ddd8eeSStefano Zampini /* determine if the two nullspaces are different (should be lightweight) */ 1551f4ddd8eeSStefano Zampini if (nearnullspace != pcbddc->onearnullspace) { 1552f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1553165b64e2SStefano Zampini } else { /* maybe the user has changed the content of the nearnullspace so check vectors ObjectStateId */ 1554f4ddd8eeSStefano Zampini PetscInt i; 1555165b64e2SStefano Zampini const Vec *nearnullvecs; 1556165b64e2SStefano Zampini PetscObjectState state; 1557165b64e2SStefano Zampini PetscInt nnsp_size; 1558165b64e2SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullspace,NULL,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 1559f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 1560f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&state);CHKERRQ(ierr); 1561165b64e2SStefano Zampini if (pcbddc->onearnullvecs_state[i] != state) { 1562f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1563f4ddd8eeSStefano Zampini break; 1564f4ddd8eeSStefano Zampini } 1565f4ddd8eeSStefano Zampini } 1566f4ddd8eeSStefano Zampini } 1567f4ddd8eeSStefano Zampini } 1568f4ddd8eeSStefano Zampini } else { 1569f4ddd8eeSStefano Zampini if (!nearnullspace) { /* both nearnullspaces are null */ 1570f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_FALSE; 1571f4ddd8eeSStefano Zampini } else { /* nearnullspace attached later */ 1572f4ddd8eeSStefano Zampini new_nearnullspace_provided = PETSC_TRUE; 1573f4ddd8eeSStefano Zampini } 1574f4ddd8eeSStefano Zampini } 1575f4ddd8eeSStefano Zampini 1576f4ddd8eeSStefano Zampini /* Setup constraints and related work vectors */ 1577727cdba6SStefano Zampini /* reset primal space flags */ 1578f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 1579727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 15808de1fae6SStefano Zampini if (computeconstraintsmatrix || new_nearnullspace_provided) { 1581727cdba6SStefano Zampini /* It also sets the primal space flags */ 1582674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 1583e7b262bdSStefano Zampini /* Allocate needed local vectors (which depends on quantities defined during ConstraintsSetUp) */ 1584f4ddd8eeSStefano Zampini ierr = PCBDDCSetUpLocalWorkVectors(pc);CHKERRQ(ierr); 15853975b054SStefano Zampini } 15865e8657edSStefano Zampini 15873975b054SStefano Zampini if (computesolvers || pcbddc->new_primal_space) { 15885e8657edSStefano Zampini if (pcbddc->use_change_of_basis) { 15895e8657edSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 1590c263805aSStefano Zampini Mat temp_mat = NULL; 15915e8657edSStefano Zampini 15924f1b2e48SStefano Zampini if (pcbddc->benign_change) { 1593c263805aSStefano Zampini /* insert B0 in pcbddc->local_mat */ 1594c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_FALSE);CHKERRQ(ierr); 1595f1a72664SStefano Zampini /* swap local matrices */ 1596f1a72664SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&temp_mat);CHKERRQ(ierr); 1597f1a72664SStefano Zampini ierr = PetscObjectReference((PetscObject)temp_mat);CHKERRQ(ierr); 1598f1a72664SStefano Zampini ierr = MatISSetLocalMat(pc->pmat,pcbddc->local_mat);CHKERRQ(ierr); 1599f1a72664SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 1600c263805aSStefano Zampini } 16015e8657edSStefano Zampini ierr = PCBDDCComputeLocalMatrix(pc,pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 16024f1b2e48SStefano Zampini if (pcbddc->benign_change) { 1603c263805aSStefano Zampini /* restore original matrix */ 1604f1a72664SStefano Zampini ierr = MatISSetLocalMat(pc->pmat,temp_mat);CHKERRQ(ierr); 1605f1a72664SStefano Zampini ierr = PetscObjectDereference((PetscObject)temp_mat);CHKERRQ(ierr); 1606c263805aSStefano Zampini /* pop B0 from pcbddc->local_mat */ 1607c263805aSStefano Zampini ierr = PCBDDCBenignPopOrPushB0(pc,PETSC_TRUE);CHKERRQ(ierr); 1608c263805aSStefano Zampini } 16095e8657edSStefano Zampini /* get submatrices */ 16105e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 16115e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 16125e8657edSStefano Zampini ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 16135e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 16145e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 16155e8657edSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 16163975b054SStefano Zampini /* set flag in pcis to not reuse submatrices during PCISCreate */ 16173975b054SStefano Zampini pcis->reusesubmatrices = PETSC_FALSE; 16189c6a02ceSStefano Zampini } else if (!pcbddc->user_ChangeOfBasisMatrix && !pcbddc->benign_change) { 1619b96c3477SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 16205e8657edSStefano Zampini ierr = PetscObjectReference((PetscObject)matis->A);CHKERRQ(ierr); 16215e8657edSStefano Zampini pcbddc->local_mat = matis->A; 16225e8657edSStefano Zampini } 1623b96c3477SStefano Zampini /* SetUp coarse and local Neumann solvers */ 162499cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1625b96c3477SStefano Zampini /* SetUp Scaling operator */ 1626674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 16270c7d97c5SJed Brown } 16280369aaf7SStefano Zampini 162958a03d70SStefano Zampini if (pcbddc->dbg_flag) { 163058a03d70SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 16312b510759SStefano Zampini } 16320c7d97c5SJed Brown PetscFunctionReturn(0); 16330c7d97c5SJed Brown } 16340c7d97c5SJed Brown 16350c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 16360c7d97c5SJed Brown /* 163750efa1b5SStefano Zampini PCApply_BDDC - Applies the BDDC operator to a vector. 16380c7d97c5SJed Brown 16390c7d97c5SJed Brown Input Parameters: 16400f202f7eSStefano Zampini + pc - the preconditioner context 16410f202f7eSStefano Zampini - r - input vector (global) 16420c7d97c5SJed Brown 16430c7d97c5SJed Brown Output Parameter: 16440c7d97c5SJed Brown . z - output vector (global) 16450c7d97c5SJed Brown 16460c7d97c5SJed Brown Application Interface Routine: PCApply() 16470c7d97c5SJed Brown */ 16480c7d97c5SJed Brown #undef __FUNCT__ 16490c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 165053cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 16510c7d97c5SJed Brown { 16520c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 16530c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1654b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 16550c7d97c5SJed Brown PetscErrorCode ierr; 16563b03a366Sstefano_zampini const PetscScalar one = 1.0; 16573b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 16582617d88aSStefano Zampini const PetscScalar zero = 0.0; 16590c7d97c5SJed Brown 16600c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 16610c7d97c5SJed Brown NN interface preconditioner changed to BDDC 1662b097fa66SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static == PETSC_TRUE) */ 16630c7d97c5SJed Brown 16640c7d97c5SJed Brown PetscFunctionBegin; 1665015636ebSStefano Zampini if (pcbddc->benign_saddle_point) { /* get p0 from r */ 1666015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1667efc2fbd9SStefano Zampini } 166885c4d303SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1669b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 16700c7d97c5SJed Brown /* First Dirichlet solve */ 16710c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16720c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16730c7d97c5SJed Brown /* 16740c7d97c5SJed Brown Assembling right hand side for BDDC operator 1675b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 1676674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 16770c7d97c5SJed Brown */ 1678b097fa66SStefano Zampini if (n_D) { 1679b097fa66SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 16800c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 16818eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1682b097fa66SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 1683b097fa66SStefano Zampini } else { 1684b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1685b097fa66SStefano Zampini } 16860c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 16870c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1688674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1689b76ba322SStefano Zampini } else { 16904fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 1691b097fa66SStefano Zampini if (pcbddc->switch_static) { 16920bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 1693b097fa66SStefano Zampini } 1694674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1695b76ba322SStefano Zampini } 16964fee134fSStefano Zampini } 1697b76ba322SStefano Zampini 16982617d88aSStefano Zampini /* Apply interface preconditioner 16992617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1700dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 17012617d88aSStefano Zampini 1702674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1703674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 17040c7d97c5SJed Brown 17053b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 17060c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17070c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1708b097fa66SStefano Zampini if (n_B) { 17090c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 17108eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 1711b097fa66SStefano Zampini } else if (pcbddc->switch_static) { 1712b097fa66SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 1713b097fa66SStefano Zampini } 1714df187020SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1715efc2fbd9SStefano Zampini 1716b097fa66SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1717b097fa66SStefano Zampini if (pcbddc->switch_static) { 1718b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1719b097fa66SStefano Zampini } else { 1720b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1721b097fa66SStefano Zampini } 17220c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17230c7d97c5SJed Brown ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1724b097fa66SStefano Zampini } else { 1725b097fa66SStefano Zampini if (pcbddc->switch_static) { 1726b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1727b097fa66SStefano Zampini } else { 1728b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1729b097fa66SStefano Zampini } 1730b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1731b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1732b097fa66SStefano Zampini } 1733efc2fbd9SStefano Zampini 1734015636ebSStefano Zampini if (pcbddc->benign_saddle_point) { /* set p0 (computed in PCBDDCApplyInterface) */ 1735015636ebSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1736efc2fbd9SStefano Zampini } 17370c7d97c5SJed Brown PetscFunctionReturn(0); 17380c7d97c5SJed Brown } 173950efa1b5SStefano Zampini 174050efa1b5SStefano Zampini /* -------------------------------------------------------------------------- */ 174150efa1b5SStefano Zampini /* 174250efa1b5SStefano Zampini PCApplyTranspose_BDDC - Applies the transpose of the BDDC operator to a vector. 174350efa1b5SStefano Zampini 174450efa1b5SStefano Zampini Input Parameters: 17450f202f7eSStefano Zampini + pc - the preconditioner context 17460f202f7eSStefano Zampini - r - input vector (global) 174750efa1b5SStefano Zampini 174850efa1b5SStefano Zampini Output Parameter: 174950efa1b5SStefano Zampini . z - output vector (global) 175050efa1b5SStefano Zampini 175150efa1b5SStefano Zampini Application Interface Routine: PCApplyTranspose() 175250efa1b5SStefano Zampini */ 175350efa1b5SStefano Zampini #undef __FUNCT__ 175450efa1b5SStefano Zampini #define __FUNCT__ "PCApplyTranspose_BDDC" 175550efa1b5SStefano Zampini PetscErrorCode PCApplyTranspose_BDDC(PC pc,Vec r,Vec z) 175650efa1b5SStefano Zampini { 175750efa1b5SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 175850efa1b5SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 1759b097fa66SStefano Zampini PetscInt n_B = pcis->n_B, n_D = pcis->n - n_B; 176050efa1b5SStefano Zampini PetscErrorCode ierr; 176150efa1b5SStefano Zampini const PetscScalar one = 1.0; 176250efa1b5SStefano Zampini const PetscScalar m_one = -1.0; 176350efa1b5SStefano Zampini const PetscScalar zero = 0.0; 176450efa1b5SStefano Zampini 176550efa1b5SStefano Zampini PetscFunctionBegin; 1766537c1cdfSStefano Zampini if (pcbddc->benign_saddle_point) { /* get p0 from r */ 1767537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,r,PETSC_TRUE);CHKERRQ(ierr); 1768537c1cdfSStefano Zampini } 176950efa1b5SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1770b097fa66SStefano Zampini ierr = VecCopy(r,z);CHKERRQ(ierr); 177150efa1b5SStefano Zampini /* First Dirichlet solve */ 177250efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 177350efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 177450efa1b5SStefano Zampini /* 177550efa1b5SStefano Zampini Assembling right hand side for BDDC operator 1776b097fa66SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. pcbddc->switch_static == PETSC_TRUE) 177750efa1b5SStefano Zampini - pcis->vec1_B the interface part of the global vector z 177850efa1b5SStefano Zampini */ 1779b097fa66SStefano Zampini if (n_D) { 1780b097fa66SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 178150efa1b5SStefano Zampini ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 178250efa1b5SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 1783b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_IB,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 1784b097fa66SStefano Zampini } else { 1785b097fa66SStefano Zampini ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1786b097fa66SStefano Zampini } 178750efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 178850efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 178950efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 179050efa1b5SStefano Zampini } else { 1791b097fa66SStefano Zampini if (pcbddc->switch_static) { 179250efa1b5SStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 1793b097fa66SStefano Zampini } 179450efa1b5SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 179550efa1b5SStefano Zampini } 179650efa1b5SStefano Zampini 179750efa1b5SStefano Zampini /* Apply interface preconditioner 179850efa1b5SStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 1799dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_TRUE);CHKERRQ(ierr); 180050efa1b5SStefano Zampini 180150efa1b5SStefano Zampini /* Apply transpose of partition of unity operator */ 180250efa1b5SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 180350efa1b5SStefano Zampini 180450efa1b5SStefano Zampini /* Second Dirichlet solve and assembling of output */ 180550efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 180650efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1807b097fa66SStefano Zampini if (n_B) { 180850efa1b5SStefano Zampini ierr = MatMultTranspose(pcis->A_BI,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 180950efa1b5SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 1810b097fa66SStefano Zampini } else if (pcbddc->switch_static) { 1811b097fa66SStefano Zampini ierr = MatMultTranspose(pcis->A_II,pcis->vec1_D,pcis->vec3_D);CHKERRQ(ierr); 1812b097fa66SStefano Zampini } 1813b0147a47SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_D,pcis->vec3_D,pcis->vec4_D);CHKERRQ(ierr); 1814b097fa66SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 1815b097fa66SStefano Zampini if (pcbddc->switch_static) { 1816b097fa66SStefano Zampini ierr = VecAXPBYPCZ(pcis->vec2_D,m_one,one,m_one,pcis->vec4_D,pcis->vec1_D);CHKERRQ(ierr); 1817b097fa66SStefano Zampini } else { 1818b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec2_D,m_one,m_one,pcis->vec4_D);CHKERRQ(ierr); 1819b097fa66SStefano Zampini } 182050efa1b5SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 182150efa1b5SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1822b097fa66SStefano Zampini } else { 1823b097fa66SStefano Zampini if (pcbddc->switch_static) { 1824b097fa66SStefano Zampini ierr = VecAXPBY(pcis->vec4_D,one,m_one,pcis->vec1_D);CHKERRQ(ierr); 1825b097fa66SStefano Zampini } else { 1826b097fa66SStefano Zampini ierr = VecScale(pcis->vec4_D,m_one);CHKERRQ(ierr); 1827b097fa66SStefano Zampini } 1828b097fa66SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1829b097fa66SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec4_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1830b097fa66SStefano Zampini } 1831537c1cdfSStefano Zampini if (pcbddc->benign_saddle_point) { /* set p0 (computed in PCBDDCApplyInterface) */ 1832537c1cdfSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,z,PETSC_FALSE);CHKERRQ(ierr); 1833537c1cdfSStefano Zampini } 183450efa1b5SStefano Zampini PetscFunctionReturn(0); 183550efa1b5SStefano Zampini } 1836da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1837674ae819SStefano Zampini 1838da1bb401SStefano Zampini #undef __FUNCT__ 1839da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 1840da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 1841da1bb401SStefano Zampini { 1842da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1843da1bb401SStefano Zampini PetscErrorCode ierr; 1844da1bb401SStefano Zampini 1845da1bb401SStefano Zampini PetscFunctionBegin; 1846da1bb401SStefano Zampini /* free data created by PCIS */ 1847da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 1848674ae819SStefano Zampini /* free BDDC custom data */ 1849674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 1850674ae819SStefano Zampini /* destroy objects related to topography */ 1851674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 1852674ae819SStefano Zampini /* free allocated graph structure */ 1853da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 1854b96c3477SStefano Zampini /* free allocated sub schurs structure */ 1855b96c3477SStefano Zampini ierr = PetscFree(pcbddc->sub_schurs);CHKERRQ(ierr); 185634a97f8cSStefano Zampini /* destroy objects for scaling operator */ 1857674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 185834a97f8cSStefano Zampini ierr = PetscFree(pcbddc->deluxe_ctx);CHKERRQ(ierr); 1859674ae819SStefano Zampini /* free solvers stuff */ 1860674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 186162a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 186262a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 186362a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 1864906d46d4SStefano Zampini /* free stuff for change of basis hooks */ 1865906d46d4SStefano Zampini if (pcbddc->new_global_mat) { 1866906d46d4SStefano Zampini PCBDDCChange_ctx change_ctx; 1867906d46d4SStefano Zampini ierr = MatShellGetContext(pcbddc->new_global_mat,&change_ctx);CHKERRQ(ierr); 1868906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->original_mat);CHKERRQ(ierr); 1869906d46d4SStefano Zampini ierr = MatDestroy(&change_ctx->global_change);CHKERRQ(ierr); 1870906d46d4SStefano Zampini ierr = VecDestroyVecs(2,&change_ctx->work);CHKERRQ(ierr); 1871906d46d4SStefano Zampini ierr = PetscFree(change_ctx);CHKERRQ(ierr); 1872906d46d4SStefano Zampini } 1873906d46d4SStefano Zampini ierr = MatDestroy(&pcbddc->new_global_mat);CHKERRQ(ierr); 18743425bc38SStefano Zampini /* remove functions */ 1875906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",NULL);CHKERRQ(ierr); 1876674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 187730368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",NULL);CHKERRQ(ierr); 1878bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 18792b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 1880b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 18812b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 1882bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 1883bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 188482ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 1885bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 188682ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 1887bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 188882ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 1889bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 1890785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 1891bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 189263602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 1893bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 1894bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 1895bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 1896bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 1897674ae819SStefano Zampini /* Free the private data structure */ 1898674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 1899da1bb401SStefano Zampini PetscFunctionReturn(0); 1900da1bb401SStefano Zampini } 19013425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 19021e6b0712SBarry Smith 19033425bc38SStefano Zampini #undef __FUNCT__ 19043425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 19053425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 19063425bc38SStefano Zampini { 1907674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 1908c08af4c6SStefano Zampini Vec copy_standard_rhs; 19093425bc38SStefano Zampini PC_IS* pcis; 19103425bc38SStefano Zampini PC_BDDC* pcbddc; 19113425bc38SStefano Zampini PetscErrorCode ierr; 19120c7d97c5SJed Brown 19133425bc38SStefano Zampini PetscFunctionBegin; 19143425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 19153425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 19163425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 19173425bc38SStefano Zampini 1918c08af4c6SStefano Zampini /* 1919c08af4c6SStefano Zampini change of basis for physical rhs if needed 1920c08af4c6SStefano Zampini It also changes the rhs in case of dirichlet boundaries 1921c08af4c6SStefano Zampini TODO: better management when FETIDP will have its own class 1922c08af4c6SStefano Zampini */ 1923c08af4c6SStefano Zampini ierr = VecDuplicate(standard_rhs,©_standard_rhs);CHKERRQ(ierr); 1924c08af4c6SStefano Zampini ierr = VecCopy(standard_rhs,copy_standard_rhs);CHKERRQ(ierr); 1925c08af4c6SStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,copy_standard_rhs,NULL);CHKERRQ(ierr); 19263425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 1927c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,copy_standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1928c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,copy_standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1929fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 1930fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 1931c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1932c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1933674ae819SStefano Zampini /* Apply partition of unity */ 19343425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 1935c08af4c6SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,copy_standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 19368eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 19373425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 19383425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 19393425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 19403425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 1941c08af4c6SStefano Zampini ierr = VecSet(copy_standard_rhs,0.0);CHKERRQ(ierr); 1942c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,copy_standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1943c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,copy_standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1944c08af4c6SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,copy_standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 1945c08af4c6SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1946c08af4c6SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,copy_standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19473425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 19483425bc38SStefano Zampini } 1949c08af4c6SStefano Zampini ierr = VecDestroy(©_standard_rhs);CHKERRQ(ierr); 19503425bc38SStefano Zampini /* BDDC rhs */ 19513425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 19528eeda7d8SStefano Zampini if (pcbddc->switch_static) { 19533425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 19543425bc38SStefano Zampini } 19553425bc38SStefano Zampini /* apply BDDC */ 1956dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 19573425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 19583425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 19593425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 19603425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19613425bc38SStefano Zampini ierr = VecScatterEnd(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 19623425bc38SStefano Zampini PetscFunctionReturn(0); 19633425bc38SStefano Zampini } 19641e6b0712SBarry Smith 19653425bc38SStefano Zampini #undef __FUNCT__ 19663425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 19673425bc38SStefano Zampini /*@ 19680f202f7eSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETI-DP linear system using the physical right-hand side 19693425bc38SStefano Zampini 19703425bc38SStefano Zampini Collective 19713425bc38SStefano Zampini 19723425bc38SStefano Zampini Input Parameters: 19730f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix object obtained by a call to PCBDDCCreateFETIDPOperators 19740f202f7eSStefano Zampini - standard_rhs - the right-hand side of the original linear system 19753425bc38SStefano Zampini 19763425bc38SStefano Zampini Output Parameters: 19770f202f7eSStefano Zampini . fetidp_flux_rhs - the right-hand side for the FETI-DP linear system 19783425bc38SStefano Zampini 19793425bc38SStefano Zampini Level: developer 19803425bc38SStefano Zampini 19813425bc38SStefano Zampini Notes: 19823425bc38SStefano Zampini 19830f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetSolution 19843425bc38SStefano Zampini @*/ 19853425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 19863425bc38SStefano Zampini { 1987674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 19883425bc38SStefano Zampini PetscErrorCode ierr; 19893425bc38SStefano Zampini 19903425bc38SStefano Zampini PetscFunctionBegin; 19913425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 19923425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 19933425bc38SStefano Zampini PetscFunctionReturn(0); 19943425bc38SStefano Zampini } 19953425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 19961e6b0712SBarry Smith 19973425bc38SStefano Zampini #undef __FUNCT__ 19983425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 19993425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 20003425bc38SStefano Zampini { 2001674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 20023425bc38SStefano Zampini PC_IS* pcis; 20033425bc38SStefano Zampini PC_BDDC* pcbddc; 20043425bc38SStefano Zampini PetscErrorCode ierr; 20053425bc38SStefano Zampini 20063425bc38SStefano Zampini PetscFunctionBegin; 20073425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 20083425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 20093425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 20103425bc38SStefano Zampini 20113425bc38SStefano Zampini /* apply B_delta^T */ 20123425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20133425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20143425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 20153425bc38SStefano Zampini /* compute rhs for BDDC application */ 20163425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 20178eeda7d8SStefano Zampini if (pcbddc->switch_static) { 20183425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20193425bc38SStefano Zampini } 20203425bc38SStefano Zampini /* apply BDDC */ 2021dc359a40SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc,PETSC_FALSE);CHKERRQ(ierr); 20223425bc38SStefano Zampini /* put values into standard global vector */ 20233425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20243425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20258eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 20263425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 20273425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 20283425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 20293425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 20303425bc38SStefano Zampini } 20313425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20323425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 20333425bc38SStefano Zampini /* final change of basis if needed 20343425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 20353308cffdSStefano Zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 20363425bc38SStefano Zampini PetscFunctionReturn(0); 20373425bc38SStefano Zampini } 20381e6b0712SBarry Smith 20393425bc38SStefano Zampini #undef __FUNCT__ 20403425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 20413425bc38SStefano Zampini /*@ 20420f202f7eSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution using the solution of the FETI-DP linear system 20433425bc38SStefano Zampini 20443425bc38SStefano Zampini Collective 20453425bc38SStefano Zampini 20463425bc38SStefano Zampini Input Parameters: 20470f202f7eSStefano Zampini + fetidp_mat - the FETI-DP matrix obtained by a call to PCBDDCCreateFETIDPOperators 20480f202f7eSStefano Zampini - fetidp_flux_sol - the solution of the FETI-DP linear system 20493425bc38SStefano Zampini 20503425bc38SStefano Zampini Output Parameters: 20510f202f7eSStefano Zampini . standard_sol - the solution defined on the physical domain 20523425bc38SStefano Zampini 20533425bc38SStefano Zampini Level: developer 20543425bc38SStefano Zampini 20553425bc38SStefano Zampini Notes: 20563425bc38SStefano Zampini 20570f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCCreateFETIDPOperators, PCBDDCMatFETIDPGetRHS 20583425bc38SStefano Zampini @*/ 20593425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 20603425bc38SStefano Zampini { 2061674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 20623425bc38SStefano Zampini PetscErrorCode ierr; 20633425bc38SStefano Zampini 20643425bc38SStefano Zampini PetscFunctionBegin; 20653425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 20663425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 20673425bc38SStefano Zampini PetscFunctionReturn(0); 20683425bc38SStefano Zampini } 20693425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 20701e6b0712SBarry Smith 2071f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 2072edf7251bSStefano Zampini extern PetscErrorCode FETIDPMatMultTranspose(Mat,Vec,Vec); 2073f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 2074f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 2075edf7251bSStefano Zampini extern PetscErrorCode FETIDPPCApplyTranspose(PC,Vec,Vec); 2076f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 2077674ae819SStefano Zampini 20783425bc38SStefano Zampini #undef __FUNCT__ 20793425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 20803425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 20813425bc38SStefano Zampini { 2082674ae819SStefano Zampini 2083674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 20843425bc38SStefano Zampini Mat newmat; 2085674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 20863425bc38SStefano Zampini PC newpc; 2087ce94432eSBarry Smith MPI_Comm comm; 20883425bc38SStefano Zampini PetscErrorCode ierr; 20893425bc38SStefano Zampini 20903425bc38SStefano Zampini PetscFunctionBegin; 2091ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 20923425bc38SStefano Zampini /* FETIDP linear matrix */ 20933425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 20943425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 20953425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 20963425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 2097edf7251bSStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT_TRANSPOSE,(void (*)(void))FETIDPMatMultTranspose);CHKERRQ(ierr); 20983425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 20993425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 21003425bc38SStefano Zampini /* FETIDP preconditioner */ 21013425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 21023425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 21033425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 21043425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 21053425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 21063425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 2107edf7251bSStefano Zampini ierr = PCShellSetApplyTranspose(newpc,FETIDPPCApplyTranspose);CHKERRQ(ierr); 21083425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 210923ee1639SBarry Smith ierr = PCSetOperators(newpc,newmat,newmat);CHKERRQ(ierr); 21103425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 21113425bc38SStefano Zampini /* return pointers for objects created */ 21123425bc38SStefano Zampini *fetidp_mat=newmat; 21133425bc38SStefano Zampini *fetidp_pc=newpc; 21143425bc38SStefano Zampini PetscFunctionReturn(0); 21153425bc38SStefano Zampini } 21161e6b0712SBarry Smith 21173425bc38SStefano Zampini #undef __FUNCT__ 21183425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 21193425bc38SStefano Zampini /*@ 21200f202f7eSStefano Zampini PCBDDCCreateFETIDPOperators - Create FETI-DP operators 21213425bc38SStefano Zampini 21223425bc38SStefano Zampini Collective 21233425bc38SStefano Zampini 21243425bc38SStefano Zampini Input Parameters: 21250f202f7eSStefano Zampini . pc - the BDDC preconditioning context (setup should have been called before) 212628509bceSStefano Zampini 212728509bceSStefano Zampini Output Parameters: 21280f202f7eSStefano Zampini + fetidp_mat - shell FETI-DP matrix object 21290f202f7eSStefano Zampini - fetidp_pc - shell Dirichlet preconditioner for FETI-DP matrix 213028509bceSStefano Zampini 213128509bceSStefano Zampini Options Database Keys: 21320f202f7eSStefano Zampini . -fetidp_fullyredundant <false> - use or not a fully redundant set of Lagrange multipliers 21333425bc38SStefano Zampini 21343425bc38SStefano Zampini Level: developer 21353425bc38SStefano Zampini 21363425bc38SStefano Zampini Notes: 21370f202f7eSStefano Zampini Currently the only operations provided for FETI-DP matrix are MatMult and MatMultTranspose 21383425bc38SStefano Zampini 21390f202f7eSStefano Zampini .seealso: PCBDDC, PCBDDCMatFETIDPGetRHS, PCBDDCMatFETIDPGetSolution 21403425bc38SStefano Zampini @*/ 21413425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 21423425bc38SStefano Zampini { 21433425bc38SStefano Zampini PetscErrorCode ierr; 21443425bc38SStefano Zampini 21453425bc38SStefano Zampini PetscFunctionBegin; 21463425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 21473425bc38SStefano Zampini if (pc->setupcalled) { 2148516d51a7SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 2149f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 21503425bc38SStefano Zampini PetscFunctionReturn(0); 21513425bc38SStefano Zampini } 21520c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2153da1bb401SStefano Zampini /*MC 2154da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 21550c7d97c5SJed Brown 215628509bceSStefano Zampini An implementation of the BDDC preconditioner based on 215728509bceSStefano Zampini 215828509bceSStefano Zampini .vb 215928509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 216028509bceSStefano 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 216128509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 21620f202f7eSStefano 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 216328509bceSStefano Zampini .ve 216428509bceSStefano Zampini 216528509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 216628509bceSStefano Zampini 21670f202f7eSStefano Zampini Currently works with MATIS matrices with local matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 216828509bceSStefano Zampini 216928509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 217028509bceSStefano Zampini 2171b6fdb6dfSStefano 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. 2172b6fdb6dfSStefano Zampini 21730f202f7eSStefano Zampini Approximate local solvers are automatically adapted for singular linear problems (see [1]) if the user has provided the nullspace using PCBDDCSetNullSpace() 217428509bceSStefano Zampini 21750f202f7eSStefano 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() 217630368db7SStefano Zampini Additional information on dofs can be provided by using PCBDDCSetDofsSplitting(), PCBDDCSetDirichletBoundaries(), PCBDDCSetNeumannBoundaries(), and PCBDDCSetPrimalVerticesIS() and their local counterparts. 217728509bceSStefano Zampini 21780f202f7eSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace(). Non-singular modes are retained via SVD. 217928509bceSStefano Zampini 21800f202f7eSStefano 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. 21810f202f7eSStefano Zampini User defined change of basis can be passed to PCBDDC by using PCBDDCSetChangeOfBasisMat() 218228509bceSStefano Zampini 21830f202f7eSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using a MatPartitioning object. 218428509bceSStefano Zampini 2185df4d28bfSStefano 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. 218628509bceSStefano Zampini 21870f202f7eSStefano 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. 21880f202f7eSStefano Zampini Deluxe scaling is not supported yet for FETI-DP. 21890f202f7eSStefano Zampini 21900f202f7eSStefano Zampini Options Database Keys (some of them, run with -h for a complete list): 21910f202f7eSStefano Zampini 21920f202f7eSStefano Zampini . -pc_bddc_use_vertices <true> - use or not vertices in primal space 21930f202f7eSStefano Zampini . -pc_bddc_use_edges <true> - use or not edges in primal space 21940f202f7eSStefano Zampini . -pc_bddc_use_faces <false> - use or not faces in primal space 21950f202f7eSStefano Zampini . -pc_bddc_symmetric <true> - symmetric computation of primal basis functions. Specify false for unsymmetric problems 21960f202f7eSStefano Zampini . -pc_bddc_use_change_of_basis <false> - use change of basis approach (on edges only) 21970f202f7eSStefano Zampini . -pc_bddc_use_change_on_faces <false> - use change of basis approach on faces if change of basis has been requested 21980f202f7eSStefano Zampini . -pc_bddc_switch_static <false> - switches from M_2 (default) to M_3 operator (see reference article [1]) 219928509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 22000f202f7eSStefano 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) 22010f202f7eSStefano 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) 22020f202f7eSStefano Zampini . -pc_bddc_use_deluxe_scaling <false> - use deluxe scaling 22030f202f7eSStefano 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) 2204df4d28bfSStefano 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) 220528509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 220628509bceSStefano Zampini 220728509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 220828509bceSStefano Zampini .vb 220928509bceSStefano Zampini -pc_bddc_dirichlet_ 221028509bceSStefano Zampini -pc_bddc_neumann_ 221128509bceSStefano Zampini -pc_bddc_coarse_ 221228509bceSStefano Zampini .ve 22130f202f7eSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg. PCBDDC uses by default KPSPREONLY and PCLU. 221428509bceSStefano Zampini 22150f202f7eSStefano Zampini When using a multilevel approach, solvers' options at the N-th level (N > 1) can be specified as 221628509bceSStefano Zampini .vb 2217312be037SStefano Zampini -pc_bddc_dirichlet_lN_ 2218312be037SStefano Zampini -pc_bddc_neumann_lN_ 2219312be037SStefano Zampini -pc_bddc_coarse_lN_ 222028509bceSStefano Zampini .ve 22210f202f7eSStefano Zampini Note that level number ranges from the finest (0) to the coarsest (N). 22220f202f7eSStefano 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. 22230f202f7eSStefano Zampini .vb 22240f202f7eSStefano Zampini -pc_bddc_coarse_pc_bddc_adaptive_threshold 5 -pc_bddc_coarse_l1_pc_bddc_redistribute 3 22250f202f7eSStefano Zampini .ve 22260f202f7eSStefano 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 2227da1bb401SStefano Zampini 2228da1bb401SStefano Zampini Level: intermediate 2229da1bb401SStefano Zampini 2230b6fdb6dfSStefano Zampini Developer notes: 2231da1bb401SStefano Zampini 2232da1bb401SStefano Zampini Contributed by Stefano Zampini 2233da1bb401SStefano Zampini 2234da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 2235da1bb401SStefano Zampini M*/ 2236b2573a8aSBarry Smith 2237da1bb401SStefano Zampini #undef __FUNCT__ 2238da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 22398cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 2240da1bb401SStefano Zampini { 2241da1bb401SStefano Zampini PetscErrorCode ierr; 2242da1bb401SStefano Zampini PC_BDDC *pcbddc; 2243da1bb401SStefano Zampini 2244da1bb401SStefano Zampini PetscFunctionBegin; 2245da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 2246b00a9115SJed Brown ierr = PetscNewLog(pc,&pcbddc);CHKERRQ(ierr); 2247da1bb401SStefano Zampini pc->data = (void*)pcbddc; 2248da1bb401SStefano Zampini 2249da1bb401SStefano Zampini /* create PCIS data structure */ 2250da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 2251da1bb401SStefano Zampini 225247d04d0dSStefano Zampini /* BDDC customization */ 225308a5cf49SStefano Zampini pcbddc->use_local_adj = PETSC_TRUE; 225447d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 225547d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 225647d04d0dSStefano Zampini pcbddc->use_faces = PETSC_FALSE; 225747d04d0dSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 225847d04d0dSStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 225947d04d0dSStefano Zampini pcbddc->switch_static = PETSC_FALSE; 2260fa434743SStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; 2261fa434743SStefano Zampini pcbddc->use_qr_single = PETSC_FALSE; 22623301b35fSStefano Zampini pcbddc->symmetric_primal = PETSC_TRUE; 226306a4e24aSStefano Zampini pcbddc->benign_saddle_point = PETSC_FALSE; 226447d04d0dSStefano Zampini pcbddc->dbg_flag = 0; 2265b9d89cd5SStefano Zampini /* private */ 2266727cdba6SStefano Zampini pcbddc->local_primal_size = 0; 22670e6343abSStefano Zampini pcbddc->local_primal_size_cc = 0; 22680e6343abSStefano Zampini pcbddc->local_primal_ref_node = 0; 22690e6343abSStefano Zampini pcbddc->local_primal_ref_mult = 0; 2270e9189074SStefano Zampini pcbddc->n_vertices = 0; 2271727cdba6SStefano Zampini pcbddc->primal_indices_local_idxs = 0; 2272fb180af4SStefano Zampini pcbddc->recompute_topography = PETSC_FALSE; 227368457ee5SStefano Zampini pcbddc->coarse_size = -1; 2274f4ddd8eeSStefano Zampini pcbddc->new_primal_space = PETSC_FALSE; 2275727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_FALSE; 2276f4ddd8eeSStefano Zampini pcbddc->global_primal_indices = 0; 2277f4ddd8eeSStefano Zampini pcbddc->onearnullspace = 0; 2278f4ddd8eeSStefano Zampini pcbddc->onearnullvecs_state = 0; 2279674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 228030368db7SStefano Zampini pcbddc->user_primal_vertices_local = 0; 22810bdf917eSStefano Zampini pcbddc->NullSpace = 0; 22823972b0daSStefano Zampini pcbddc->temp_solution = 0; 2283534831adSStefano Zampini pcbddc->original_rhs = 0; 2284534831adSStefano Zampini pcbddc->local_mat = 0; 2285534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 2286b9b85e73SStefano Zampini pcbddc->user_ChangeOfBasisMatrix = 0; 2287906d46d4SStefano Zampini pcbddc->new_global_mat = 0; 2288da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 2289da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 2290da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 2291da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 229215aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 229315aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 2294da1bb401SStefano Zampini pcbddc->vec1_P = 0; 2295da1bb401SStefano Zampini pcbddc->vec1_R = 0; 2296da1bb401SStefano Zampini pcbddc->vec2_R = 0; 2297da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 2298da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 2299da1bb401SStefano Zampini pcbddc->R_to_B = 0; 2300da1bb401SStefano Zampini pcbddc->R_to_D = 0; 2301da1bb401SStefano Zampini pcbddc->ksp_D = 0; 2302da1bb401SStefano Zampini pcbddc->ksp_R = 0; 2303da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 2304785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = 0; 2305785d1243SStefano Zampini pcbddc->DirichletBoundaries = 0; 2306785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = 0; 230760d44989SStefano Zampini pcbddc->user_provided_isfordofs = PETSC_FALSE; 230860d44989SStefano Zampini pcbddc->n_ISForDofs = 0; 230963602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 2310da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 231163602bcaSStefano Zampini pcbddc->ISForDofsLocal = 0; 2312da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 231385c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 231447d04d0dSStefano Zampini pcbddc->coarse_loc_to_glob = 0; 231547d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 2316b0c7d250SStefano Zampini pcbddc->coarse_adj_red = 0; 23174fad6a16SStefano Zampini pcbddc->current_level = 0; 23182b510759SStefano Zampini pcbddc->max_levels = 0; 2319323d395dSStefano Zampini pcbddc->use_coarse_estimates = PETSC_FALSE; 232074e2c79eSStefano Zampini pcbddc->redistribute_coarse = 0; 2321f3bde8b3SStefano Zampini pcbddc->coarse_subassembling = 0; 2322323d395dSStefano Zampini pcbddc->coarse_subassembling_init = 0; 23234f1b2e48SStefano Zampini pcbddc->detect_disconnected = PETSC_FALSE; 23244f1b2e48SStefano Zampini pcbddc->n_local_subs = 0; 23254f1b2e48SStefano Zampini pcbddc->local_subs = NULL; 232681d14e9dSStefano Zampini 232781d14e9dSStefano Zampini /* benign subspace trick */ 232881d14e9dSStefano Zampini pcbddc->benign_change = 0; 23290369aaf7SStefano Zampini pcbddc->benign_vec = 0; 23300369aaf7SStefano Zampini pcbddc->benign_original_mat = 0; 23310369aaf7SStefano Zampini pcbddc->benign_sf = 0; 23324f1b2e48SStefano Zampini pcbddc->benign_B0 = 0; 23334f1b2e48SStefano Zampini pcbddc->benign_n = 0; 23344f1b2e48SStefano Zampini pcbddc->benign_p0 = NULL; 23354f1b2e48SStefano Zampini pcbddc->benign_p0_lidx = NULL; 23364f1b2e48SStefano Zampini pcbddc->benign_p0_gidx = NULL; 2337b0f5fe93SStefano Zampini pcbddc->benign_null = PETSC_FALSE; 233881d14e9dSStefano Zampini 2339674ae819SStefano Zampini /* create local graph structure */ 2340674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 2341674ae819SStefano Zampini 2342674ae819SStefano Zampini /* scaling */ 2343674ae819SStefano Zampini pcbddc->work_scaling = 0; 234434a97f8cSStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 2345ac632422SStefano Zampini pcbddc->faster_deluxe = PETSC_FALSE; 2346b96c3477SStefano Zampini 2347b96c3477SStefano Zampini /* create sub schurs structure */ 2348b96c3477SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 2349b96c3477SStefano Zampini pcbddc->sub_schurs_rebuild = PETSC_FALSE; 2350b96c3477SStefano Zampini pcbddc->sub_schurs_layers = -1; 2351b96c3477SStefano Zampini pcbddc->sub_schurs_use_useradj = PETSC_FALSE; 2352b96c3477SStefano Zampini 2353b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_FALSE; 2354da1bb401SStefano Zampini 2355b7eb3628SStefano Zampini /* adaptivity */ 2356f6f667cfSStefano Zampini pcbddc->adaptive_threshold = 0.0; 235708122e43SStefano Zampini pcbddc->adaptive_nmax = 0; 2358f6f667cfSStefano Zampini pcbddc->adaptive_nmin = 0; 2359b7eb3628SStefano Zampini 2360da1bb401SStefano Zampini /* function pointers */ 2361da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 236293bd9ae7SStefano Zampini pc->ops->applytranspose = PCApplyTranspose_BDDC; 2363da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 2364da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 2365da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 2366da1bb401SStefano Zampini pc->ops->view = 0; 2367da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 2368da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 2369da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 2370534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 2371534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 2372da1bb401SStefano Zampini 2373da1bb401SStefano Zampini /* composing function */ 2374906d46d4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetChangeOfBasisMat_C",PCBDDCSetChangeOfBasisMat_BDDC);CHKERRQ(ierr); 2375674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 237630368db7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesIS_C",PCBDDCSetPrimalVerticesIS_BDDC);CHKERRQ(ierr); 2377bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 23782b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 2379b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 23802b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 2381bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 2382bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 238382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2384bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 238582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2386bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 238782ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 2388bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 238982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 2390bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 239163602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 2392bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 2393bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 2394bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 2395bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 2396da1bb401SStefano Zampini PetscFunctionReturn(0); 2397da1bb401SStefano Zampini } 23983425bc38SStefano Zampini 2399