153cdbc3dSStefano Zampini /* TODOLIST 2eb97c9d2SStefano Zampini 3eb97c9d2SStefano Zampini ConstraintsSetup 4eb97c9d2SStefano Zampini - assure same constraints between neighbours by sorting vals by global index before SVD! 5eb97c9d2SStefano Zampini - tolerances for constraints as an option (take care of single precision!) 6eb97c9d2SStefano Zampini - Allow different constraints customizations among different linear solves (requires also reset/destroy of ksp_R and coarse_ksp) 7eb97c9d2SStefano Zampini - MAT_IGNORE_ZERO_ENTRIES for Constraints Matrix 8eb97c9d2SStefano Zampini 9eb97c9d2SStefano Zampini Solvers 10eb97c9d2SStefano Zampini - Try to reduce the work when reusing the solvers 11eb97c9d2SStefano Zampini - Add support for reuse fill and cholecky factor for coarse solver (similar to local solvers) 12eb97c9d2SStefano Zampini - reuse already allocated coarse matrix if possible 13eb97c9d2SStefano Zampini - Propagate ksp prefixes for solvers to mat objects? 14eb97c9d2SStefano Zampini - Propagate nearnullspace info among levels 15eb97c9d2SStefano Zampini 16eb97c9d2SStefano Zampini User interface 17eb97c9d2SStefano Zampini - Negative indices in dirichlet and Neumann is should be skipped (now they cause out-of-bounds access) 18eb97c9d2SStefano Zampini - Provide PCApplyTranpose_BDDC 19eb97c9d2SStefano Zampini - DofSplitting and DM attached to pc? 20eb97c9d2SStefano Zampini 21eb97c9d2SStefano Zampini Debugging output 22eb97c9d2SStefano Zampini - Better management of verbosity levels of debugging output 23eb97c9d2SStefano Zampini - Crashes on some architecture -> call SynchronizedAllow before every SynchronizedPrintf 24eb97c9d2SStefano Zampini 25eb97c9d2SStefano Zampini Build 26eb97c9d2SStefano Zampini - make runexe59 27eb97c9d2SStefano Zampini 28eb97c9d2SStefano Zampini Extra 29eb97c9d2SStefano Zampini - Is it possible to work with PCBDDCGraph on boundary indices only (less memory consumed)? 30eb97c9d2SStefano Zampini - Why options for "pc_bddc_coarse" solver gets propagated to "pc_bddc_coarse_1" solver? 31eb97c9d2SStefano Zampini - add support for computing h,H and related using coordinates? 32c0b83709SStefano Zampini - Change of basis approach does not work with my nonlinear mechanics example. why? (seems not an issue with l2gmap) 33eb97c9d2SStefano Zampini - Better management in PCIS code 34eb97c9d2SStefano Zampini - BDDC with MG framework? 35eb97c9d2SStefano Zampini 36eb97c9d2SStefano Zampini FETIDP 37eb97c9d2SStefano Zampini - Move FETIDP code to its own classes 38eb97c9d2SStefano Zampini 39eb97c9d2SStefano Zampini MATIS related operations contained in BDDC code 40eb97c9d2SStefano Zampini - Provide general case for subassembling 41eb97c9d2SStefano Zampini - Preallocation routines in MatConvert_IS_AIJ 42eb97c9d2SStefano Zampini 4353cdbc3dSStefano Zampini */ 440c7d97c5SJed Brown 4553cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 460c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 470c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 4853cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 4953cdbc3dSStefano Zampini 50674ae819SStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 51674ae819SStefano Zampini #include "bddcprivate.h" 523b03a366Sstefano_zampini #include <petscblaslapack.h> 53674ae819SStefano Zampini 540c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 550c7d97c5SJed Brown #undef __FUNCT__ 560c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 570c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 580c7d97c5SJed Brown { 590c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 600c7d97c5SJed Brown PetscErrorCode ierr; 610c7d97c5SJed Brown 620c7d97c5SJed Brown PetscFunctionBegin; 630c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 648eeda7d8SStefano Zampini /* Verbose debugging */ 658eeda7d8SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_check_level","Verbose output for PCBDDC (intended for debug)","none",pcbddc->dbg_flag,&pcbddc->dbg_flag,NULL);CHKERRQ(ierr); 668eeda7d8SStefano Zampini /* Primal space cumstomization */ 678eeda7d8SStefano 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); 688eeda7d8SStefano 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); 698eeda7d8SStefano 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); 708eeda7d8SStefano Zampini /* Change of basis */ 718eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_of_basis","Use or not change of basis on local edge nodes","none",pcbddc->use_change_of_basis,&pcbddc->use_change_of_basis,NULL);CHKERRQ(ierr); 728eeda7d8SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_use_change_on_faces","Use or not change of basis on local face nodes","none",pcbddc->use_change_on_faces,&pcbddc->use_change_on_faces,NULL);CHKERRQ(ierr); 73674ae819SStefano Zampini if (!pcbddc->use_change_of_basis) { 74674ae819SStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 75674ae819SStefano Zampini } 768eeda7d8SStefano Zampini /* Switch between M_2 (default) and M_3 preconditioners (as defined by C. Dohrmann in the ref. article) */ 778eeda7d8SStefano 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); 780298fd71SBarry Smith ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,NULL);CHKERRQ(ierr); 792b510759SStefano Zampini ierr = PetscOptionsInt("-pc_bddc_levels","Set maximum number of levels for multilevel","none",pcbddc->max_levels,&pcbddc->max_levels,NULL);CHKERRQ(ierr); 80674ae819SStefano 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); 810c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 820c7d97c5SJed Brown PetscFunctionReturn(0); 830c7d97c5SJed Brown } 840c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 85674ae819SStefano Zampini #undef __FUNCT__ 86674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS_BDDC" 87674ae819SStefano Zampini static PetscErrorCode PCBDDCSetPrimalVerticesLocalIS_BDDC(PC pc, IS PrimalVertices) 88674ae819SStefano Zampini { 89674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 90674ae819SStefano Zampini PetscErrorCode ierr; 911e6b0712SBarry Smith 92674ae819SStefano Zampini PetscFunctionBegin; 93674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 94674ae819SStefano Zampini ierr = PetscObjectReference((PetscObject)PrimalVertices);CHKERRQ(ierr); 95674ae819SStefano Zampini pcbddc->user_primal_vertices = PrimalVertices; 96674ae819SStefano Zampini PetscFunctionReturn(0); 97674ae819SStefano Zampini } 98674ae819SStefano Zampini #undef __FUNCT__ 99674ae819SStefano Zampini #define __FUNCT__ "PCBDDCSetPrimalVerticesLocalIS" 100674ae819SStefano Zampini /*@ 10128509bceSStefano Zampini PCBDDCSetPrimalVerticesLocalIS - Set additional user defined primal vertices in PCBDDC 102674ae819SStefano Zampini 103674ae819SStefano Zampini Not collective 104674ae819SStefano Zampini 105674ae819SStefano Zampini Input Parameters: 106674ae819SStefano Zampini + pc - the preconditioning context 10728509bceSStefano Zampini - PrimalVertices - index set of primal vertices in local numbering 108674ae819SStefano Zampini 109674ae819SStefano Zampini Level: intermediate 110674ae819SStefano Zampini 111674ae819SStefano Zampini Notes: 112674ae819SStefano Zampini 113674ae819SStefano Zampini .seealso: PCBDDC 114674ae819SStefano Zampini @*/ 115674ae819SStefano Zampini PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PC pc, IS PrimalVertices) 116674ae819SStefano Zampini { 117674ae819SStefano Zampini PetscErrorCode ierr; 118674ae819SStefano Zampini 119674ae819SStefano Zampini PetscFunctionBegin; 120674ae819SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 121674ae819SStefano Zampini PetscValidHeaderSpecific(PrimalVertices,IS_CLASSID,2); 122674ae819SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetPrimalVerticesLocalIS_C",(PC,IS),(pc,PrimalVertices));CHKERRQ(ierr); 123674ae819SStefano Zampini PetscFunctionReturn(0); 124674ae819SStefano Zampini } 125674ae819SStefano Zampini /* -------------------------------------------------------------------------- */ 1260c7d97c5SJed Brown #undef __FUNCT__ 1274fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio_BDDC" 1284fad6a16SStefano Zampini static PetscErrorCode PCBDDCSetCoarseningRatio_BDDC(PC pc,PetscInt k) 1294fad6a16SStefano Zampini { 1304fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1314fad6a16SStefano Zampini 1324fad6a16SStefano Zampini PetscFunctionBegin; 1334fad6a16SStefano Zampini pcbddc->coarsening_ratio = k; 1344fad6a16SStefano Zampini PetscFunctionReturn(0); 1354fad6a16SStefano Zampini } 1361e6b0712SBarry Smith 1374fad6a16SStefano Zampini #undef __FUNCT__ 1384fad6a16SStefano Zampini #define __FUNCT__ "PCBDDCSetCoarseningRatio" 1394fad6a16SStefano Zampini /*@ 14028509bceSStefano Zampini PCBDDCSetCoarseningRatio - Set coarsening ratio used in multilevel 1414fad6a16SStefano Zampini 1424fad6a16SStefano Zampini Logically collective on PC 1434fad6a16SStefano Zampini 1444fad6a16SStefano Zampini Input Parameters: 1454fad6a16SStefano Zampini + pc - the preconditioning context 14628509bceSStefano Zampini - k - coarsening ratio (H/h at the coarser level) 1474fad6a16SStefano Zampini 14828509bceSStefano Zampini Approximatively k subdomains at the finer level will be aggregated into a single subdomain at the coarser level 1494fad6a16SStefano Zampini 1504fad6a16SStefano Zampini Level: intermediate 1514fad6a16SStefano Zampini 1524fad6a16SStefano Zampini Notes: 1534fad6a16SStefano Zampini 1544fad6a16SStefano Zampini .seealso: PCBDDC 1554fad6a16SStefano Zampini @*/ 1564fad6a16SStefano Zampini PetscErrorCode PCBDDCSetCoarseningRatio(PC pc,PetscInt k) 1574fad6a16SStefano Zampini { 1584fad6a16SStefano Zampini PetscErrorCode ierr; 1594fad6a16SStefano Zampini 1604fad6a16SStefano Zampini PetscFunctionBegin; 1614fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1622b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,k,2); 1634fad6a16SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetCoarseningRatio_C",(PC,PetscInt),(pc,k));CHKERRQ(ierr); 1644fad6a16SStefano Zampini PetscFunctionReturn(0); 1654fad6a16SStefano Zampini } 1662b510759SStefano Zampini 167b8ffe317SStefano Zampini /* The following functions (PCBDDCSetUseExactDirichlet PCBDDCSetLevel) are not public */ 1682b510759SStefano Zampini #undef __FUNCT__ 169b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet_BDDC" 170b8ffe317SStefano Zampini static PetscErrorCode PCBDDCSetUseExactDirichlet_BDDC(PC pc,PetscBool flg) 171b8ffe317SStefano Zampini { 172b8ffe317SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 173b8ffe317SStefano Zampini 174b8ffe317SStefano Zampini PetscFunctionBegin; 17585c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = flg; 176b8ffe317SStefano Zampini PetscFunctionReturn(0); 177b8ffe317SStefano Zampini } 178b8ffe317SStefano Zampini 179b8ffe317SStefano Zampini #undef __FUNCT__ 180b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetUseExactDirichlet" 181b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetUseExactDirichlet(PC pc,PetscBool flg) 1822b510759SStefano Zampini { 1832b510759SStefano Zampini PetscErrorCode ierr; 1842b510759SStefano Zampini 1852b510759SStefano Zampini PetscFunctionBegin; 1862b510759SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 187b8ffe317SStefano Zampini PetscValidLogicalCollectiveBool(pc,flg,2); 188b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetUseExactDirichlet_C",(PC,PetscBool),(pc,flg));CHKERRQ(ierr); 1892b510759SStefano Zampini PetscFunctionReturn(0); 1902b510759SStefano Zampini } 1911e6b0712SBarry Smith 1924fad6a16SStefano Zampini #undef __FUNCT__ 1932b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel_BDDC" 1942b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevel_BDDC(PC pc,PetscInt level) 1954fad6a16SStefano Zampini { 1964fad6a16SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1974fad6a16SStefano Zampini 1984fad6a16SStefano Zampini PetscFunctionBegin; 1992b510759SStefano Zampini pcbddc->current_level = level; 2004fad6a16SStefano Zampini PetscFunctionReturn(0); 2014fad6a16SStefano Zampini } 2021e6b0712SBarry Smith 2034fad6a16SStefano Zampini #undef __FUNCT__ 204b8ffe317SStefano Zampini #define __FUNCT__ "PCBDDCSetLevel" 205b8ffe317SStefano Zampini PetscErrorCode PCBDDCSetLevel(PC pc,PetscInt level) 206b8ffe317SStefano Zampini { 207b8ffe317SStefano Zampini PetscErrorCode ierr; 208b8ffe317SStefano Zampini 209b8ffe317SStefano Zampini PetscFunctionBegin; 210b8ffe317SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 211b8ffe317SStefano Zampini PetscValidLogicalCollectiveInt(pc,level,2); 212b8ffe317SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevel_C",(PC,PetscInt),(pc,level));CHKERRQ(ierr); 213b8ffe317SStefano Zampini PetscFunctionReturn(0); 214b8ffe317SStefano Zampini } 215b8ffe317SStefano Zampini 216b8ffe317SStefano Zampini #undef __FUNCT__ 2172b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels_BDDC" 2182b510759SStefano Zampini static PetscErrorCode PCBDDCSetLevels_BDDC(PC pc,PetscInt levels) 2192b510759SStefano Zampini { 2202b510759SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2212b510759SStefano Zampini 2222b510759SStefano Zampini PetscFunctionBegin; 2232b510759SStefano Zampini pcbddc->max_levels = levels; 2242b510759SStefano Zampini PetscFunctionReturn(0); 2252b510759SStefano Zampini } 2262b510759SStefano Zampini 2272b510759SStefano Zampini #undef __FUNCT__ 2282b510759SStefano Zampini #define __FUNCT__ "PCBDDCSetLevels" 2294fad6a16SStefano Zampini /*@ 23028509bceSStefano Zampini PCBDDCSetLevels - Sets the maximum number of levels for multilevel 2314fad6a16SStefano Zampini 2324fad6a16SStefano Zampini Logically collective on PC 2334fad6a16SStefano Zampini 2344fad6a16SStefano Zampini Input Parameters: 2354fad6a16SStefano Zampini + pc - the preconditioning context 23628509bceSStefano Zampini - levels - the maximum number of levels (max 9) 2374fad6a16SStefano Zampini 23828509bceSStefano Zampini Default value is 0, i.e. traditional one-level BDDC 2394fad6a16SStefano Zampini 2404fad6a16SStefano Zampini Level: intermediate 2414fad6a16SStefano Zampini 2424fad6a16SStefano Zampini Notes: 2434fad6a16SStefano Zampini 2444fad6a16SStefano Zampini .seealso: PCBDDC 2454fad6a16SStefano Zampini @*/ 2462b510759SStefano Zampini PetscErrorCode PCBDDCSetLevels(PC pc,PetscInt levels) 2474fad6a16SStefano Zampini { 2484fad6a16SStefano Zampini PetscErrorCode ierr; 2494fad6a16SStefano Zampini 2504fad6a16SStefano Zampini PetscFunctionBegin; 2514fad6a16SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2522b510759SStefano Zampini PetscValidLogicalCollectiveInt(pc,levels,2); 2532b510759SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLevels_C",(PC,PetscInt),(pc,levels));CHKERRQ(ierr); 2544fad6a16SStefano Zampini PetscFunctionReturn(0); 2554fad6a16SStefano Zampini } 2564fad6a16SStefano Zampini /* -------------------------------------------------------------------------- */ 2571e6b0712SBarry Smith 2584fad6a16SStefano Zampini #undef __FUNCT__ 2590bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace_BDDC" 2600bdf917eSStefano Zampini static PetscErrorCode PCBDDCSetNullSpace_BDDC(PC pc,MatNullSpace NullSpace) 2610bdf917eSStefano Zampini { 2620bdf917eSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2630bdf917eSStefano Zampini PetscErrorCode ierr; 2640bdf917eSStefano Zampini 2650bdf917eSStefano Zampini PetscFunctionBegin; 2660bdf917eSStefano Zampini ierr = PetscObjectReference((PetscObject)NullSpace);CHKERRQ(ierr); 2670bdf917eSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->NullSpace);CHKERRQ(ierr); 2680bdf917eSStefano Zampini pcbddc->NullSpace = NullSpace; 2690bdf917eSStefano Zampini PetscFunctionReturn(0); 2700bdf917eSStefano Zampini } 2711e6b0712SBarry Smith 2720bdf917eSStefano Zampini #undef __FUNCT__ 2730bdf917eSStefano Zampini #define __FUNCT__ "PCBDDCSetNullSpace" 2740bdf917eSStefano Zampini /*@ 27528509bceSStefano Zampini PCBDDCSetNullSpace - Set nullspace for BDDC operator 2760bdf917eSStefano Zampini 2770bdf917eSStefano Zampini Logically collective on PC and MatNullSpace 2780bdf917eSStefano Zampini 2790bdf917eSStefano Zampini Input Parameters: 2800bdf917eSStefano Zampini + pc - the preconditioning context 28128509bceSStefano Zampini - NullSpace - Null space of the linear operator to be preconditioned (Pmat) 2820bdf917eSStefano Zampini 2830bdf917eSStefano Zampini Level: intermediate 2840bdf917eSStefano Zampini 2850bdf917eSStefano Zampini Notes: 2860bdf917eSStefano Zampini 2870bdf917eSStefano Zampini .seealso: PCBDDC 2880bdf917eSStefano Zampini @*/ 2890bdf917eSStefano Zampini PetscErrorCode PCBDDCSetNullSpace(PC pc,MatNullSpace NullSpace) 2900bdf917eSStefano Zampini { 2910bdf917eSStefano Zampini PetscErrorCode ierr; 2920bdf917eSStefano Zampini 2930bdf917eSStefano Zampini PetscFunctionBegin; 2940bdf917eSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 295674ae819SStefano Zampini PetscValidHeaderSpecific(NullSpace,MAT_NULLSPACE_CLASSID,2); 2962b510759SStefano Zampini PetscCheckSameComm(pc,1,NullSpace,2); 2970bdf917eSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNullSpace_C",(PC,MatNullSpace),(pc,NullSpace));CHKERRQ(ierr); 2980bdf917eSStefano Zampini PetscFunctionReturn(0); 2990bdf917eSStefano Zampini } 3000bdf917eSStefano Zampini /* -------------------------------------------------------------------------- */ 3011e6b0712SBarry Smith 3020bdf917eSStefano Zampini #undef __FUNCT__ 303785d1243SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries_BDDC" 304785d1243SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundaries_BDDC(PC pc,IS DirichletBoundaries) 305785d1243SStefano Zampini { 306785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 307785d1243SStefano Zampini PetscErrorCode ierr; 308785d1243SStefano Zampini 309785d1243SStefano Zampini PetscFunctionBegin; 310785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 311785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 312785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 313785d1243SStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 314785d1243SStefano Zampini pcbddc->DirichletBoundaries = DirichletBoundaries; 315785d1243SStefano Zampini PetscFunctionReturn(0); 316785d1243SStefano Zampini } 317785d1243SStefano Zampini 318785d1243SStefano Zampini #undef __FUNCT__ 319785d1243SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundaries" 320785d1243SStefano Zampini /*@ 321785d1243SStefano Zampini PCBDDCSetDirichletBoundaries - Set IS defining Dirichlet boundaries for the global problem. 322785d1243SStefano Zampini 323785d1243SStefano Zampini Collective 324785d1243SStefano Zampini 325785d1243SStefano Zampini Input Parameters: 326785d1243SStefano Zampini + pc - the preconditioning context 327785d1243SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries 328785d1243SStefano Zampini 329785d1243SStefano Zampini Level: intermediate 330785d1243SStefano Zampini 331785d1243SStefano Zampini Notes: Any process can list any global node 332785d1243SStefano Zampini 333785d1243SStefano Zampini .seealso: PCBDDC 334785d1243SStefano Zampini @*/ 335785d1243SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundaries(PC pc,IS DirichletBoundaries) 336785d1243SStefano Zampini { 337785d1243SStefano Zampini PetscErrorCode ierr; 338785d1243SStefano Zampini 339785d1243SStefano Zampini PetscFunctionBegin; 340785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 341785d1243SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 342785d1243SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 343785d1243SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundaries_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 344785d1243SStefano Zampini PetscFunctionReturn(0); 345785d1243SStefano Zampini } 346785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 347785d1243SStefano Zampini 348785d1243SStefano Zampini #undef __FUNCT__ 34982ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal_BDDC" 35082ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetDirichletBoundariesLocal_BDDC(PC pc,IS DirichletBoundaries) 3513b03a366Sstefano_zampini { 3523b03a366Sstefano_zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3533b03a366Sstefano_zampini PetscErrorCode ierr; 3543b03a366Sstefano_zampini 3553b03a366Sstefano_zampini PetscFunctionBegin; 356785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 357785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 3583b03a366Sstefano_zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 35936e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)DirichletBoundaries);CHKERRQ(ierr); 360785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = DirichletBoundaries; 3613b03a366Sstefano_zampini PetscFunctionReturn(0); 3623b03a366Sstefano_zampini } 3631e6b0712SBarry Smith 3643b03a366Sstefano_zampini #undef __FUNCT__ 36582ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetDirichletBoundariesLocal" 3663b03a366Sstefano_zampini /*@ 36782ba6b80SStefano Zampini PCBDDCSetDirichletBoundariesLocal - Set IS defining Dirichlet boundaries for the global problem in local ordering. 3683b03a366Sstefano_zampini 369785d1243SStefano Zampini Collective 3703b03a366Sstefano_zampini 3713b03a366Sstefano_zampini Input Parameters: 3723b03a366Sstefano_zampini + pc - the preconditioning context 37382ba6b80SStefano Zampini - DirichletBoundaries - parallel IS defining the Dirichlet boundaries (in local ordering) 3743b03a366Sstefano_zampini 3753b03a366Sstefano_zampini Level: intermediate 3763b03a366Sstefano_zampini 3773b03a366Sstefano_zampini Notes: 3783b03a366Sstefano_zampini 3793b03a366Sstefano_zampini .seealso: PCBDDC 3803b03a366Sstefano_zampini @*/ 38182ba6b80SStefano Zampini PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PC pc,IS DirichletBoundaries) 3823b03a366Sstefano_zampini { 3833b03a366Sstefano_zampini PetscErrorCode ierr; 3843b03a366Sstefano_zampini 3853b03a366Sstefano_zampini PetscFunctionBegin; 3863b03a366Sstefano_zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 387674ae819SStefano Zampini PetscValidHeaderSpecific(DirichletBoundaries,IS_CLASSID,2); 38882ba6b80SStefano Zampini PetscCheckSameComm(pc,1,DirichletBoundaries,2); 38982ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDirichletBoundariesLocal_C",(PC,IS),(pc,DirichletBoundaries));CHKERRQ(ierr); 3903b03a366Sstefano_zampini PetscFunctionReturn(0); 3913b03a366Sstefano_zampini } 3923b03a366Sstefano_zampini /* -------------------------------------------------------------------------- */ 3931e6b0712SBarry Smith 3943b03a366Sstefano_zampini #undef __FUNCT__ 395785d1243SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 396785d1243SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 397785d1243SStefano Zampini { 398785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 399785d1243SStefano Zampini PetscErrorCode ierr; 400785d1243SStefano Zampini 401785d1243SStefano Zampini PetscFunctionBegin; 402785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 403785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 404785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 405785d1243SStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 406785d1243SStefano Zampini pcbddc->NeumannBoundaries = NeumannBoundaries; 407785d1243SStefano Zampini PetscFunctionReturn(0); 408785d1243SStefano Zampini } 409785d1243SStefano Zampini 410785d1243SStefano Zampini #undef __FUNCT__ 411785d1243SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 412785d1243SStefano Zampini /*@ 413785d1243SStefano Zampini PCBDDCSetNeumannBoundaries - Set IS defining Neumann boundaries for the global problem. 414785d1243SStefano Zampini 415785d1243SStefano Zampini Collective 416785d1243SStefano Zampini 417785d1243SStefano Zampini Input Parameters: 418785d1243SStefano Zampini + pc - the preconditioning context 419785d1243SStefano Zampini - NeumannBoundaries - parallel IS defining the Neumann boundaries 420785d1243SStefano Zampini 421785d1243SStefano Zampini Level: intermediate 422785d1243SStefano Zampini 423785d1243SStefano Zampini Notes: Any process can list any global node 424785d1243SStefano Zampini 425785d1243SStefano Zampini .seealso: PCBDDC 426785d1243SStefano Zampini @*/ 427785d1243SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 428785d1243SStefano Zampini { 429785d1243SStefano Zampini PetscErrorCode ierr; 430785d1243SStefano Zampini 431785d1243SStefano Zampini PetscFunctionBegin; 432785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 433785d1243SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 434785d1243SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 435785d1243SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 436785d1243SStefano Zampini PetscFunctionReturn(0); 437785d1243SStefano Zampini } 438785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 439785d1243SStefano Zampini 440785d1243SStefano Zampini #undef __FUNCT__ 44182ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal_BDDC" 44282ba6b80SStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundariesLocal_BDDC(PC pc,IS NeumannBoundaries) 4430c7d97c5SJed Brown { 4440c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 44553cdbc3dSStefano Zampini PetscErrorCode ierr; 4460c7d97c5SJed Brown 4470c7d97c5SJed Brown PetscFunctionBegin; 448785d1243SStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 449785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 45053cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 45136e030ebSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 452785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = NeumannBoundaries; 4530c7d97c5SJed Brown PetscFunctionReturn(0); 4540c7d97c5SJed Brown } 4551e6b0712SBarry Smith 4560c7d97c5SJed Brown #undef __FUNCT__ 45782ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCSetNeumannBoundariesLocal" 45857527edcSJed Brown /*@ 45982ba6b80SStefano Zampini PCBDDCSetNeumannBoundariesLocal - Set IS defining Neumann boundaries for the global problem in local ordering. 46057527edcSJed Brown 461785d1243SStefano Zampini Collective 46257527edcSJed Brown 46357527edcSJed Brown Input Parameters: 46457527edcSJed Brown + pc - the preconditioning context 46582ba6b80SStefano Zampini - NeumannBoundaries - parallel IS defining the subdomain part of Neumann boundaries (in local ordering) 46657527edcSJed Brown 46757527edcSJed Brown Level: intermediate 46857527edcSJed Brown 46957527edcSJed Brown Notes: 47057527edcSJed Brown 47157527edcSJed Brown .seealso: PCBDDC 47257527edcSJed Brown @*/ 47382ba6b80SStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PC pc,IS NeumannBoundaries) 4740c7d97c5SJed Brown { 4750c7d97c5SJed Brown PetscErrorCode ierr; 4760c7d97c5SJed Brown 4770c7d97c5SJed Brown PetscFunctionBegin; 4780c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 479674ae819SStefano Zampini PetscValidHeaderSpecific(NeumannBoundaries,IS_CLASSID,2); 48082ba6b80SStefano Zampini PetscCheckSameComm(pc,1,NeumannBoundaries,2); 48182ba6b80SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundariesLocal_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 48253cdbc3dSStefano Zampini PetscFunctionReturn(0); 48353cdbc3dSStefano Zampini } 48453cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 4851e6b0712SBarry Smith 48653cdbc3dSStefano Zampini #undef __FUNCT__ 487785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries_BDDC" 488785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundaries_BDDC(PC pc,IS *DirichletBoundaries) 489da1bb401SStefano Zampini { 490da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 491da1bb401SStefano Zampini 492da1bb401SStefano Zampini PetscFunctionBegin; 493da1bb401SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundaries; 494da1bb401SStefano Zampini PetscFunctionReturn(0); 495da1bb401SStefano Zampini } 4961e6b0712SBarry Smith 497da1bb401SStefano Zampini #undef __FUNCT__ 498785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundaries" 499785d1243SStefano Zampini /*@ 500785d1243SStefano Zampini PCBDDCGetDirichletBoundaries - Get parallel IS for Dirichlet boundaries 501785d1243SStefano Zampini 502785d1243SStefano Zampini Collective 503785d1243SStefano Zampini 504785d1243SStefano Zampini Input Parameters: 505785d1243SStefano Zampini . pc - the preconditioning context 506785d1243SStefano Zampini 507785d1243SStefano Zampini Output Parameters: 508785d1243SStefano Zampini . DirichletBoundaries - index set defining the Dirichlet boundaries 509785d1243SStefano Zampini 510785d1243SStefano Zampini Level: intermediate 511785d1243SStefano Zampini 512785d1243SStefano Zampini Notes: The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetDirichletBoundaries 513785d1243SStefano Zampini 514785d1243SStefano Zampini .seealso: PCBDDC 515785d1243SStefano Zampini @*/ 516785d1243SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundaries(PC pc,IS *DirichletBoundaries) 517785d1243SStefano Zampini { 518785d1243SStefano Zampini PetscErrorCode ierr; 519785d1243SStefano Zampini 520785d1243SStefano Zampini PetscFunctionBegin; 521785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 522785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundaries_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 523785d1243SStefano Zampini PetscFunctionReturn(0); 524785d1243SStefano Zampini } 525785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 526785d1243SStefano Zampini 527785d1243SStefano Zampini #undef __FUNCT__ 528785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal_BDDC" 529785d1243SStefano Zampini static PetscErrorCode PCBDDCGetDirichletBoundariesLocal_BDDC(PC pc,IS *DirichletBoundaries) 530785d1243SStefano Zampini { 531785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 532785d1243SStefano Zampini 533785d1243SStefano Zampini PetscFunctionBegin; 534785d1243SStefano Zampini *DirichletBoundaries = pcbddc->DirichletBoundariesLocal; 535785d1243SStefano Zampini PetscFunctionReturn(0); 536785d1243SStefano Zampini } 537785d1243SStefano Zampini 538785d1243SStefano Zampini #undef __FUNCT__ 53982ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetDirichletBoundariesLocal" 540da1bb401SStefano Zampini /*@ 54182ba6b80SStefano Zampini PCBDDCGetDirichletBoundariesLocal - Get parallel IS for Dirichlet boundaries (in local ordering) 542da1bb401SStefano Zampini 543785d1243SStefano Zampini Collective 544da1bb401SStefano Zampini 545da1bb401SStefano Zampini Input Parameters: 54628509bceSStefano Zampini . pc - the preconditioning context 547da1bb401SStefano Zampini 548da1bb401SStefano Zampini Output Parameters: 54928509bceSStefano Zampini . DirichletBoundaries - index set defining the subdomain part of Dirichlet boundaries 550da1bb401SStefano Zampini 551da1bb401SStefano Zampini Level: intermediate 552da1bb401SStefano Zampini 553da1bb401SStefano Zampini Notes: 554da1bb401SStefano Zampini 555da1bb401SStefano Zampini .seealso: PCBDDC 556da1bb401SStefano Zampini @*/ 55782ba6b80SStefano Zampini PetscErrorCode PCBDDCGetDirichletBoundariesLocal(PC pc,IS *DirichletBoundaries) 558da1bb401SStefano Zampini { 559da1bb401SStefano Zampini PetscErrorCode ierr; 560da1bb401SStefano Zampini 561da1bb401SStefano Zampini PetscFunctionBegin; 562da1bb401SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 56382ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetDirichletBoundariesLocal_C",(PC,IS*),(pc,DirichletBoundaries));CHKERRQ(ierr); 564da1bb401SStefano Zampini PetscFunctionReturn(0); 565da1bb401SStefano Zampini } 566da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 5671e6b0712SBarry Smith 568da1bb401SStefano Zampini #undef __FUNCT__ 569785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 570785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 57153cdbc3dSStefano Zampini { 57253cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 57353cdbc3dSStefano Zampini 57453cdbc3dSStefano Zampini PetscFunctionBegin; 57553cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 57653cdbc3dSStefano Zampini PetscFunctionReturn(0); 57753cdbc3dSStefano Zampini } 5781e6b0712SBarry Smith 57953cdbc3dSStefano Zampini #undef __FUNCT__ 580785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 581785d1243SStefano Zampini /*@ 582785d1243SStefano Zampini PCBDDCGetNeumannBoundaries - Get parallel IS for Neumann boundaries 583785d1243SStefano Zampini 584785d1243SStefano Zampini Collective 585785d1243SStefano Zampini 586785d1243SStefano Zampini Input Parameters: 587785d1243SStefano Zampini . pc - the preconditioning context 588785d1243SStefano Zampini 589785d1243SStefano Zampini Output Parameters: 590785d1243SStefano Zampini . NeumannBoundaries - index set defining the Neumann boundaries 591785d1243SStefano Zampini 592785d1243SStefano Zampini Level: intermediate 593785d1243SStefano Zampini 594785d1243SStefano Zampini Notes: The IS returned (if any) is the same passed in earlier by the user with PCBDDCSetNeumannBoundaries 595785d1243SStefano Zampini 596785d1243SStefano Zampini .seealso: PCBDDC 597785d1243SStefano Zampini @*/ 598785d1243SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 599785d1243SStefano Zampini { 600785d1243SStefano Zampini PetscErrorCode ierr; 601785d1243SStefano Zampini 602785d1243SStefano Zampini PetscFunctionBegin; 603785d1243SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 604785d1243SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 605785d1243SStefano Zampini PetscFunctionReturn(0); 606785d1243SStefano Zampini } 607785d1243SStefano Zampini /* -------------------------------------------------------------------------- */ 608785d1243SStefano Zampini 609785d1243SStefano Zampini #undef __FUNCT__ 610785d1243SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal_BDDC" 611785d1243SStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundariesLocal_BDDC(PC pc,IS *NeumannBoundaries) 612785d1243SStefano Zampini { 613785d1243SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 614785d1243SStefano Zampini 615785d1243SStefano Zampini PetscFunctionBegin; 616785d1243SStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundariesLocal; 617785d1243SStefano Zampini PetscFunctionReturn(0); 618785d1243SStefano Zampini } 619785d1243SStefano Zampini 620785d1243SStefano Zampini #undef __FUNCT__ 62182ba6b80SStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundariesLocal" 62253cdbc3dSStefano Zampini /*@ 62382ba6b80SStefano Zampini PCBDDCGetNeumannBoundariesLocal - Get parallel IS for Neumann boundaries (in local ordering) 62453cdbc3dSStefano Zampini 625785d1243SStefano Zampini Collective 62653cdbc3dSStefano Zampini 62753cdbc3dSStefano Zampini Input Parameters: 62828509bceSStefano Zampini . pc - the preconditioning context 62953cdbc3dSStefano Zampini 63053cdbc3dSStefano Zampini Output Parameters: 63128509bceSStefano Zampini . NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 63253cdbc3dSStefano Zampini 63353cdbc3dSStefano Zampini Level: intermediate 63453cdbc3dSStefano Zampini 63553cdbc3dSStefano Zampini Notes: 63653cdbc3dSStefano Zampini 63753cdbc3dSStefano Zampini .seealso: PCBDDC 63853cdbc3dSStefano Zampini @*/ 63982ba6b80SStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundariesLocal(PC pc,IS *NeumannBoundaries) 64053cdbc3dSStefano Zampini { 64153cdbc3dSStefano Zampini PetscErrorCode ierr; 64253cdbc3dSStefano Zampini 64353cdbc3dSStefano Zampini PetscFunctionBegin; 64453cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 64582ba6b80SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundariesLocal_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 6460c7d97c5SJed Brown PetscFunctionReturn(0); 6470c7d97c5SJed Brown } 64836e030ebSStefano Zampini /* -------------------------------------------------------------------------- */ 6491e6b0712SBarry Smith 65036e030ebSStefano Zampini #undef __FUNCT__ 651da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph_BDDC" 6521a83f524SJed Brown static PetscErrorCode PCBDDCSetLocalAdjacencyGraph_BDDC(PC pc, PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 65336e030ebSStefano Zampini { 65436e030ebSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 655da1bb401SStefano Zampini PCBDDCGraph mat_graph = pcbddc->mat_graph; 656da1bb401SStefano Zampini PetscErrorCode ierr; 65736e030ebSStefano Zampini 65836e030ebSStefano Zampini PetscFunctionBegin; 659674ae819SStefano Zampini /* free old CSR */ 660674ae819SStefano Zampini ierr = PCBDDCGraphResetCSR(mat_graph);CHKERRQ(ierr); 661fb223d50SStefano Zampini /* TODO: PCBDDCGraphSetAdjacency */ 662674ae819SStefano Zampini /* get CSR into graph structure */ 663da1bb401SStefano Zampini if (copymode == PETSC_COPY_VALUES) { 664674ae819SStefano Zampini ierr = PetscMalloc((nvtxs+1)*sizeof(PetscInt),&mat_graph->xadj);CHKERRQ(ierr); 665674ae819SStefano Zampini ierr = PetscMalloc(xadj[nvtxs]*sizeof(PetscInt),&mat_graph->adjncy);CHKERRQ(ierr); 666674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->xadj,xadj,(nvtxs+1)*sizeof(PetscInt));CHKERRQ(ierr); 667674ae819SStefano Zampini ierr = PetscMemcpy(mat_graph->adjncy,adjncy,xadj[nvtxs]*sizeof(PetscInt));CHKERRQ(ierr); 668da1bb401SStefano Zampini } else if (copymode == PETSC_OWN_POINTER) { 6691a83f524SJed Brown mat_graph->xadj = (PetscInt*)xadj; 6701a83f524SJed Brown mat_graph->adjncy = (PetscInt*)adjncy; 671674ae819SStefano Zampini } 672575ad6abSStefano Zampini mat_graph->nvtxs_csr = nvtxs; 67336e030ebSStefano Zampini PetscFunctionReturn(0); 67436e030ebSStefano Zampini } 6751e6b0712SBarry Smith 67636e030ebSStefano Zampini #undef __FUNCT__ 677da1bb401SStefano Zampini #define __FUNCT__ "PCBDDCSetLocalAdjacencyGraph" 67836e030ebSStefano Zampini /*@ 67928509bceSStefano Zampini PCBDDCSetLocalAdjacencyGraph - Set adjacency structure (CSR graph) of the local Neumann matrix 68036e030ebSStefano Zampini 68136e030ebSStefano Zampini Not collective 68236e030ebSStefano Zampini 68336e030ebSStefano Zampini Input Parameters: 68436e030ebSStefano Zampini + pc - the preconditioning context 68528509bceSStefano Zampini . nvtxs - number of local vertices of the graph (i.e., the local size of your problem) 68628509bceSStefano Zampini . xadj, adjncy - the CSR graph 68728509bceSStefano Zampini - copymode - either PETSC_COPY_VALUES or PETSC_OWN_POINTER. 68836e030ebSStefano Zampini 68936e030ebSStefano Zampini Level: intermediate 69036e030ebSStefano Zampini 69136e030ebSStefano Zampini Notes: 69236e030ebSStefano Zampini 69328509bceSStefano Zampini .seealso: PCBDDC,PetscCopyMode 69436e030ebSStefano Zampini @*/ 6951a83f524SJed Brown PetscErrorCode PCBDDCSetLocalAdjacencyGraph(PC pc,PetscInt nvtxs,const PetscInt xadj[],const PetscInt adjncy[], PetscCopyMode copymode) 69636e030ebSStefano Zampini { 697575ad6abSStefano Zampini void (*f)(void) = 0; 69836e030ebSStefano Zampini PetscErrorCode ierr; 69936e030ebSStefano Zampini 70036e030ebSStefano Zampini PetscFunctionBegin; 70136e030ebSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 702674ae819SStefano Zampini PetscValidIntPointer(xadj,3); 703674ae819SStefano Zampini PetscValidIntPointer(xadj,4); 704674ae819SStefano Zampini if (copymode != PETSC_COPY_VALUES && copymode != PETSC_OWN_POINTER) { 705674ae819SStefano Zampini SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported copy mode %d in %s\n",copymode,__FUNCT__); 706da1bb401SStefano Zampini } 70736e030ebSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetLocalAdjacencyGraph_C",(PC,PetscInt,const PetscInt[],const PetscInt[],PetscCopyMode),(pc,nvtxs,xadj,adjncy,copymode));CHKERRQ(ierr); 708575ad6abSStefano Zampini /* free arrays if PCBDDC is not the PC type */ 709575ad6abSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",&f);CHKERRQ(ierr); 710575ad6abSStefano Zampini if (!f && copymode == PETSC_OWN_POINTER) { 711575ad6abSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 712575ad6abSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 71336e030ebSStefano Zampini } 71436e030ebSStefano Zampini PetscFunctionReturn(0); 71536e030ebSStefano Zampini } 7169c0446d6SStefano Zampini /* -------------------------------------------------------------------------- */ 7171e6b0712SBarry Smith 7189c0446d6SStefano Zampini #undef __FUNCT__ 719*63602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal_BDDC" 720*63602bcaSStefano Zampini static PetscErrorCode PCBDDCSetDofsSplittingLocal_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 721*63602bcaSStefano Zampini { 722*63602bcaSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 723*63602bcaSStefano Zampini PetscInt i; 724*63602bcaSStefano Zampini PetscErrorCode ierr; 725*63602bcaSStefano Zampini 726*63602bcaSStefano Zampini PetscFunctionBegin; 727*63602bcaSStefano Zampini /* Destroy ISes if they were already set */ 728*63602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 729*63602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 730*63602bcaSStefano Zampini } 731*63602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 732*63602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 733*63602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 734*63602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 735*63602bcaSStefano Zampini } 736*63602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 737*63602bcaSStefano Zampini pcbddc->n_ISForDofs = 0; 738*63602bcaSStefano Zampini /* allocate space then set */ 739*63602bcaSStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 740*63602bcaSStefano Zampini for (i=0;i<n_is;i++) { 741*63602bcaSStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 742*63602bcaSStefano Zampini pcbddc->ISForDofsLocal[i]=ISForDofs[i]; 743*63602bcaSStefano Zampini } 744*63602bcaSStefano Zampini pcbddc->n_ISForDofsLocal=n_is; 745*63602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 746*63602bcaSStefano Zampini PetscFunctionReturn(0); 747*63602bcaSStefano Zampini } 748*63602bcaSStefano Zampini 749*63602bcaSStefano Zampini #undef __FUNCT__ 750*63602bcaSStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplittingLocal" 751*63602bcaSStefano Zampini /*@ 752*63602bcaSStefano Zampini PCBDDCSetDofsSplittingLocal - Set index sets defining fields of the local subdomain matrix 753*63602bcaSStefano Zampini 754*63602bcaSStefano Zampini Collective 755*63602bcaSStefano Zampini 756*63602bcaSStefano Zampini Input Parameters: 757*63602bcaSStefano Zampini + pc - the preconditioning context 758*63602bcaSStefano Zampini - n_is - number of index sets defining the fields 759*63602bcaSStefano Zampini . ISForDofs - array of IS describing the fields in local ordering 760*63602bcaSStefano Zampini 761*63602bcaSStefano Zampini Level: intermediate 762*63602bcaSStefano Zampini 763*63602bcaSStefano Zampini Notes: n_is should be the same among processes. Not all nodes need to be listed: unlisted nodes will belong to a different field. 764*63602bcaSStefano Zampini 765*63602bcaSStefano Zampini .seealso: PCBDDC 766*63602bcaSStefano Zampini @*/ 767*63602bcaSStefano Zampini PetscErrorCode PCBDDCSetDofsSplittingLocal(PC pc,PetscInt n_is, IS ISForDofs[]) 768*63602bcaSStefano Zampini { 769*63602bcaSStefano Zampini PetscInt i; 770*63602bcaSStefano Zampini PetscErrorCode ierr; 771*63602bcaSStefano Zampini 772*63602bcaSStefano Zampini PetscFunctionBegin; 773*63602bcaSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 774*63602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 775*63602bcaSStefano Zampini for (i=0;i<n_is;i++) { 776*63602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 777*63602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 778*63602bcaSStefano Zampini } 779*63602bcaSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 780*63602bcaSStefano Zampini PetscFunctionReturn(0); 781*63602bcaSStefano Zampini } 782*63602bcaSStefano Zampini /* -------------------------------------------------------------------------- */ 783*63602bcaSStefano Zampini 784*63602bcaSStefano Zampini #undef __FUNCT__ 7859c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting_BDDC" 7869c0446d6SStefano Zampini static PetscErrorCode PCBDDCSetDofsSplitting_BDDC(PC pc,PetscInt n_is, IS ISForDofs[]) 7879c0446d6SStefano Zampini { 7889c0446d6SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7899c0446d6SStefano Zampini PetscInt i; 7909c0446d6SStefano Zampini PetscErrorCode ierr; 7919c0446d6SStefano Zampini 7929c0446d6SStefano Zampini PetscFunctionBegin; 793da1bb401SStefano Zampini /* Destroy ISes if they were already set */ 7949c0446d6SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 7959c0446d6SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 7969c0446d6SStefano Zampini } 797d11ae9bbSstefano_zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 798*63602bcaSStefano Zampini /* last user setting takes precendence -> destroy any other customization */ 799*63602bcaSStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 800*63602bcaSStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 801*63602bcaSStefano Zampini } 802*63602bcaSStefano Zampini ierr = PetscFree(pcbddc->ISForDofsLocal);CHKERRQ(ierr); 803*63602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 804da1bb401SStefano Zampini /* allocate space then set */ 8059c0446d6SStefano Zampini ierr = PetscMalloc(n_is*sizeof(IS),&pcbddc->ISForDofs);CHKERRQ(ierr); 8069c0446d6SStefano Zampini for (i=0;i<n_is;i++) { 807da1bb401SStefano Zampini ierr = PetscObjectReference((PetscObject)ISForDofs[i]);CHKERRQ(ierr); 808da1bb401SStefano Zampini pcbddc->ISForDofs[i]=ISForDofs[i]; 8099c0446d6SStefano Zampini } 8109c0446d6SStefano Zampini pcbddc->n_ISForDofs=n_is; 811*63602bcaSStefano Zampini if (n_is) pcbddc->user_provided_isfordofs = PETSC_TRUE; 8129c0446d6SStefano Zampini PetscFunctionReturn(0); 8139c0446d6SStefano Zampini } 8141e6b0712SBarry Smith 8159c0446d6SStefano Zampini #undef __FUNCT__ 8169c0446d6SStefano Zampini #define __FUNCT__ "PCBDDCSetDofsSplitting" 8179c0446d6SStefano Zampini /*@ 818*63602bcaSStefano Zampini PCBDDCSetDofsSplitting - Set index sets defining fields of the global matrix 8199c0446d6SStefano Zampini 820*63602bcaSStefano Zampini Collective 8219c0446d6SStefano Zampini 8229c0446d6SStefano Zampini Input Parameters: 8239c0446d6SStefano Zampini + pc - the preconditioning context 82428509bceSStefano Zampini - n_is - number of index sets defining the fields 825*63602bcaSStefano Zampini . ISForDofs - array of IS describing the fields in global ordering 8269c0446d6SStefano Zampini 8279c0446d6SStefano Zampini Level: intermediate 8289c0446d6SStefano Zampini 829*63602bcaSStefano Zampini Notes: Any process can list any global node. Not all nodes need to be listed: unlisted nodes will belong to a different field. 8309c0446d6SStefano Zampini 8319c0446d6SStefano Zampini .seealso: PCBDDC 8329c0446d6SStefano Zampini @*/ 8339c0446d6SStefano Zampini PetscErrorCode PCBDDCSetDofsSplitting(PC pc,PetscInt n_is, IS ISForDofs[]) 8349c0446d6SStefano Zampini { 8352b510759SStefano Zampini PetscInt i; 8369c0446d6SStefano Zampini PetscErrorCode ierr; 8379c0446d6SStefano Zampini 8389c0446d6SStefano Zampini PetscFunctionBegin; 8399c0446d6SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 840*63602bcaSStefano Zampini PetscValidLogicalCollectiveInt(pc,n_is,2); 8412b510759SStefano Zampini for (i=0;i<n_is;i++) { 842*63602bcaSStefano Zampini PetscCheckSameComm(pc,1,ISForDofs[i],3); 843*63602bcaSStefano Zampini PetscValidHeaderSpecific(ISForDofs[i],IS_CLASSID,3); 8442b510759SStefano Zampini } 8459c0446d6SStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetDofsSplitting_C",(PC,PetscInt,IS[]),(pc,n_is,ISForDofs));CHKERRQ(ierr); 8469c0446d6SStefano Zampini PetscFunctionReturn(0); 8479c0446d6SStefano Zampini } 848da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 849534831adSStefano Zampini #undef __FUNCT__ 850534831adSStefano Zampini #define __FUNCT__ "PCPreSolve_BDDC" 851534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 852534831adSStefano Zampini /* 853534831adSStefano Zampini PCPreSolve_BDDC - Changes the right hand side and (if necessary) the initial 854534831adSStefano Zampini guess if a transformation of basis approach has been selected. 8559c0446d6SStefano Zampini 856534831adSStefano Zampini Input Parameter: 857534831adSStefano Zampini + pc - the preconditioner contex 858534831adSStefano Zampini 859534831adSStefano Zampini Application Interface Routine: PCPreSolve() 860534831adSStefano Zampini 861534831adSStefano Zampini Notes: 862534831adSStefano Zampini The interface routine PCPreSolve() is not usually called directly by 863534831adSStefano Zampini the user, but instead is called by KSPSolve(). 864534831adSStefano Zampini */ 865534831adSStefano Zampini static PetscErrorCode PCPreSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 866534831adSStefano Zampini { 867534831adSStefano Zampini PetscErrorCode ierr; 868534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 869534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 870534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 871534831adSStefano Zampini Mat temp_mat; 8723972b0daSStefano Zampini IS dirIS; 8733972b0daSStefano Zampini Vec used_vec; 87482ba6b80SStefano Zampini PetscBool guess_nonzero; 875534831adSStefano Zampini 876534831adSStefano Zampini PetscFunctionBegin; 87785c4d303SStefano Zampini /* if we are working with cg, one dirichlet solve can be avoided during Krylov iterations */ 87885c4d303SStefano Zampini if (ksp) { 87985c4d303SStefano Zampini PetscBool iscg; 88085c4d303SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)ksp,KSPCG,&iscg);CHKERRQ(ierr); 88185c4d303SStefano Zampini if (!iscg) { 88285c4d303SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 88385c4d303SStefano Zampini } 88485c4d303SStefano Zampini } 88585c4d303SStefano Zampini /* Creates parallel work vectors used in presolve */ 88662a6ff1dSStefano Zampini if (!pcbddc->original_rhs) { 88762a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->original_rhs);CHKERRQ(ierr); 88862a6ff1dSStefano Zampini } 88962a6ff1dSStefano Zampini if (!pcbddc->temp_solution) { 89062a6ff1dSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->temp_solution);CHKERRQ(ierr); 89162a6ff1dSStefano Zampini } 8923972b0daSStefano Zampini if (x) { 8933972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 8943972b0daSStefano Zampini used_vec = x; 8953972b0daSStefano Zampini } else { 8963972b0daSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->temp_solution);CHKERRQ(ierr); 8973972b0daSStefano Zampini used_vec = pcbddc->temp_solution; 8983972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 8993972b0daSStefano Zampini } 9003972b0daSStefano Zampini /* hack into ksp data structure PCPreSolve comes earlier in src/ksp/ksp/interface/itfunc.c */ 9013972b0daSStefano Zampini if (ksp) { 9023972b0daSStefano Zampini ierr = KSPGetInitialGuessNonzero(ksp,&guess_nonzero);CHKERRQ(ierr); 9033972b0daSStefano Zampini if (!guess_nonzero) { 9043972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 9053972b0daSStefano Zampini } 9063972b0daSStefano Zampini } 9073308cffdSStefano Zampini 9083972b0daSStefano Zampini /* store the original rhs */ 9093972b0daSStefano Zampini ierr = VecCopy(rhs,pcbddc->original_rhs);CHKERRQ(ierr); 9103972b0daSStefano Zampini 9113972b0daSStefano Zampini /* Take into account zeroed rows -> change rhs and store solution removed */ 912785d1243SStefano Zampini /* note that Dirichlet boundaries in global ordering (if any) has already been translated into local ordering in PCBDDCAnalyzeInterface */ 91382ba6b80SStefano Zampini ierr = PCBDDCGetDirichletBoundariesLocal(pc,&dirIS);CHKERRQ(ierr); 91482ba6b80SStefano Zampini if (rhs && dirIS) { 915785d1243SStefano Zampini PetscInt dirsize,i,*is_indices; 916785d1243SStefano Zampini PetscScalar *array_x,*array_diagonal; 917785d1243SStefano Zampini 9183972b0daSStefano Zampini ierr = MatGetDiagonal(pc->pmat,pcis->vec1_global);CHKERRQ(ierr); 9193972b0daSStefano Zampini ierr = VecPointwiseDivide(pcis->vec1_global,rhs,pcis->vec1_global);CHKERRQ(ierr); 9203972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9213972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9223972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 9233972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,used_vec,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 92482ba6b80SStefano Zampini ierr = ISGetLocalSize(dirIS,&dirsize);CHKERRQ(ierr); 9253972b0daSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 9263972b0daSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 9273972b0daSStefano Zampini ierr = ISGetIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 9282fa5cd67SKarl Rupp for (i=0; i<dirsize; i++) array_x[is_indices[i]] = array_diagonal[is_indices[i]]; 9293972b0daSStefano Zampini ierr = ISRestoreIndices(dirIS,(const PetscInt**)&is_indices);CHKERRQ(ierr); 9303972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array_diagonal);CHKERRQ(ierr); 9313972b0daSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array_x);CHKERRQ(ierr); 9323972b0daSStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 9333972b0daSStefano Zampini ierr = VecScatterEnd(matis->ctx,pcis->vec1_N,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 934b76ba322SStefano Zampini 9353972b0daSStefano Zampini /* remove the computed solution from the rhs */ 9363972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 9373972b0daSStefano Zampini ierr = MatMultAdd(pc->pmat,used_vec,rhs,rhs);CHKERRQ(ierr); 9383972b0daSStefano Zampini ierr = VecScale(used_vec,-1.0);CHKERRQ(ierr); 9393308cffdSStefano Zampini } 940b76ba322SStefano Zampini 941b76ba322SStefano Zampini /* store partially computed solution and set initial guess */ 9423972b0daSStefano Zampini if (x) { 9433972b0daSStefano Zampini ierr = VecCopy(used_vec,pcbddc->temp_solution);CHKERRQ(ierr); 9443972b0daSStefano Zampini ierr = VecSet(used_vec,0.0);CHKERRQ(ierr); 94585c4d303SStefano Zampini if (pcbddc->use_exact_dirichlet_trick) { 946b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 947b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,rhs,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 948b76ba322SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 949b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 950b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,used_vec,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 951b76ba322SStefano Zampini if (ksp) { 952b76ba322SStefano Zampini ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); 953b76ba322SStefano Zampini } 954b76ba322SStefano Zampini } 9553972b0daSStefano Zampini } 956b76ba322SStefano Zampini 95792e3dcfbSStefano Zampini /* prepare MatMult and rhs for solver */ 958674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 959b76ba322SStefano Zampini /* swap pointers for local matrices */ 960b76ba322SStefano Zampini temp_mat = matis->A; 961b76ba322SStefano Zampini matis->A = pcbddc->local_mat; 962b76ba322SStefano Zampini pcbddc->local_mat = temp_mat; 96392e3dcfbSStefano Zampini if (rhs) { 964b76ba322SStefano Zampini /* Get local rhs and apply transformation of basis */ 965b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 966b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,rhs,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 967b76ba322SStefano Zampini /* from original basis to modified basis */ 968b76ba322SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 969b76ba322SStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 970b76ba322SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 971b76ba322SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,rhs,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 972674ae819SStefano Zampini } 97392e3dcfbSStefano Zampini } 97492e3dcfbSStefano Zampini 97592e3dcfbSStefano Zampini /* remove nullspace if present */ 9760bdf917eSStefano Zampini if (ksp && pcbddc->NullSpace) { 977d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,used_vec);CHKERRQ(ierr); 978d0195637SJed Brown ierr = MatNullSpaceRemove(pcbddc->NullSpace,rhs);CHKERRQ(ierr); 979b76ba322SStefano Zampini } 9800bdf917eSStefano Zampini ierr = VecDestroy(&used_vec);CHKERRQ(ierr); 981534831adSStefano Zampini PetscFunctionReturn(0); 982534831adSStefano Zampini } 983534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 984534831adSStefano Zampini #undef __FUNCT__ 985534831adSStefano Zampini #define __FUNCT__ "PCPostSolve_BDDC" 986534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 987534831adSStefano Zampini /* 988534831adSStefano Zampini PCPostSolve_BDDC - Changes the computed solution if a transformation of basis 989534831adSStefano Zampini approach has been selected. Also, restores rhs to its original state. 990534831adSStefano Zampini 991534831adSStefano Zampini Input Parameter: 992534831adSStefano Zampini + pc - the preconditioner contex 993534831adSStefano Zampini 994534831adSStefano Zampini Application Interface Routine: PCPostSolve() 995534831adSStefano Zampini 996534831adSStefano Zampini Notes: 997534831adSStefano Zampini The interface routine PCPostSolve() is not usually called directly by 998534831adSStefano Zampini the user, but instead is called by KSPSolve(). 999534831adSStefano Zampini */ 1000534831adSStefano Zampini static PetscErrorCode PCPostSolve_BDDC(PC pc, KSP ksp, Vec rhs, Vec x) 1001534831adSStefano Zampini { 1002534831adSStefano Zampini PetscErrorCode ierr; 1003534831adSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1004534831adSStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 1005534831adSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1006534831adSStefano Zampini Mat temp_mat; 1007534831adSStefano Zampini 1008534831adSStefano Zampini PetscFunctionBegin; 1009674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 1010534831adSStefano Zampini /* swap pointers for local matrices */ 1011534831adSStefano Zampini temp_mat = matis->A; 1012534831adSStefano Zampini matis->A = pcbddc->local_mat; 1013534831adSStefano Zampini pcbddc->local_mat = temp_mat; 10143425bc38SStefano Zampini } 10153308cffdSStefano Zampini if (pcbddc->use_change_of_basis && x) { 1016534831adSStefano Zampini /* Get Local boundary and apply transformation of basis to solution vector */ 1017534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1018534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,x,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1019534831adSStefano Zampini /* from modified basis to original basis */ 1020534831adSStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 1021534831adSStefano Zampini /* put back modified values into the global vec using INSERT_VALUES copy mode */ 1022534831adSStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1023534831adSStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec2_B,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1024534831adSStefano Zampini } 10253972b0daSStefano Zampini /* add solution removed in presolve */ 10263425bc38SStefano Zampini if (x) { 10273425bc38SStefano Zampini ierr = VecAXPY(x,1.0,pcbddc->temp_solution);CHKERRQ(ierr); 10283425bc38SStefano Zampini } 1029fb223d50SStefano Zampini /* restore rhs to its original state */ 1030fb223d50SStefano Zampini if (rhs) { 1031fb223d50SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,rhs);CHKERRQ(ierr); 1032fb223d50SStefano Zampini } 1033534831adSStefano Zampini PetscFunctionReturn(0); 1034534831adSStefano Zampini } 1035534831adSStefano Zampini /* -------------------------------------------------------------------------- */ 103653cdbc3dSStefano Zampini #undef __FUNCT__ 103753cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 10380c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 10390c7d97c5SJed Brown /* 10400c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 10410c7d97c5SJed Brown by setting data structures and options. 10420c7d97c5SJed Brown 10430c7d97c5SJed Brown Input Parameter: 104453cdbc3dSStefano Zampini + pc - the preconditioner context 10450c7d97c5SJed Brown 10460c7d97c5SJed Brown Application Interface Routine: PCSetUp() 10470c7d97c5SJed Brown 10480c7d97c5SJed Brown Notes: 10490c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 10500c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 10510c7d97c5SJed Brown */ 105253cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 10530c7d97c5SJed Brown { 10540c7d97c5SJed Brown PetscErrorCode ierr; 10550c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 1056674ae819SStefano Zampini MatStructure flag; 1057674ae819SStefano Zampini PetscBool computeis,computetopography,computesolvers; 10580c7d97c5SJed Brown 10590c7d97c5SJed Brown PetscFunctionBegin; 1060674ae819SStefano Zampini /* the following lines of code should be replaced by a better logic between PCIS, PCNN, PCBDDC and other nonoverlapping preconditioners */ 1061fcd409f5SStefano Zampini /* PCIS does not support MatStructures different from SAME_PRECONDITIONER */ 10623b03a366Sstefano_zampini /* For BDDC we need to define a local "Neumann" problem different to that defined in PCISSetup 1063fcd409f5SStefano Zampini Also, BDDC directly build the Dirichlet problem */ 10643b03a366Sstefano_zampini /* Get stdout for dbg */ 1065674ae819SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->dbg_viewer) { 1066ce94432eSBarry Smith ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)pc),&pcbddc->dbg_viewer);CHKERRQ(ierr); 1067e269702eSStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); 10682b510759SStefano Zampini if (pcbddc->current_level) { 10692b510759SStefano Zampini ierr = PetscViewerASCIIAddTab(pcbddc->dbg_viewer,2);CHKERRQ(ierr); 10702b510759SStefano Zampini } 1071e269702eSStefano Zampini } 1072674ae819SStefano Zampini /* first attempt to split work */ 1073674ae819SStefano Zampini if (pc->setupcalled) { 1074674ae819SStefano Zampini computeis = PETSC_FALSE; 1075674ae819SStefano Zampini ierr = PCGetOperators(pc,NULL,NULL,&flag);CHKERRQ(ierr); 1076674ae819SStefano Zampini if (flag == SAME_PRECONDITIONER) { 1077674ae819SStefano Zampini computetopography = PETSC_FALSE; 1078674ae819SStefano Zampini computesolvers = PETSC_FALSE; 1079674ae819SStefano Zampini } else if (flag == SAME_NONZERO_PATTERN) { 1080674ae819SStefano Zampini computetopography = PETSC_FALSE; 1081674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1082674ae819SStefano Zampini } else { /* DIFFERENT_NONZERO_PATTERN */ 1083674ae819SStefano Zampini computetopography = PETSC_TRUE; 1084674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1085674ae819SStefano Zampini } 1086674ae819SStefano Zampini } else { 1087674ae819SStefano Zampini computeis = PETSC_TRUE; 1088674ae819SStefano Zampini computetopography = PETSC_TRUE; 1089674ae819SStefano Zampini computesolvers = PETSC_TRUE; 1090674ae819SStefano Zampini } 1091fcd409f5SStefano Zampini /* Set up all the "iterative substructuring" common block without computing solvers */ 1092674ae819SStefano Zampini if (computeis) { 1093fcd409f5SStefano Zampini /* HACK INTO PCIS */ 1094fcd409f5SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 1095fcd409f5SStefano Zampini pcis->computesolvers = PETSC_FALSE; 1096674ae819SStefano Zampini ierr = PCISSetUp(pc);CHKERRQ(ierr); 1097674ae819SStefano Zampini } 1098674ae819SStefano Zampini /* Analyze interface and set up local constraint and change of basis matrices */ 1099674ae819SStefano Zampini if (computetopography) { 1100674ae819SStefano Zampini /* reset data */ 1101674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 1102674ae819SStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 1103674ae819SStefano Zampini ierr = PCBDDCConstraintsSetUp(pc);CHKERRQ(ierr); 1104674ae819SStefano Zampini } 1105674ae819SStefano Zampini if (computesolvers) { 1106674ae819SStefano Zampini /* reset data */ 1107674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 1108674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 110999cc7994SStefano Zampini /* Create coarse and local stuffs */ 111099cc7994SStefano Zampini ierr = PCBDDCSetUpSolvers(pc);CHKERRQ(ierr); 1111674ae819SStefano Zampini ierr = PCBDDCScalingSetUp(pc);CHKERRQ(ierr); 11120c7d97c5SJed Brown } 11132b510759SStefano Zampini if (pcbddc->dbg_flag && pcbddc->current_level) { 11142b510759SStefano Zampini ierr = PetscViewerASCIISubtractTab(pcbddc->dbg_viewer,2);CHKERRQ(ierr); 11152b510759SStefano Zampini } 11160c7d97c5SJed Brown PetscFunctionReturn(0); 11170c7d97c5SJed Brown } 11180c7d97c5SJed Brown 11190c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 11200c7d97c5SJed Brown /* 11210c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 11220c7d97c5SJed Brown 11230c7d97c5SJed Brown Input Parameters: 11240c7d97c5SJed Brown . pc - the preconditioner context 11250c7d97c5SJed Brown . r - input vector (global) 11260c7d97c5SJed Brown 11270c7d97c5SJed Brown Output Parameter: 11280c7d97c5SJed Brown . z - output vector (global) 11290c7d97c5SJed Brown 11300c7d97c5SJed Brown Application Interface Routine: PCApply() 11310c7d97c5SJed Brown */ 11320c7d97c5SJed Brown #undef __FUNCT__ 11330c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 113453cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 11350c7d97c5SJed Brown { 11360c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 11370c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 11380c7d97c5SJed Brown PetscErrorCode ierr; 11393b03a366Sstefano_zampini const PetscScalar one = 1.0; 11403b03a366Sstefano_zampini const PetscScalar m_one = -1.0; 11412617d88aSStefano Zampini const PetscScalar zero = 0.0; 11420c7d97c5SJed Brown 11430c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 11440c7d97c5SJed Brown NN interface preconditioner changed to BDDC 11458eeda7d8SStefano Zampini Added support for M_3 preconditioner in the reference article (code is active if pcbddc->switch_static = PETSC_TRUE) */ 11460c7d97c5SJed Brown 11470c7d97c5SJed Brown PetscFunctionBegin; 114885c4d303SStefano Zampini if (!pcbddc->use_exact_dirichlet_trick) { 11490c7d97c5SJed Brown /* First Dirichlet solve */ 11500c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11510c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 115253cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 11530c7d97c5SJed Brown /* 11540c7d97c5SJed Brown Assembling right hand side for BDDC operator 1155674ae819SStefano Zampini - pcis->vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 1156674ae819SStefano Zampini - pcis->vec1_B the interface part of the global vector z 11570c7d97c5SJed Brown */ 11580c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 11590c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 11608eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 11610c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 11620c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 11630c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11640c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1165674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,z,pcis->vec1_B);CHKERRQ(ierr); 1166b76ba322SStefano Zampini } else { 11670bdf917eSStefano Zampini ierr = VecSet(pcis->vec1_D,zero);CHKERRQ(ierr); 1168b76ba322SStefano Zampini ierr = VecSet(pcis->vec2_D,zero);CHKERRQ(ierr); 1169674ae819SStefano Zampini ierr = PCBDDCScalingRestriction(pc,r,pcis->vec1_B);CHKERRQ(ierr); 1170b76ba322SStefano Zampini } 1171b76ba322SStefano Zampini 11722617d88aSStefano Zampini /* Apply interface preconditioner 11732617d88aSStefano Zampini input/output vecs: pcis->vec1_B and pcis->vec1_D */ 11742617d88aSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc);CHKERRQ(ierr); 11752617d88aSStefano Zampini 1176674ae819SStefano Zampini /* Apply transpose of partition of unity operator */ 1177674ae819SStefano Zampini ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,z);CHKERRQ(ierr); 11780c7d97c5SJed Brown 11793b03a366Sstefano_zampini /* Second Dirichlet solve and assembling of output */ 11800c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11810c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11820c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 11838eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 118453cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 11850c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 11868eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 11870c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 11880c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11890c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 11900c7d97c5SJed Brown PetscFunctionReturn(0); 11910c7d97c5SJed Brown } 1192da1bb401SStefano Zampini /* -------------------------------------------------------------------------- */ 1193674ae819SStefano Zampini 1194da1bb401SStefano Zampini #undef __FUNCT__ 1195da1bb401SStefano Zampini #define __FUNCT__ "PCDestroy_BDDC" 1196da1bb401SStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 1197da1bb401SStefano Zampini { 1198da1bb401SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1199da1bb401SStefano Zampini PetscErrorCode ierr; 1200da1bb401SStefano Zampini 1201da1bb401SStefano Zampini PetscFunctionBegin; 1202da1bb401SStefano Zampini /* free data created by PCIS */ 1203da1bb401SStefano Zampini ierr = PCISDestroy(pc);CHKERRQ(ierr); 1204674ae819SStefano Zampini /* free BDDC custom data */ 1205674ae819SStefano Zampini ierr = PCBDDCResetCustomization(pc);CHKERRQ(ierr); 1206674ae819SStefano Zampini /* destroy objects related to topography */ 1207674ae819SStefano Zampini ierr = PCBDDCResetTopography(pc);CHKERRQ(ierr); 1208674ae819SStefano Zampini /* free allocated graph structure */ 1209da1bb401SStefano Zampini ierr = PetscFree(pcbddc->mat_graph);CHKERRQ(ierr); 1210674ae819SStefano Zampini /* free data for scaling operator */ 1211674ae819SStefano Zampini ierr = PCBDDCScalingDestroy(pc);CHKERRQ(ierr); 1212674ae819SStefano Zampini /* free solvers stuff */ 1213674ae819SStefano Zampini ierr = PCBDDCResetSolvers(pc);CHKERRQ(ierr); 121433bc96a4SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 121533bc96a4SStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 12169881197aSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 1217ac78edfcSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 121862a6ff1dSStefano Zampini /* free global vectors needed in presolve */ 121962a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->temp_solution);CHKERRQ(ierr); 122062a6ff1dSStefano Zampini ierr = VecDestroy(&pcbddc->original_rhs);CHKERRQ(ierr); 12213425bc38SStefano Zampini /* remove functions */ 1222674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",NULL);CHKERRQ(ierr); 1223bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",NULL);CHKERRQ(ierr); 12242b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",NULL);CHKERRQ(ierr); 1225b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",NULL);CHKERRQ(ierr); 12262b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",NULL);CHKERRQ(ierr); 1227bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",NULL);CHKERRQ(ierr); 1228785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 122982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 1230785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 123182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 1232785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",NULL);CHKERRQ(ierr); 123382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",NULL);CHKERRQ(ierr); 1234785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",NULL);CHKERRQ(ierr); 1235785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",NULL);CHKERRQ(ierr); 1236bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",NULL);CHKERRQ(ierr); 1237*63602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",NULL);CHKERRQ(ierr); 1238bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",NULL);CHKERRQ(ierr); 1239bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",NULL);CHKERRQ(ierr); 1240bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",NULL);CHKERRQ(ierr); 1241bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",NULL);CHKERRQ(ierr); 1242674ae819SStefano Zampini /* Free the private data structure */ 1243674ae819SStefano Zampini ierr = PetscFree(pc->data);CHKERRQ(ierr); 1244da1bb401SStefano Zampini PetscFunctionReturn(0); 1245da1bb401SStefano Zampini } 12463425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 12471e6b0712SBarry Smith 12483425bc38SStefano Zampini #undef __FUNCT__ 12493425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS_BDDC" 12503425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetRHS_BDDC(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 12513425bc38SStefano Zampini { 1252674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 12533425bc38SStefano Zampini PC_IS* pcis; 12543425bc38SStefano Zampini PC_BDDC* pcbddc; 12553425bc38SStefano Zampini PetscErrorCode ierr; 12560c7d97c5SJed Brown 12573425bc38SStefano Zampini PetscFunctionBegin; 12583425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 12593425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 12603425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 12613425bc38SStefano Zampini 12623425bc38SStefano Zampini /* change of basis for physical rhs if needed 12633425bc38SStefano Zampini It also changes the rhs in case of dirichlet boundaries */ 12643308cffdSStefano Zampini ierr = PCPreSolve_BDDC(mat_ctx->pc,NULL,standard_rhs,NULL);CHKERRQ(ierr); 12653425bc38SStefano Zampini /* store vectors for computation of fetidp final solution */ 12663425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12673425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,standard_rhs,mat_ctx->temp_solution_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1268fb223d50SStefano Zampini /* scale rhs since it should be unassembled */ 1269fb223d50SStefano Zampini /* TODO use counter scaling? (also below) */ 12703425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12713425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1272674ae819SStefano Zampini /* Apply partition of unity */ 12733425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 1274674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 12758eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 12763425bc38SStefano Zampini /* compute partially subassembled Schur complement right-hand side */ 12773425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 12783425bc38SStefano Zampini ierr = MatMult(pcis->A_BI,pcis->vec1_D,pcis->vec1_B);CHKERRQ(ierr); 12793425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_B,-1.0,pcis->vec1_B);CHKERRQ(ierr); 12803425bc38SStefano Zampini ierr = VecSet(standard_rhs,0.0);CHKERRQ(ierr); 12813425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 12823425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,mat_ctx->temp_solution_B,standard_rhs,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1283674ae819SStefano Zampini /* ierr = PCBDDCScalingRestriction(mat_ctx->pc,standard_rhs,mat_ctx->temp_solution_B);CHKERRQ(ierr); */ 12843425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12853425bc38SStefano Zampini ierr = VecScatterEnd(pcis->global_to_B,standard_rhs,mat_ctx->temp_solution_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12863425bc38SStefano Zampini ierr = VecPointwiseMult(mat_ctx->temp_solution_B,pcis->D,mat_ctx->temp_solution_B);CHKERRQ(ierr); 12873425bc38SStefano Zampini } 12883425bc38SStefano Zampini /* BDDC rhs */ 12893425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_B,pcis->vec1_B);CHKERRQ(ierr); 12908eeda7d8SStefano Zampini if (pcbddc->switch_static) { 12913425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 12923425bc38SStefano Zampini } 12933425bc38SStefano Zampini /* apply BDDC */ 12943425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 12953425bc38SStefano Zampini /* Application of B_delta and assembling of rhs for fetidp fluxes */ 12963425bc38SStefano Zampini ierr = VecSet(fetidp_flux_rhs,0.0);CHKERRQ(ierr); 12973425bc38SStefano Zampini ierr = MatMult(mat_ctx->B_delta,pcis->vec1_B,mat_ctx->lambda_local);CHKERRQ(ierr); 12983425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 12993425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,mat_ctx->lambda_local,fetidp_flux_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 13003425bc38SStefano Zampini /* restore original rhs */ 13013425bc38SStefano Zampini ierr = VecCopy(pcbddc->original_rhs,standard_rhs);CHKERRQ(ierr); 13023425bc38SStefano Zampini PetscFunctionReturn(0); 13033425bc38SStefano Zampini } 13041e6b0712SBarry Smith 13053425bc38SStefano Zampini #undef __FUNCT__ 13063425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetRHS" 13073425bc38SStefano Zampini /*@ 130828509bceSStefano Zampini PCBDDCMatFETIDPGetRHS - Compute the right-hand side for FETIDP linear system 13093425bc38SStefano Zampini 13103425bc38SStefano Zampini Collective 13113425bc38SStefano Zampini 13123425bc38SStefano Zampini Input Parameters: 131328509bceSStefano Zampini + fetidp_mat - the FETIDP matrix object obtained by calling PCBDDCCreateFETIDPOperators 131428509bceSStefano Zampini . standard_rhs - the right-hand side for your linear system 13153425bc38SStefano Zampini 13163425bc38SStefano Zampini Output Parameters: 131728509bceSStefano Zampini - fetidp_flux_rhs - the right-hand side for the FETIDP linear system 13183425bc38SStefano Zampini 13193425bc38SStefano Zampini Level: developer 13203425bc38SStefano Zampini 13213425bc38SStefano Zampini Notes: 13223425bc38SStefano Zampini 132328509bceSStefano Zampini .seealso: PCBDDC,PCBDDCCreateFETIDPOperators 13243425bc38SStefano Zampini @*/ 13253425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetRHS(Mat fetidp_mat, Vec standard_rhs, Vec fetidp_flux_rhs) 13263425bc38SStefano Zampini { 1327674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 13283425bc38SStefano Zampini PetscErrorCode ierr; 13293425bc38SStefano Zampini 13303425bc38SStefano Zampini PetscFunctionBegin; 13313425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 13323425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetRHS_C",(Mat,Vec,Vec),(fetidp_mat,standard_rhs,fetidp_flux_rhs));CHKERRQ(ierr); 13333425bc38SStefano Zampini PetscFunctionReturn(0); 13343425bc38SStefano Zampini } 13353425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 13361e6b0712SBarry Smith 13373425bc38SStefano Zampini #undef __FUNCT__ 13383425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution_BDDC" 13393425bc38SStefano Zampini static PetscErrorCode PCBDDCMatFETIDPGetSolution_BDDC(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 13403425bc38SStefano Zampini { 1341674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 13423425bc38SStefano Zampini PC_IS* pcis; 13433425bc38SStefano Zampini PC_BDDC* pcbddc; 13443425bc38SStefano Zampini PetscErrorCode ierr; 13453425bc38SStefano Zampini 13463425bc38SStefano Zampini PetscFunctionBegin; 13473425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 13483425bc38SStefano Zampini pcis = (PC_IS*)mat_ctx->pc->data; 13493425bc38SStefano Zampini pcbddc = (PC_BDDC*)mat_ctx->pc->data; 13503425bc38SStefano Zampini 13513425bc38SStefano Zampini /* apply B_delta^T */ 13523425bc38SStefano Zampini ierr = VecScatterBegin(mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13533425bc38SStefano Zampini ierr = VecScatterEnd (mat_ctx->l2g_lambda,fetidp_flux_sol,mat_ctx->lambda_local,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13543425bc38SStefano Zampini ierr = MatMultTranspose(mat_ctx->B_delta,mat_ctx->lambda_local,pcis->vec1_B);CHKERRQ(ierr); 13553425bc38SStefano Zampini /* compute rhs for BDDC application */ 13563425bc38SStefano Zampini ierr = VecAYPX(pcis->vec1_B,-1.0,mat_ctx->temp_solution_B);CHKERRQ(ierr); 13578eeda7d8SStefano Zampini if (pcbddc->switch_static) { 13583425bc38SStefano Zampini ierr = VecCopy(mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 13593425bc38SStefano Zampini } 13603425bc38SStefano Zampini /* apply BDDC */ 13613425bc38SStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(mat_ctx->pc);CHKERRQ(ierr); 13623425bc38SStefano Zampini /* put values into standard global vector */ 13633425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13643425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13658eeda7d8SStefano Zampini if (!pcbddc->switch_static) { 13663425bc38SStefano Zampini /* compute values into the interior if solved for the partially subassembled Schur complement */ 13673425bc38SStefano Zampini ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec1_D);CHKERRQ(ierr); 13683425bc38SStefano Zampini ierr = VecAXPY(mat_ctx->temp_solution_D,-1.0,pcis->vec1_D);CHKERRQ(ierr); 13693425bc38SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,mat_ctx->temp_solution_D,pcis->vec1_D);CHKERRQ(ierr); 13703425bc38SStefano Zampini } 13713425bc38SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13723425bc38SStefano Zampini ierr = VecScatterEnd (pcis->global_to_D,pcis->vec1_D,standard_sol,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 13733425bc38SStefano Zampini /* final change of basis if needed 13743425bc38SStefano Zampini Is also sums the dirichlet part removed during RHS assembling */ 13753308cffdSStefano Zampini ierr = PCPostSolve_BDDC(mat_ctx->pc,NULL,NULL,standard_sol);CHKERRQ(ierr); 13763425bc38SStefano Zampini PetscFunctionReturn(0); 13773425bc38SStefano Zampini } 13781e6b0712SBarry Smith 13793425bc38SStefano Zampini #undef __FUNCT__ 13803425bc38SStefano Zampini #define __FUNCT__ "PCBDDCMatFETIDPGetSolution" 13813425bc38SStefano Zampini /*@ 138228509bceSStefano Zampini PCBDDCMatFETIDPGetSolution - Compute the physical solution from the solution of the FETIDP linear system 13833425bc38SStefano Zampini 13843425bc38SStefano Zampini Collective 13853425bc38SStefano Zampini 13863425bc38SStefano Zampini Input Parameters: 138728509bceSStefano Zampini + fetidp_mat - the FETIDP matrix obtained by calling PCBDDCCreateFETIDPOperators 138828509bceSStefano Zampini . fetidp_flux_sol - the solution of the FETIDP linear system 13893425bc38SStefano Zampini 13903425bc38SStefano Zampini Output Parameters: 139128509bceSStefano Zampini - standard_sol - the solution defined on the physical domain 13923425bc38SStefano Zampini 13933425bc38SStefano Zampini Level: developer 13943425bc38SStefano Zampini 13953425bc38SStefano Zampini Notes: 13963425bc38SStefano Zampini 139728509bceSStefano Zampini .seealso: PCBDDC,PCBDDCCreateFETIDPOperators 13983425bc38SStefano Zampini @*/ 13993425bc38SStefano Zampini PetscErrorCode PCBDDCMatFETIDPGetSolution(Mat fetidp_mat, Vec fetidp_flux_sol, Vec standard_sol) 14003425bc38SStefano Zampini { 1401674ae819SStefano Zampini FETIDPMat_ctx mat_ctx; 14023425bc38SStefano Zampini PetscErrorCode ierr; 14033425bc38SStefano Zampini 14043425bc38SStefano Zampini PetscFunctionBegin; 14053425bc38SStefano Zampini ierr = MatShellGetContext(fetidp_mat,&mat_ctx);CHKERRQ(ierr); 14063425bc38SStefano Zampini ierr = PetscTryMethod(mat_ctx->pc,"PCBDDCMatFETIDPGetSolution_C",(Mat,Vec,Vec),(fetidp_mat,fetidp_flux_sol,standard_sol));CHKERRQ(ierr); 14073425bc38SStefano Zampini PetscFunctionReturn(0); 14083425bc38SStefano Zampini } 14093425bc38SStefano Zampini /* -------------------------------------------------------------------------- */ 14101e6b0712SBarry Smith 1411f23aa3ddSBarry Smith extern PetscErrorCode FETIDPMatMult(Mat,Vec,Vec); 1412f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPMat(Mat); 1413f23aa3ddSBarry Smith extern PetscErrorCode FETIDPPCApply(PC,Vec,Vec); 1414f23aa3ddSBarry Smith extern PetscErrorCode PCBDDCDestroyFETIDPPC(PC); 1415674ae819SStefano Zampini 14163425bc38SStefano Zampini #undef __FUNCT__ 14173425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators_BDDC" 14183425bc38SStefano Zampini static PetscErrorCode PCBDDCCreateFETIDPOperators_BDDC(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 14193425bc38SStefano Zampini { 1420674ae819SStefano Zampini 1421674ae819SStefano Zampini FETIDPMat_ctx fetidpmat_ctx; 14223425bc38SStefano Zampini Mat newmat; 1423674ae819SStefano Zampini FETIDPPC_ctx fetidppc_ctx; 14243425bc38SStefano Zampini PC newpc; 1425ce94432eSBarry Smith MPI_Comm comm; 14263425bc38SStefano Zampini PetscErrorCode ierr; 14273425bc38SStefano Zampini 14283425bc38SStefano Zampini PetscFunctionBegin; 1429ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 14303425bc38SStefano Zampini /* FETIDP linear matrix */ 14313425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPMatContext(pc,&fetidpmat_ctx);CHKERRQ(ierr); 14323425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPMatContext(fetidpmat_ctx);CHKERRQ(ierr); 14333425bc38SStefano Zampini ierr = MatCreateShell(comm,PETSC_DECIDE,PETSC_DECIDE,fetidpmat_ctx->n_lambda,fetidpmat_ctx->n_lambda,fetidpmat_ctx,&newmat);CHKERRQ(ierr); 14343425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_MULT,(void (*)(void))FETIDPMatMult);CHKERRQ(ierr); 14353425bc38SStefano Zampini ierr = MatShellSetOperation(newmat,MATOP_DESTROY,(void (*)(void))PCBDDCDestroyFETIDPMat);CHKERRQ(ierr); 14363425bc38SStefano Zampini ierr = MatSetUp(newmat);CHKERRQ(ierr); 14373425bc38SStefano Zampini /* FETIDP preconditioner */ 14383425bc38SStefano Zampini ierr = PCBDDCCreateFETIDPPCContext(pc,&fetidppc_ctx);CHKERRQ(ierr); 14393425bc38SStefano Zampini ierr = PCBDDCSetupFETIDPPCContext(newmat,fetidppc_ctx);CHKERRQ(ierr); 14403425bc38SStefano Zampini ierr = PCCreate(comm,&newpc);CHKERRQ(ierr); 14413425bc38SStefano Zampini ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); 14423425bc38SStefano Zampini ierr = PCShellSetContext(newpc,fetidppc_ctx);CHKERRQ(ierr); 14433425bc38SStefano Zampini ierr = PCShellSetApply(newpc,FETIDPPCApply);CHKERRQ(ierr); 14443425bc38SStefano Zampini ierr = PCShellSetDestroy(newpc,PCBDDCDestroyFETIDPPC);CHKERRQ(ierr); 14453425bc38SStefano Zampini ierr = PCSetOperators(newpc,newmat,newmat,SAME_PRECONDITIONER);CHKERRQ(ierr); 14463425bc38SStefano Zampini ierr = PCSetUp(newpc);CHKERRQ(ierr); 14473425bc38SStefano Zampini /* return pointers for objects created */ 14483425bc38SStefano Zampini *fetidp_mat=newmat; 14493425bc38SStefano Zampini *fetidp_pc=newpc; 14503425bc38SStefano Zampini PetscFunctionReturn(0); 14513425bc38SStefano Zampini } 14521e6b0712SBarry Smith 14533425bc38SStefano Zampini #undef __FUNCT__ 14543425bc38SStefano Zampini #define __FUNCT__ "PCBDDCCreateFETIDPOperators" 14553425bc38SStefano Zampini /*@ 145628509bceSStefano Zampini PCBDDCCreateFETIDPOperators - Create operators for FETIDP 14573425bc38SStefano Zampini 14583425bc38SStefano Zampini Collective 14593425bc38SStefano Zampini 14603425bc38SStefano Zampini Input Parameters: 146128509bceSStefano Zampini + pc - the BDDC preconditioning context already setup 146228509bceSStefano Zampini 146328509bceSStefano Zampini Output Parameters: 146428509bceSStefano Zampini . fetidp_mat - shell FETIDP matrix object 146528509bceSStefano Zampini . fetidp_pc - shell Dirichlet preconditioner for FETIDP matrix 146628509bceSStefano Zampini 146728509bceSStefano Zampini Options Database Keys: 146828509bceSStefano Zampini - -fetidp_fullyredundant: use or not a fully redundant set of Lagrange multipliers 14693425bc38SStefano Zampini 14703425bc38SStefano Zampini Level: developer 14713425bc38SStefano Zampini 14723425bc38SStefano Zampini Notes: 147328509bceSStefano Zampini Currently the only operation provided for FETIDP matrix is MatMult 14743425bc38SStefano Zampini 14753425bc38SStefano Zampini .seealso: PCBDDC 14763425bc38SStefano Zampini @*/ 14773425bc38SStefano Zampini PetscErrorCode PCBDDCCreateFETIDPOperators(PC pc, Mat *fetidp_mat, PC *fetidp_pc) 14783425bc38SStefano Zampini { 14793425bc38SStefano Zampini PetscErrorCode ierr; 14803425bc38SStefano Zampini 14813425bc38SStefano Zampini PetscFunctionBegin; 14823425bc38SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 14833425bc38SStefano Zampini if (pc->setupcalled) { 1484516d51a7SStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCCreateFETIDPOperators_C",(PC,Mat*,PC*),(pc,fetidp_mat,fetidp_pc));CHKERRQ(ierr); 1485f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"You must call PCSetup_BDDC() first \n"); 14863425bc38SStefano Zampini PetscFunctionReturn(0); 14873425bc38SStefano Zampini } 14880c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1489da1bb401SStefano Zampini /*MC 1490da1bb401SStefano Zampini PCBDDC - Balancing Domain Decomposition by Constraints. 14910c7d97c5SJed Brown 149228509bceSStefano Zampini An implementation of the BDDC preconditioner based on 149328509bceSStefano Zampini 149428509bceSStefano Zampini .vb 149528509bceSStefano Zampini [1] C. R. Dohrmann. "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 149628509bceSStefano 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 149728509bceSStefano Zampini [3] J. Mandel, B. Sousedik, C. R. Dohrmann. "Multispace and Multilevel BDDC", http://arxiv.org/abs/0712.3977 149828509bceSStefano Zampini .ve 149928509bceSStefano Zampini 150028509bceSStefano Zampini The matrix to be preconditioned (Pmat) must be of type MATIS. 150128509bceSStefano Zampini 1502b6fdb6dfSStefano Zampini Currently works with MATIS matrices with local Neumann matrices of type MATSEQAIJ, MATSEQBAIJ or MATSEQSBAIJ, either with real or complex numbers. 150328509bceSStefano Zampini 150428509bceSStefano Zampini It also works with unsymmetric and indefinite problems. 150528509bceSStefano Zampini 1506b6fdb6dfSStefano 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. 1507b6fdb6dfSStefano Zampini 150828509bceSStefano Zampini Approximate local solvers are automatically adapted for singular linear problems (see [1]) if the user has provided the nullspace using PCBDDCSetNullSpace 150928509bceSStefano Zampini 151028509bceSStefano Zampini Boundary nodes are split in vertices, edges and faces 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 151128509bceSStefano Zampini 151228509bceSStefano Zampini Constraints can be customized by attaching a MatNullSpace object to the MATIS matrix via MatSetNearNullSpace. 151328509bceSStefano Zampini 1514b6fdb6dfSStefano Zampini Change of basis is performed similarly to [2] when requested. When more the 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. 151528509bceSStefano Zampini 151628509bceSStefano Zampini The PETSc implementation also supports multilevel BDDC [3]. Coarse grids are partitioned using MatPartitioning object. 151728509bceSStefano Zampini 1518da1bb401SStefano Zampini Options Database Keys: 151928509bceSStefano Zampini 152028509bceSStefano Zampini . -pc_bddc_use_vertices <1> - use or not vertices in primal space 152128509bceSStefano Zampini . -pc_bddc_use_edges <1> - use or not edges in primal space 1522b6fdb6dfSStefano Zampini . -pc_bddc_use_faces <0> - use or not faces in primal space 152328509bceSStefano Zampini . -pc_bddc_use_change_of_basis <0> - use change of basis approach (on edges only) 152428509bceSStefano Zampini . -pc_bddc_use_change_on_faces <0> - use change of basis approach on faces if change of basis has been requested 152528509bceSStefano Zampini . -pc_bddc_switch_static <0> - switches from M_2 to M_3 operator (see reference article [1]) 152628509bceSStefano Zampini . -pc_bddc_levels <0> - maximum number of levels for multilevel 152728509bceSStefano Zampini . -pc_bddc_coarsening_ratio - H/h ratio at the coarser level 152828509bceSStefano Zampini - -pc_bddc_check_level <0> - set verbosity level of debugging output 152928509bceSStefano Zampini 153028509bceSStefano Zampini Options for Dirichlet, Neumann or coarse solver can be set with 153128509bceSStefano Zampini .vb 153228509bceSStefano Zampini -pc_bddc_dirichlet_ 153328509bceSStefano Zampini -pc_bddc_neumann_ 153428509bceSStefano Zampini -pc_bddc_coarse_ 153528509bceSStefano Zampini .ve 153628509bceSStefano Zampini e.g -pc_bddc_dirichlet_ksp_type richardson -pc_bddc_dirichlet_pc_type gamg 153728509bceSStefano Zampini 153828509bceSStefano Zampini When using a multilevel approach, solvers' options at the N-th level can be specified as 153928509bceSStefano Zampini .vb 154028509bceSStefano Zampini -pc_bddc_dirichlet_N_ 154128509bceSStefano Zampini -pc_bddc_neumann_N_ 154228509bceSStefano Zampini -pc_bddc_coarse_N_ 154328509bceSStefano Zampini .ve 154428509bceSStefano Zampini Note that level number ranges from the finest 0 to the coarsest N 1545da1bb401SStefano Zampini 1546da1bb401SStefano Zampini Level: intermediate 1547da1bb401SStefano Zampini 1548b6fdb6dfSStefano Zampini Developer notes: 154928509bceSStefano Zampini Currently does not work with KSPBCGS and other KSPs requiring the specialization of PCApplyTranspose 1550da1bb401SStefano Zampini 155128509bceSStefano Zampini New deluxe scaling operator will be available soon. 1552da1bb401SStefano Zampini 1553da1bb401SStefano Zampini Contributed by Stefano Zampini 1554da1bb401SStefano Zampini 1555da1bb401SStefano Zampini .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 1556da1bb401SStefano Zampini M*/ 1557b2573a8aSBarry Smith 1558da1bb401SStefano Zampini #undef __FUNCT__ 1559da1bb401SStefano Zampini #define __FUNCT__ "PCCreate_BDDC" 15608cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_BDDC(PC pc) 1561da1bb401SStefano Zampini { 1562da1bb401SStefano Zampini PetscErrorCode ierr; 1563da1bb401SStefano Zampini PC_BDDC *pcbddc; 1564da1bb401SStefano Zampini 1565da1bb401SStefano Zampini PetscFunctionBegin; 1566da1bb401SStefano Zampini /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 1567da1bb401SStefano Zampini ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 1568da1bb401SStefano Zampini pc->data = (void*)pcbddc; 1569da1bb401SStefano Zampini 1570da1bb401SStefano Zampini /* create PCIS data structure */ 1571da1bb401SStefano Zampini ierr = PCISCreate(pc);CHKERRQ(ierr); 1572da1bb401SStefano Zampini 157347d04d0dSStefano Zampini /* BDDC customization */ 157447d04d0dSStefano Zampini pcbddc->use_vertices = PETSC_TRUE; 157547d04d0dSStefano Zampini pcbddc->use_edges = PETSC_TRUE; 157647d04d0dSStefano Zampini pcbddc->use_faces = PETSC_FALSE; 157747d04d0dSStefano Zampini pcbddc->use_change_of_basis = PETSC_FALSE; 157847d04d0dSStefano Zampini pcbddc->use_change_on_faces = PETSC_FALSE; 157947d04d0dSStefano Zampini pcbddc->switch_static = PETSC_FALSE; 158047d04d0dSStefano Zampini pcbddc->use_nnsp_true = PETSC_FALSE; /* not yet exposed */ 158147d04d0dSStefano Zampini pcbddc->dbg_flag = 0; 158247d04d0dSStefano Zampini 1583674ae819SStefano Zampini pcbddc->user_primal_vertices = 0; 15840bdf917eSStefano Zampini pcbddc->NullSpace = 0; 15853972b0daSStefano Zampini pcbddc->temp_solution = 0; 1586534831adSStefano Zampini pcbddc->original_rhs = 0; 1587534831adSStefano Zampini pcbddc->local_mat = 0; 1588534831adSStefano Zampini pcbddc->ChangeOfBasisMatrix = 0; 1589da1bb401SStefano Zampini pcbddc->coarse_vec = 0; 1590da1bb401SStefano Zampini pcbddc->coarse_rhs = 0; 1591da1bb401SStefano Zampini pcbddc->coarse_ksp = 0; 1592da1bb401SStefano Zampini pcbddc->coarse_phi_B = 0; 1593da1bb401SStefano Zampini pcbddc->coarse_phi_D = 0; 159415aaf578SStefano Zampini pcbddc->coarse_psi_B = 0; 159515aaf578SStefano Zampini pcbddc->coarse_psi_D = 0; 1596da1bb401SStefano Zampini pcbddc->vec1_P = 0; 1597da1bb401SStefano Zampini pcbddc->vec1_R = 0; 1598da1bb401SStefano Zampini pcbddc->vec2_R = 0; 1599da1bb401SStefano Zampini pcbddc->local_auxmat1 = 0; 1600da1bb401SStefano Zampini pcbddc->local_auxmat2 = 0; 1601da1bb401SStefano Zampini pcbddc->R_to_B = 0; 1602da1bb401SStefano Zampini pcbddc->R_to_D = 0; 1603da1bb401SStefano Zampini pcbddc->ksp_D = 0; 1604da1bb401SStefano Zampini pcbddc->ksp_R = 0; 1605da1bb401SStefano Zampini pcbddc->NeumannBoundaries = 0; 1606785d1243SStefano Zampini pcbddc->NeumannBoundariesLocal = 0; 1607785d1243SStefano Zampini pcbddc->DirichletBoundaries = 0; 1608785d1243SStefano Zampini pcbddc->DirichletBoundariesLocal = 0; 160960d44989SStefano Zampini pcbddc->user_provided_isfordofs = PETSC_FALSE; 161060d44989SStefano Zampini pcbddc->n_ISForDofs = 0; 1611*63602bcaSStefano Zampini pcbddc->n_ISForDofsLocal = 0; 1612da1bb401SStefano Zampini pcbddc->ISForDofs = 0; 1613*63602bcaSStefano Zampini pcbddc->ISForDofsLocal = 0; 1614da1bb401SStefano Zampini pcbddc->ConstraintMatrix = 0; 161585c4d303SStefano Zampini pcbddc->use_exact_dirichlet_trick = PETSC_TRUE; 161647d04d0dSStefano Zampini pcbddc->coarse_loc_to_glob = 0; 161747d04d0dSStefano Zampini pcbddc->coarsening_ratio = 8; 16184fad6a16SStefano Zampini pcbddc->current_level = 0; 16192b510759SStefano Zampini pcbddc->max_levels = 0; 1620da1bb401SStefano Zampini 1621674ae819SStefano Zampini /* create local graph structure */ 1622674ae819SStefano Zampini ierr = PCBDDCGraphCreate(&pcbddc->mat_graph);CHKERRQ(ierr); 1623674ae819SStefano Zampini 1624674ae819SStefano Zampini /* scaling */ 1625674ae819SStefano Zampini pcbddc->use_deluxe_scaling = PETSC_FALSE; 1626674ae819SStefano Zampini pcbddc->work_scaling = 0; 1627da1bb401SStefano Zampini 1628da1bb401SStefano Zampini /* function pointers */ 1629da1bb401SStefano Zampini pc->ops->apply = PCApply_BDDC; 1630da1bb401SStefano Zampini pc->ops->applytranspose = 0; 1631da1bb401SStefano Zampini pc->ops->setup = PCSetUp_BDDC; 1632da1bb401SStefano Zampini pc->ops->destroy = PCDestroy_BDDC; 1633da1bb401SStefano Zampini pc->ops->setfromoptions = PCSetFromOptions_BDDC; 1634da1bb401SStefano Zampini pc->ops->view = 0; 1635da1bb401SStefano Zampini pc->ops->applyrichardson = 0; 1636da1bb401SStefano Zampini pc->ops->applysymmetricleft = 0; 1637da1bb401SStefano Zampini pc->ops->applysymmetricright = 0; 1638534831adSStefano Zampini pc->ops->presolve = PCPreSolve_BDDC; 1639534831adSStefano Zampini pc->ops->postsolve = PCPostSolve_BDDC; 1640da1bb401SStefano Zampini 1641da1bb401SStefano Zampini /* composing function */ 1642674ae819SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetPrimalVerticesLocalIS_C",PCBDDCSetPrimalVerticesLocalIS_BDDC);CHKERRQ(ierr); 1643bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetCoarseningRatio_C",PCBDDCSetCoarseningRatio_BDDC);CHKERRQ(ierr); 16442b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevel_C",PCBDDCSetLevel_BDDC);CHKERRQ(ierr); 1645b8ffe317SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetUseExactDirichlet_C",PCBDDCSetUseExactDirichlet_BDDC);CHKERRQ(ierr); 16462b510759SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLevels_C",PCBDDCSetLevels_BDDC);CHKERRQ(ierr); 1647bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNullSpace_C",PCBDDCSetNullSpace_BDDC);CHKERRQ(ierr); 1648785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundaries_C",PCBDDCSetDirichletBoundaries_BDDC);CHKERRQ(ierr); 164982ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDirichletBoundariesLocal_C",PCBDDCSetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 1650785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C",PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 165182ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetNeumannBoundariesLocal_C",PCBDDCSetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 1652785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundaries_C",PCBDDCGetDirichletBoundaries_BDDC);CHKERRQ(ierr); 165382ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetDirichletBoundariesLocal_C",PCBDDCGetDirichletBoundariesLocal_BDDC);CHKERRQ(ierr); 1654785d1243SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C",PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 165582ba6b80SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCGetNeumannBoundariesLocal_C",PCBDDCGetNeumannBoundariesLocal_BDDC);CHKERRQ(ierr); 1656bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplitting_C",PCBDDCSetDofsSplitting_BDDC);CHKERRQ(ierr); 1657*63602bcaSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetDofsSplittingLocal_C",PCBDDCSetDofsSplittingLocal_BDDC);CHKERRQ(ierr); 1658bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCSetLocalAdjacencyGraph_C",PCBDDCSetLocalAdjacencyGraph_BDDC);CHKERRQ(ierr); 1659bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCCreateFETIDPOperators_C",PCBDDCCreateFETIDPOperators_BDDC);CHKERRQ(ierr); 1660bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetRHS_C",PCBDDCMatFETIDPGetRHS_BDDC);CHKERRQ(ierr); 1661bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCMatFETIDPGetSolution_C",PCBDDCMatFETIDPGetSolution_BDDC);CHKERRQ(ierr); 1662da1bb401SStefano Zampini PetscFunctionReturn(0); 1663da1bb401SStefano Zampini } 16643425bc38SStefano Zampini 1665