153cdbc3dSStefano Zampini /* TODOLIST 253cdbc3dSStefano Zampini remove // commments 353cdbc3dSStefano Zampini remove coarse enums -> allows use of PCBDDCGetCoarseKSP 453cdbc3dSStefano Zampini code refactoring 553cdbc3dSStefano Zampini remove metis dependency -> use MatPartitioning for multilevel 653cdbc3dSStefano Zampini analyze MatSetNearNullSpace as suggested by Jed 753cdbc3dSStefano Zampini options structure 853cdbc3dSStefano Zampini */ 90c7d97c5SJed Brown 1053cdbc3dSStefano Zampini /* ---------------------------------------------------------------------------------------------------------------------------------------------- 110c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 120c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 1353cdbc3dSStefano Zampini ---------------------------------------------------------------------------------------------------------------------------------------------- */ 1453cdbc3dSStefano Zampini 1553cdbc3dSStefano Zampini #include "bddc.h" /*I "petscpc.h" I*/ /* includes for fortran wrappers */ 160c7d97c5SJed Brown 170c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 180c7d97c5SJed Brown #undef __FUNCT__ 190c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 200c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 210c7d97c5SJed Brown { 220c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 230c7d97c5SJed Brown PetscErrorCode ierr; 240c7d97c5SJed Brown 250c7d97c5SJed Brown PetscFunctionBegin; 260c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 270c7d97c5SJed Brown /* Verbose debugging of main data structures */ 280c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_check_all" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->check_flag ,&pcbddc->check_flag ,PETSC_NULL);CHKERRQ(ierr); 290c7d97c5SJed Brown /* Some customization for default primal space */ 300c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_vertices_only" ,"Use vertices only in coarse space (i.e. discard constraints)","none",pcbddc->vertices_flag ,&pcbddc->vertices_flag ,PETSC_NULL);CHKERRQ(ierr); 310c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_constraints_only","Use constraints only in coarse space (i.e. discard vertices)","none",pcbddc->constraints_flag,&pcbddc->constraints_flag,PETSC_NULL);CHKERRQ(ierr); 320c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_faces_only" ,"Use faces only in coarse space (i.e. discard edges)" ,"none",pcbddc->faces_flag ,&pcbddc->faces_flag ,PETSC_NULL);CHKERRQ(ierr); 330c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_edges_only" ,"Use edges only in coarse space (i.e. discard faces)" ,"none",pcbddc->edges_flag ,&pcbddc->edges_flag ,PETSC_NULL);CHKERRQ(ierr); 340c7d97c5SJed Brown /* Coarse solver context */ 350c7d97c5SJed Brown static const char *avail_coarse_problems[] = {"sequential","replicated","parallel","multilevel",""}; //order of choiches depends on ENUM defined in bddc.h 360c7d97c5SJed Brown ierr = PetscOptionsEnum("-pc_bddc_coarse_problem_type","Set coarse problem type","none",avail_coarse_problems,(PetscEnum)pcbddc->coarse_problem_type,(PetscEnum*)&pcbddc->coarse_problem_type,PETSC_NULL);CHKERRQ(ierr); 370c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 380c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_switch_preconditioning_type","Switch between M_2 (default) and M_3 preconditioners (as defined by Dohrmann)","none",pcbddc->prec_type,&pcbddc->prec_type,PETSC_NULL);CHKERRQ(ierr); 390c7d97c5SJed Brown ierr = PetscOptionsInt("-pc_bddc_coarsening_ratio","Set coarsening ratio used in multilevel coarsening","none",pcbddc->coarsening_ratio,&pcbddc->coarsening_ratio,PETSC_NULL);CHKERRQ(ierr); 400c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 410c7d97c5SJed Brown PetscFunctionReturn(0); 420c7d97c5SJed Brown } 430c7d97c5SJed Brown 440c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 450c7d97c5SJed Brown EXTERN_C_BEGIN 460c7d97c5SJed Brown #undef __FUNCT__ 470c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 4853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 490c7d97c5SJed Brown { 500c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 510c7d97c5SJed Brown 520c7d97c5SJed Brown PetscFunctionBegin; 530c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 540c7d97c5SJed Brown PetscFunctionReturn(0); 550c7d97c5SJed Brown } 560c7d97c5SJed Brown EXTERN_C_END 570c7d97c5SJed Brown 580c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 590c7d97c5SJed Brown #undef __FUNCT__ 600c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 6153cdbc3dSStefano Zampini /*@ 6253cdbc3dSStefano Zampini PCBDDCSetCoarseProblemType - brief explanation 6353cdbc3dSStefano Zampini 6453cdbc3dSStefano Zampini Collective on PC 6553cdbc3dSStefano Zampini 6653cdbc3dSStefano Zampini Input Parameters: 6753cdbc3dSStefano Zampini + pc - the preconditioning context 6853cdbc3dSStefano Zampini - CoarseProblemType - pick a better name and explain what this is 6953cdbc3dSStefano Zampini 7053cdbc3dSStefano Zampini Level: intermediate 7153cdbc3dSStefano Zampini 7253cdbc3dSStefano Zampini Notes: 7353cdbc3dSStefano Zampini usage notes, perhaps an example 7453cdbc3dSStefano Zampini 7553cdbc3dSStefano Zampini .seealso: PCBDDC 7653cdbc3dSStefano Zampini @*/ 770c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 780c7d97c5SJed Brown { 790c7d97c5SJed Brown PetscErrorCode ierr; 800c7d97c5SJed Brown 810c7d97c5SJed Brown PetscFunctionBegin; 820c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 830c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 840c7d97c5SJed Brown PetscFunctionReturn(0); 850c7d97c5SJed Brown } 860c7d97c5SJed Brown 870c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 880c7d97c5SJed Brown EXTERN_C_BEGIN 890c7d97c5SJed Brown #undef __FUNCT__ 900c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 9153cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,IS NeumannBoundaries) 920c7d97c5SJed Brown { 930c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 9453cdbc3dSStefano Zampini PetscErrorCode ierr; 950c7d97c5SJed Brown 960c7d97c5SJed Brown PetscFunctionBegin; 9753cdbc3dSStefano Zampini ierr = PetscObjectReference((PetscObject)NeumannBoundaries);CHKERRQ(ierr); 9853cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 9953cdbc3dSStefano Zampini ierr = ISDuplicate(NeumannBoundaries,&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 10053cdbc3dSStefano Zampini ierr = ISCopy(NeumannBoundaries,pcbddc->NeumannBoundaries);CHKERRQ(ierr); 1010c7d97c5SJed Brown PetscFunctionReturn(0); 1020c7d97c5SJed Brown } 1030c7d97c5SJed Brown EXTERN_C_END 1040c7d97c5SJed Brown 1050c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1060c7d97c5SJed Brown #undef __FUNCT__ 1070c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 10857527edcSJed Brown /*@ 10953cdbc3dSStefano Zampini PCBDDCSetNeumannBoundaries - Set index set defining subdomain part of 11053cdbc3dSStefano Zampini Neumann boundaries for the global problem. 11157527edcSJed Brown 11253cdbc3dSStefano Zampini Logically Collective on PC 11357527edcSJed Brown 11457527edcSJed Brown Input Parameters: 11557527edcSJed Brown + pc - the preconditioning context 11653cdbc3dSStefano Zampini - NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 11757527edcSJed Brown 11857527edcSJed Brown Level: intermediate 11957527edcSJed Brown 12057527edcSJed Brown Notes: 12157527edcSJed Brown usage notes, perhaps an example 12257527edcSJed Brown 12357527edcSJed Brown .seealso: PCBDDC 12457527edcSJed Brown @*/ 12553cdbc3dSStefano Zampini PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,IS NeumannBoundaries) 1260c7d97c5SJed Brown { 1270c7d97c5SJed Brown PetscErrorCode ierr; 1280c7d97c5SJed Brown 1290c7d97c5SJed Brown PetscFunctionBegin; 1300c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 13153cdbc3dSStefano Zampini ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,IS),(pc,NeumannBoundaries));CHKERRQ(ierr); 13253cdbc3dSStefano Zampini PetscFunctionReturn(0); 13353cdbc3dSStefano Zampini } 13453cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 13553cdbc3dSStefano Zampini EXTERN_C_BEGIN 13653cdbc3dSStefano Zampini #undef __FUNCT__ 13753cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries_BDDC" 13853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCGetNeumannBoundaries_BDDC(PC pc,IS *NeumannBoundaries) 13953cdbc3dSStefano Zampini { 14053cdbc3dSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 14153cdbc3dSStefano Zampini 14253cdbc3dSStefano Zampini PetscFunctionBegin; 14353cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 14453cdbc3dSStefano Zampini *NeumannBoundaries = pcbddc->NeumannBoundaries; 14553cdbc3dSStefano Zampini } else { 14653cdbc3dSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Error in %s: Neumann boundaries not set!.\n",__FUNCT__); 14753cdbc3dSStefano Zampini } 14853cdbc3dSStefano Zampini PetscFunctionReturn(0); 14953cdbc3dSStefano Zampini } 15053cdbc3dSStefano Zampini EXTERN_C_END 15153cdbc3dSStefano Zampini 15253cdbc3dSStefano Zampini /* -------------------------------------------------------------------------- */ 15353cdbc3dSStefano Zampini #undef __FUNCT__ 15453cdbc3dSStefano Zampini #define __FUNCT__ "PCBDDCGetNeumannBoundaries" 15553cdbc3dSStefano Zampini /*@ 15653cdbc3dSStefano Zampini PCBDDCGetNeumannBoundaries - Get index set defining subdomain part of 15753cdbc3dSStefano Zampini Neumann boundaries for the global problem. 15853cdbc3dSStefano Zampini 15953cdbc3dSStefano Zampini Logically Collective on PC 16053cdbc3dSStefano Zampini 16153cdbc3dSStefano Zampini Input Parameters: 16253cdbc3dSStefano Zampini + pc - the preconditioning context 16353cdbc3dSStefano Zampini 16453cdbc3dSStefano Zampini Output Parameters: 16553cdbc3dSStefano Zampini + NeumannBoundaries - index set defining the subdomain part of Neumann boundaries 16653cdbc3dSStefano Zampini 16753cdbc3dSStefano Zampini Level: intermediate 16853cdbc3dSStefano Zampini 16953cdbc3dSStefano Zampini Notes: 17053cdbc3dSStefano Zampini usage notes, perhaps an example 17153cdbc3dSStefano Zampini 17253cdbc3dSStefano Zampini .seealso: PCBDDC 17353cdbc3dSStefano Zampini @*/ 17453cdbc3dSStefano Zampini PetscErrorCode PCBDDCGetNeumannBoundaries(PC pc,IS *NeumannBoundaries) 17553cdbc3dSStefano Zampini { 17653cdbc3dSStefano Zampini PetscErrorCode ierr; 17753cdbc3dSStefano Zampini 17853cdbc3dSStefano Zampini PetscFunctionBegin; 17953cdbc3dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 18053cdbc3dSStefano Zampini ierr = PetscUseMethod(pc,"PCBDDCGetNeumannBoundaries_C",(PC,IS*),(pc,NeumannBoundaries));CHKERRQ(ierr); 1810c7d97c5SJed Brown PetscFunctionReturn(0); 1820c7d97c5SJed Brown } 1830c7d97c5SJed Brown 18453cdbc3dSStefano Zampini #undef __FUNCT__ 18553cdbc3dSStefano Zampini #define __FUNCT__ "PCSetUp_BDDC" 1860c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1870c7d97c5SJed Brown /* 1880c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 1890c7d97c5SJed Brown by setting data structures and options. 1900c7d97c5SJed Brown 1910c7d97c5SJed Brown Input Parameter: 19253cdbc3dSStefano Zampini + pc - the preconditioner context 1930c7d97c5SJed Brown 1940c7d97c5SJed Brown Application Interface Routine: PCSetUp() 1950c7d97c5SJed Brown 1960c7d97c5SJed Brown Notes: 1970c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 1980c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 1990c7d97c5SJed Brown */ 20053cdbc3dSStefano Zampini PetscErrorCode PCSetUp_BDDC(PC pc) 2010c7d97c5SJed Brown { 2020c7d97c5SJed Brown PetscErrorCode ierr; 2030c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2040c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 2050c7d97c5SJed Brown 2060c7d97c5SJed Brown PetscFunctionBegin; 2070c7d97c5SJed Brown if (!pc->setupcalled) { 2080c7d97c5SJed Brown 2090c7d97c5SJed Brown /* For BDDC we need to define a local "Neumann" to that defined in PCISSetup 2100c7d97c5SJed Brown So, we set to pcnone the Neumann problem of pcid in order to avoid unneeded computation 2110c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 2120c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 2130c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 2140c7d97c5SJed Brown /* Set up all the "iterative substructuring" common block */ 2150c7d97c5SJed Brown ierr = PCISSetUp(pc);CHKERRQ(ierr); 2160c7d97c5SJed Brown /* Destroy some PC_IS data which is not needed by BDDC */ 2170c7d97c5SJed Brown //if (pcis->ksp_D) {ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr);} 2180c7d97c5SJed Brown //if (pcis->ksp_N) {ierr = KSPDestroy(&pcis->ksp_N);CHKERRQ(ierr);} 2190c7d97c5SJed Brown //if (pcis->vec2_B) {ierr = VecDestroy(&pcis->vec2_B);CHKERRQ(ierr);} 2200c7d97c5SJed Brown //if (pcis->vec3_B) {ierr = VecDestroy(&pcis->vec3_B);CHKERRQ(ierr);} 2210c7d97c5SJed Brown //pcis->ksp_D = 0; 2220c7d97c5SJed Brown //pcis->ksp_N = 0; 2230c7d97c5SJed Brown //pcis->vec2_B = 0; 2240c7d97c5SJed Brown //pcis->vec3_B = 0; 2250c7d97c5SJed Brown 2260c7d97c5SJed Brown //TODO MOVE CODE FRAGMENT 2270c7d97c5SJed Brown PetscInt im_active=0; 2280c7d97c5SJed Brown if(pcis->n) im_active = 1; 22953cdbc3dSStefano Zampini ierr = MPI_Allreduce(&im_active,&pcbddc->active_procs,1,MPIU_INT,MPI_SUM,((PetscObject)pc)->comm);CHKERRQ(ierr); 2300c7d97c5SJed Brown //printf("Calling PCBDDC MANAGE with active procs %d (im_active = %d)\n",pcbddc->active_procs,im_active); 2310c7d97c5SJed Brown /* Set up grid quantities for BDDC */ 2320c7d97c5SJed Brown //TODO only active procs must call this -> remove synchronized print inside (the only point of sync) 2330c7d97c5SJed Brown ierr = PCBDDCManageLocalBoundaries(pc);CHKERRQ(ierr); 2340c7d97c5SJed Brown 2350c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 2360c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 2370c7d97c5SJed Brown 2380c7d97c5SJed Brown if ( !pcis->n_neigh ) pcis->ISLocalToGlobalMappingGetInfoWasCalled=PETSC_FALSE; //processes fakely involved in multilevel should not call ISLocalToGlobalMappingRestoreInfo 2390c7d97c5SJed Brown /* We no more need this matrix */ 2400c7d97c5SJed Brown //if (pcis->A_BB) {ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr);} 2410c7d97c5SJed Brown //pcis->A_BB = 0; 2420c7d97c5SJed Brown 2430c7d97c5SJed Brown //printf("Using coarse problem type %d\n",pcbddc->coarse_problem_type); 2440c7d97c5SJed Brown //printf("Using coarse communications type %d\n",pcbddc->coarse_communications_type); 2450c7d97c5SJed Brown //printf("Using coarsening ratio %d\n",pcbddc->coarsening_ratio); 2460c7d97c5SJed Brown } 2470c7d97c5SJed Brown 2480c7d97c5SJed Brown PetscFunctionReturn(0); 2490c7d97c5SJed Brown } 2500c7d97c5SJed Brown 2510c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2520c7d97c5SJed Brown /* 2530c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 2540c7d97c5SJed Brown 2550c7d97c5SJed Brown Input Parameters: 2560c7d97c5SJed Brown . pc - the preconditioner context 2570c7d97c5SJed Brown . r - input vector (global) 2580c7d97c5SJed Brown 2590c7d97c5SJed Brown Output Parameter: 2600c7d97c5SJed Brown . z - output vector (global) 2610c7d97c5SJed Brown 2620c7d97c5SJed Brown Application Interface Routine: PCApply() 2630c7d97c5SJed Brown */ 2640c7d97c5SJed Brown #undef __FUNCT__ 2650c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 26653cdbc3dSStefano Zampini PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 2670c7d97c5SJed Brown { 2680c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 2690c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 2700c7d97c5SJed Brown PetscErrorCode ierr; 2710c7d97c5SJed Brown PetscScalar one = 1.0; 2720c7d97c5SJed Brown PetscScalar m_one = -1.0; 2730c7d97c5SJed Brown 2740c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 2750c7d97c5SJed Brown NN interface preconditioner changed to BDDC 2760c7d97c5SJed Brown Added support for M_3 preconditioenr in the reference article (code is active if pcbddc->prec_type = PETSC_TRUE) */ 2770c7d97c5SJed Brown 2780c7d97c5SJed Brown PetscFunctionBegin; 2790c7d97c5SJed Brown /* First Dirichlet solve */ 2800c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2810c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 28253cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 2830c7d97c5SJed Brown /* 2840c7d97c5SJed Brown Assembling right hand side for BDDC operator 2850c7d97c5SJed Brown - vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 2860c7d97c5SJed Brown - the interface part of the global vector z 2870c7d97c5SJed Brown */ 2880c7d97c5SJed Brown //ierr = VecScatterBegin(pcis->global_to_B,r,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2890c7d97c5SJed Brown //ierr = VecScatterEnd (pcis->global_to_B,r,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2900c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 2910c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 2920c7d97c5SJed Brown //ierr = MatMultAdd(pcis->A_BI,pcis->vec2_D,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 2930c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 2940c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 2950c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 2960c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2970c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 2980c7d97c5SJed Brown 2990c7d97c5SJed Brown /* 3000c7d97c5SJed Brown Apply interface preconditioner 3010c7d97c5SJed Brown Results are stored in: 3020c7d97c5SJed Brown - vec1_D (if needed, i.e. with prec_type = PETSC_TRUE) 3030c7d97c5SJed Brown - the interface part of the global vector z 3040c7d97c5SJed Brown */ 3050c7d97c5SJed Brown ierr = PCBDDCApplyInterfacePreconditioner(pc,z);CHKERRQ(ierr); 3060c7d97c5SJed Brown 3070c7d97c5SJed Brown /* Second Dirichlet solves and assembling of output */ 3080c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3090c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3100c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 3110c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 31253cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 3130c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 3140c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 3150c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 3160c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3170c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3180c7d97c5SJed Brown 3190c7d97c5SJed Brown PetscFunctionReturn(0); 3200c7d97c5SJed Brown 3210c7d97c5SJed Brown } 3220c7d97c5SJed Brown 3230c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 3240c7d97c5SJed Brown /* 3250c7d97c5SJed Brown PCBDDCApplyInterfacePreconditioner - Apply the BDDC preconditioner at the interface. 3260c7d97c5SJed Brown 3270c7d97c5SJed Brown */ 3280c7d97c5SJed Brown #undef __FUNCT__ 3290c7d97c5SJed Brown #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 33053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, Vec z) 3310c7d97c5SJed Brown { 3320c7d97c5SJed Brown PetscErrorCode ierr; 3330c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3340c7d97c5SJed Brown PC_IS* pcis = (PC_IS*) (pc->data); 3350c7d97c5SJed Brown PetscScalar zero = 0.0; 3360c7d97c5SJed Brown 3370c7d97c5SJed Brown PetscFunctionBegin; 3380c7d97c5SJed Brown /* Get Local boundary and apply partition of unity */ 3390c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3400c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3410c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 3420c7d97c5SJed Brown 3430c7d97c5SJed Brown /* Application of PHI^T */ 3440c7d97c5SJed Brown ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 3450c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 3460c7d97c5SJed Brown 3470c7d97c5SJed Brown /* Scatter data of coarse_rhs */ 3480c7d97c5SJed Brown if(pcbddc->coarse_rhs) ierr = VecSet(pcbddc->coarse_rhs,zero);CHKERRQ(ierr); 3490c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3500c7d97c5SJed Brown 3510c7d97c5SJed Brown /* Local solution on R nodes */ 3520c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 3530c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3540c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3550c7d97c5SJed Brown if(pcbddc->prec_type) { 3560c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3570c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3580c7d97c5SJed Brown } 3590c7d97c5SJed Brown ierr = PCBDDCSolveSaddlePoint(pc);CHKERRQ(ierr); 3600c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 3610c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3620c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3630c7d97c5SJed Brown if(pcbddc->prec_type) { 3640c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3650c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 3660c7d97c5SJed Brown } 3670c7d97c5SJed Brown 3680c7d97c5SJed Brown /* Coarse solution */ 3690c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 37053cdbc3dSStefano Zampini if(pcbddc->coarse_rhs) ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 3710c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3720c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd (pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3730c7d97c5SJed Brown 3740c7d97c5SJed Brown /* Sum contributions from two levels */ 3750c7d97c5SJed Brown /* Apply partition of unity and sum boundary values */ 3760c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 3770c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 3780c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 3790c7d97c5SJed Brown ierr = VecSet(z,zero);CHKERRQ(ierr); 3800c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3810c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 3820c7d97c5SJed Brown 3830c7d97c5SJed Brown PetscFunctionReturn(0); 3840c7d97c5SJed Brown } 3850c7d97c5SJed Brown 3860c7d97c5SJed Brown 3870c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 3880c7d97c5SJed Brown /* 3890c7d97c5SJed Brown PCBDDCSolveSaddlePoint 3900c7d97c5SJed Brown 3910c7d97c5SJed Brown */ 3920c7d97c5SJed Brown #undef __FUNCT__ 3930c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSolveSaddlePoint" 39453cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSolveSaddlePoint(PC pc) 3950c7d97c5SJed Brown { 3960c7d97c5SJed Brown PetscErrorCode ierr; 3970c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 3980c7d97c5SJed Brown 3990c7d97c5SJed Brown PetscFunctionBegin; 4000c7d97c5SJed Brown 40153cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4020c7d97c5SJed Brown if(pcbddc->n_constraints) { 4030c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec2_R,pcbddc->vec1_C);CHKERRQ(ierr); 4040c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 4050c7d97c5SJed Brown } 4060c7d97c5SJed Brown 4070c7d97c5SJed Brown PetscFunctionReturn(0); 4080c7d97c5SJed Brown } 4090c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4100c7d97c5SJed Brown /* 4110c7d97c5SJed Brown PCBDDCScatterCoarseDataBegin 4120c7d97c5SJed Brown 4130c7d97c5SJed Brown */ 4140c7d97c5SJed Brown #undef __FUNCT__ 4150c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 41653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 4170c7d97c5SJed Brown { 4180c7d97c5SJed Brown PetscErrorCode ierr; 4190c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4200c7d97c5SJed Brown 4210c7d97c5SJed Brown PetscFunctionBegin; 4220c7d97c5SJed Brown 4230c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 4240c7d97c5SJed Brown case SCATTERS_BDDC: 4250c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 4260c7d97c5SJed Brown break; 4270c7d97c5SJed Brown case GATHERS_BDDC: 4280c7d97c5SJed Brown break; 4290c7d97c5SJed Brown } 4300c7d97c5SJed Brown PetscFunctionReturn(0); 4310c7d97c5SJed Brown 4320c7d97c5SJed Brown } 4330c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4340c7d97c5SJed Brown /* 4350c7d97c5SJed Brown PCBDDCScatterCoarseDataEnd 4360c7d97c5SJed Brown 4370c7d97c5SJed Brown */ 4380c7d97c5SJed Brown #undef __FUNCT__ 4390c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 44053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 4410c7d97c5SJed Brown { 4420c7d97c5SJed Brown PetscErrorCode ierr; 4430c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4440c7d97c5SJed Brown PetscScalar* array_to; 4450c7d97c5SJed Brown PetscScalar* array_from; 4460c7d97c5SJed Brown MPI_Comm comm=((PetscObject)pc)->comm; 4470c7d97c5SJed Brown PetscInt i; 4480c7d97c5SJed Brown 4490c7d97c5SJed Brown PetscFunctionBegin; 4500c7d97c5SJed Brown 4510c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 4520c7d97c5SJed Brown case SCATTERS_BDDC: 4530c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 4540c7d97c5SJed Brown break; 4550c7d97c5SJed Brown case GATHERS_BDDC: 4560c7d97c5SJed Brown if(vec_from) VecGetArray(vec_from,&array_from); 4570c7d97c5SJed Brown if(vec_to) VecGetArray(vec_to,&array_to); 4580c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 4590c7d97c5SJed Brown case SEQUENTIAL_BDDC: 4600c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 46153cdbc3dSStefano Zampini ierr = MPI_Gatherv(&array_from[0],pcbddc->local_primal_size,MPIU_SCALAR,&pcbddc->replicated_local_primal_values[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 4620c7d97c5SJed Brown if(vec_to) { 4630c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 4640c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 4650c7d97c5SJed Brown } 4660c7d97c5SJed Brown } else { 4670c7d97c5SJed Brown if(vec_from) 4680c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 4690c7d97c5SJed Brown pcbddc->replicated_local_primal_values[i]=array_from[pcbddc->replicated_local_primal_indices[i]]; 47053cdbc3dSStefano Zampini ierr = MPI_Scatterv(&pcbddc->replicated_local_primal_values[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_SCALAR,&array_to[0],pcbddc->local_primal_size,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 4710c7d97c5SJed Brown } 4720c7d97c5SJed Brown break; 4730c7d97c5SJed Brown case REPLICATED_BDDC: 4740c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 47553cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&array_from[0],pcbddc->local_primal_size,MPIU_SCALAR,&pcbddc->replicated_local_primal_values[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_SCALAR,comm);CHKERRQ(ierr); 4760c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 4770c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 4780c7d97c5SJed Brown } else { /* no communications needed for SCATTER_REVERSE since needed data is already present */ 4790c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) 4800c7d97c5SJed Brown array_to[i]=array_from[pcbddc->local_primal_indices[i]]; 4810c7d97c5SJed Brown } 4820c7d97c5SJed Brown break; 48353cdbc3dSStefano Zampini case MULTILEVEL_BDDC: 48453cdbc3dSStefano Zampini break; 48553cdbc3dSStefano Zampini case PARALLEL_BDDC: 48653cdbc3dSStefano Zampini break; 4870c7d97c5SJed Brown } 4880c7d97c5SJed Brown if(vec_from) VecRestoreArray(vec_from,&array_from); 4890c7d97c5SJed Brown if(vec_to) VecRestoreArray(vec_to,&array_to); 4900c7d97c5SJed Brown break; 4910c7d97c5SJed Brown } 4920c7d97c5SJed Brown PetscFunctionReturn(0); 4930c7d97c5SJed Brown 4940c7d97c5SJed Brown } 4950c7d97c5SJed Brown 4960c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 4970c7d97c5SJed Brown /* 4980c7d97c5SJed Brown PCDestroy_BDDC - Destroys the private context for the NN preconditioner 4990c7d97c5SJed Brown that was created with PCCreate_BDDC(). 5000c7d97c5SJed Brown 5010c7d97c5SJed Brown Input Parameter: 5020c7d97c5SJed Brown . pc - the preconditioner context 5030c7d97c5SJed Brown 5040c7d97c5SJed Brown Application Interface Routine: PCDestroy() 5050c7d97c5SJed Brown */ 5060c7d97c5SJed Brown #undef __FUNCT__ 5070c7d97c5SJed Brown #define __FUNCT__ "PCDestroy_BDDC" 50853cdbc3dSStefano Zampini PetscErrorCode PCDestroy_BDDC(PC pc) 5090c7d97c5SJed Brown { 5100c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5110c7d97c5SJed Brown PetscErrorCode ierr; 5120c7d97c5SJed Brown 5130c7d97c5SJed Brown PetscFunctionBegin; 5140c7d97c5SJed Brown /* free data created by PCIS */ 5150c7d97c5SJed Brown ierr = PCISDestroy(pc);CHKERRQ(ierr); 5160c7d97c5SJed Brown /* free BDDC data */ 51753cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 51853cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr); 51953cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 52053cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_mat);CHKERRQ(ierr); 52153cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 52253cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 52353cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 52453cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 52553cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 52653cdbc3dSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 52753cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 52853cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 52953cdbc3dSStefano Zampini ierr = VecDestroy(&pcbddc->vec4_D);CHKERRQ(ierr); 53053cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 53153cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 53253cdbc3dSStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 53353cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 53453cdbc3dSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 53553cdbc3dSStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 53653cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->vertices);CHKERRQ(ierr); 53753cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_indices);CHKERRQ(ierr); 53853cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 5390c7d97c5SJed Brown if (pcbddc->replicated_local_primal_values) { free(pcbddc->replicated_local_primal_values); } 54053cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr); 54153cdbc3dSStefano Zampini ierr = PetscFree(pcbddc->local_primal_sizes);CHKERRQ(ierr); 5420c7d97c5SJed Brown if (pcbddc->n_constraints) { 5430c7d97c5SJed Brown ierr = PetscFree(pcbddc->indices_to_constraint[0]);CHKERRQ(ierr); 5440c7d97c5SJed Brown ierr = PetscFree(pcbddc->indices_to_constraint);CHKERRQ(ierr); 5450c7d97c5SJed Brown ierr = PetscFree(pcbddc->quadrature_constraint[0]);CHKERRQ(ierr); 5460c7d97c5SJed Brown ierr = PetscFree(pcbddc->quadrature_constraint);CHKERRQ(ierr); 5470c7d97c5SJed Brown ierr = PetscFree(pcbddc->sizes_of_constraint);CHKERRQ(ierr); 5480c7d97c5SJed Brown } 5490c7d97c5SJed Brown /* Free the private data structure that was hanging off the PC */ 5500c7d97c5SJed Brown ierr = PetscFree(pcbddc);CHKERRQ(ierr); 5510c7d97c5SJed Brown PetscFunctionReturn(0); 5520c7d97c5SJed Brown } 5530c7d97c5SJed Brown 5540c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 5550c7d97c5SJed Brown /*MC 5560c7d97c5SJed Brown PCBDDC - Balancing Domain Decomposition by Constraints. 5570c7d97c5SJed Brown 5580c7d97c5SJed Brown Options Database Keys: 5590c7d97c5SJed Brown . -pc_is_damp_fixed <fact> - 5600c7d97c5SJed Brown . -pc_is_remove_nullspace_fixed - 5610c7d97c5SJed Brown . -pc_is_set_damping_factor_floating <fact> - 5620c7d97c5SJed Brown . -pc_is_not_damp_floating - 5630c7d97c5SJed Brown 5640c7d97c5SJed Brown Level: intermediate 5650c7d97c5SJed Brown 5660c7d97c5SJed Brown Notes: The matrix used with this preconditioner must be of type MATIS 5670c7d97c5SJed Brown 5680c7d97c5SJed Brown Unlike more 'conventional' interface preconditioners, this iterates over ALL the 5690c7d97c5SJed Brown degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 5700c7d97c5SJed Brown on the subdomains). 5710c7d97c5SJed Brown 5720c7d97c5SJed Brown Options for the coarse grid preconditioner can be set with -pc_bddc_coarse_pc_xxx 5730c7d97c5SJed Brown Options for the Dirichlet subproblem can be set with -pc_bddc_localD_xxx 5740c7d97c5SJed Brown Options for the Neumann subproblem can be set with -pc_bddc_localN_xxx 5750c7d97c5SJed Brown 5760c7d97c5SJed Brown Contributed by Stefano Zampini 5770c7d97c5SJed Brown 5780c7d97c5SJed Brown .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 5790c7d97c5SJed Brown M*/ 5800c7d97c5SJed Brown EXTERN_C_BEGIN 5810c7d97c5SJed Brown #undef __FUNCT__ 5820c7d97c5SJed Brown #define __FUNCT__ "PCCreate_BDDC" 5830c7d97c5SJed Brown PetscErrorCode PCCreate_BDDC(PC pc) 5840c7d97c5SJed Brown { 5850c7d97c5SJed Brown PetscErrorCode ierr; 5860c7d97c5SJed Brown PC_BDDC *pcbddc; 5870c7d97c5SJed Brown 5880c7d97c5SJed Brown PetscFunctionBegin; 5890c7d97c5SJed Brown /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 5900c7d97c5SJed Brown ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 5910c7d97c5SJed Brown pc->data = (void*)pcbddc; 5920c7d97c5SJed Brown /* create PCIS data structure */ 5930c7d97c5SJed Brown ierr = PCISCreate(pc);CHKERRQ(ierr); 5940c7d97c5SJed Brown /* BDDC specific */ 5950c7d97c5SJed Brown pcbddc->coarse_vec = 0; 5960c7d97c5SJed Brown pcbddc->coarse_rhs = 0; 59753cdbc3dSStefano Zampini pcbddc->coarse_ksp = 0; 5980c7d97c5SJed Brown pcbddc->coarse_phi_B = 0; 5990c7d97c5SJed Brown pcbddc->coarse_phi_D = 0; 6000c7d97c5SJed Brown pcbddc->vec1_P = 0; 6010c7d97c5SJed Brown pcbddc->vec1_R = 0; 6020c7d97c5SJed Brown pcbddc->vec2_R = 0; 6030c7d97c5SJed Brown pcbddc->local_auxmat1 = 0; 6040c7d97c5SJed Brown pcbddc->local_auxmat2 = 0; 6050c7d97c5SJed Brown pcbddc->R_to_B = 0; 6060c7d97c5SJed Brown pcbddc->R_to_D = 0; 60753cdbc3dSStefano Zampini pcbddc->ksp_D = 0; 60853cdbc3dSStefano Zampini pcbddc->ksp_R = 0; 6090c7d97c5SJed Brown pcbddc->n_constraints = 0; 6100c7d97c5SJed Brown pcbddc->n_vertices = 0; 6110c7d97c5SJed Brown pcbddc->vertices = 0; 6120c7d97c5SJed Brown pcbddc->indices_to_constraint = 0; 6130c7d97c5SJed Brown pcbddc->quadrature_constraint = 0; 6140c7d97c5SJed Brown pcbddc->sizes_of_constraint = 0; 6150c7d97c5SJed Brown pcbddc->local_primal_indices = 0; 6160c7d97c5SJed Brown pcbddc->prec_type = PETSC_FALSE; 61753cdbc3dSStefano Zampini pcbddc->NeumannBoundaries = 0; 6180c7d97c5SJed Brown pcbddc->local_primal_sizes = 0; 6190c7d97c5SJed Brown pcbddc->local_primal_displacements = 0; 6200c7d97c5SJed Brown pcbddc->replicated_local_primal_indices = 0; 6210c7d97c5SJed Brown pcbddc->replicated_local_primal_values = 0; 6220c7d97c5SJed Brown pcbddc->coarse_loc_to_glob = 0; 6230c7d97c5SJed Brown pcbddc->check_flag = PETSC_FALSE; 6240c7d97c5SJed Brown pcbddc->vertices_flag = PETSC_FALSE; 6250c7d97c5SJed Brown pcbddc->constraints_flag = PETSC_FALSE; 6260c7d97c5SJed Brown pcbddc->faces_flag = PETSC_FALSE; 6270c7d97c5SJed Brown pcbddc->edges_flag = PETSC_FALSE; 6280c7d97c5SJed Brown pcbddc->coarsening_ratio = 8; 6290c7d97c5SJed Brown /* function pointers */ 6300c7d97c5SJed Brown pc->ops->apply = PCApply_BDDC; 6310c7d97c5SJed Brown pc->ops->applytranspose = 0; 6320c7d97c5SJed Brown pc->ops->setup = PCSetUp_BDDC; 6330c7d97c5SJed Brown pc->ops->destroy = PCDestroy_BDDC; 6340c7d97c5SJed Brown pc->ops->setfromoptions = PCSetFromOptions_BDDC; 6350c7d97c5SJed Brown pc->ops->view = 0; 6360c7d97c5SJed Brown pc->ops->applyrichardson = 0; 6370c7d97c5SJed Brown pc->ops->applysymmetricleft = 0; 6380c7d97c5SJed Brown pc->ops->applysymmetricright = 0; 6390c7d97c5SJed Brown /* composing function */ 6400c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C","PCBDDCSetNeumannBoundaries_BDDC", 6410c7d97c5SJed Brown PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 64253cdbc3dSStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCGetNeumannBoundaries_C","PCBDDCGetNeumannBoundaries_BDDC", 64353cdbc3dSStefano Zampini PCBDDCGetNeumannBoundaries_BDDC);CHKERRQ(ierr); 6440c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseProblemType_C","PCBDDCSetCoarseProblemType_BDDC", 6450c7d97c5SJed Brown PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 6460c7d97c5SJed Brown PetscFunctionReturn(0); 6470c7d97c5SJed Brown } 6480c7d97c5SJed Brown EXTERN_C_END 6490c7d97c5SJed Brown 6500c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 6510c7d97c5SJed Brown /* 6520c7d97c5SJed Brown PCBDDCCoarseSetUp - 6530c7d97c5SJed Brown */ 6540c7d97c5SJed Brown #undef __FUNCT__ 6550c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 65653cdbc3dSStefano Zampini static PetscErrorCode PCBDDCCoarseSetUp(PC pc) 6570c7d97c5SJed Brown { 6580c7d97c5SJed Brown PetscErrorCode ierr; 6590c7d97c5SJed Brown 6600c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 6610c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 6620c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 6630c7d97c5SJed Brown IS is_R_local; 6640c7d97c5SJed Brown IS is_V_local; 6650c7d97c5SJed Brown IS is_C_local; 6660c7d97c5SJed Brown IS is_aux1; 6670c7d97c5SJed Brown IS is_aux2; 6680c7d97c5SJed Brown PetscViewer viewer; 6690c7d97c5SJed Brown PetscBool check_flag=pcbddc->check_flag; 6700c7d97c5SJed Brown const VecType impVecType; 6710c7d97c5SJed Brown const MatType impMatType; 6720c7d97c5SJed Brown PetscInt n_R=0; 6730c7d97c5SJed Brown PetscInt n_D=0; 6740c7d97c5SJed Brown PetscInt n_B=0; 6750c7d97c5SJed Brown PetscMPIInt totprocs; 6760c7d97c5SJed Brown PetscScalar zero=0.0; 6770c7d97c5SJed Brown PetscScalar one=1.0; 6780c7d97c5SJed Brown PetscScalar m_one=-1.0; 6790c7d97c5SJed Brown PetscScalar* array; 6800c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 6810c7d97c5SJed Brown PetscInt *idx_R_local; 6820c7d97c5SJed Brown PetscInt *idx_V_B; 6830c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 6840c7d97c5SJed Brown PetscScalar *constraints_errors; 6850c7d97c5SJed Brown /* auxiliary indices */ 6860c7d97c5SJed Brown PetscInt s,i,j,k; 6870c7d97c5SJed Brown 6880c7d97c5SJed Brown PetscFunctionBegin; 6890c7d97c5SJed Brown if(pcbddc->check_flag) { 6900c7d97c5SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&viewer);CHKERRQ(ierr); 6910c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 6920c7d97c5SJed Brown } 6930c7d97c5SJed Brown 6940c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 6950c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 6960c7d97c5SJed Brown /* Set local primal size */ 6970c7d97c5SJed Brown pcbddc->local_primal_size = pcbddc->n_vertices + pcbddc->n_constraints; 6980c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 6990c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 7000c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7010c7d97c5SJed Brown for (i=0;i<pcbddc->n_vertices;i++) { array[ pcbddc->vertices[i] ] = zero; } 7020c7d97c5SJed Brown ierr = PetscMalloc(( pcis->n - pcbddc->n_vertices )*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 7030c7d97c5SJed Brown for (i=0, n_R=0; i<pcis->n; i++) { if (array[i] == one) { idx_R_local[n_R] = i; n_R++; } } 7040c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7050c7d97c5SJed Brown if(check_flag) { 7060c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 7070c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 7080c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 7090c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 7100c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"r_size = %d, v_size = %d, constraints = %d, local_primal_size = %d\n",n_R,pcbddc->n_vertices,pcbddc->n_constraints,pcbddc->local_primal_size);CHKERRQ(ierr); 7110c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 7120c7d97c5SJed Brown } 7130c7d97c5SJed Brown /* Allocate needed vectors */ 7140c7d97c5SJed Brown /* Set Mat type for local matrices needed by BDDC precondtioner */ 7150c7d97c5SJed Brown // ierr = MatGetType(matis->A,&impMatType);CHKERRQ(ierr); 7160c7d97c5SJed Brown //ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 7170c7d97c5SJed Brown impMatType = MATSEQDENSE; 7180c7d97c5SJed Brown impVecType = VECSEQ; 7190c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 7200c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_N,&pcis->vec2_N);CHKERRQ(ierr); 7210c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 7220c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 7230c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 724*d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 7250c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 7260c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 7270c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 7280c7d97c5SJed Brown 7290c7d97c5SJed Brown /* Creating some index sets needed */ 7300c7d97c5SJed Brown /* For submatrices */ 7310c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_COPY_VALUES,&is_R_local);CHKERRQ(ierr); 7320c7d97c5SJed Brown if(pcbddc->n_vertices) { ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->vertices,PETSC_COPY_VALUES,&is_V_local);CHKERRQ(ierr); } 7330c7d97c5SJed Brown if(pcbddc->n_constraints) { ierr = ISCreateStride (PETSC_COMM_SELF,pcbddc->n_constraints,pcbddc->n_vertices,1,&is_C_local);CHKERRQ(ierr); } 7340c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 7350c7d97c5SJed Brown { 7360c7d97c5SJed Brown PetscInt *aux_array1; 7370c7d97c5SJed Brown PetscInt *aux_array2; 7380c7d97c5SJed Brown PetscScalar value; 7390c7d97c5SJed Brown 7400c7d97c5SJed Brown ierr = PetscMalloc( (pcis->n_B-pcbddc->n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 7410c7d97c5SJed Brown ierr = PetscMalloc( (pcis->n_B-pcbddc->n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 7420c7d97c5SJed Brown 743*d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 7440c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7450c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7460c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7470c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7480c7d97c5SJed Brown ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7490c7d97c5SJed Brown ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7500c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7510c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] > one) { aux_array1[s] = i; s++; } } 7520c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7530c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 7540c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 7550c7d97c5SJed Brown for (i=0, s=0; i<n_B; i++) { if (array[i] > one) { aux_array2[s] = i; s++; } } 7560c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7570c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 7580c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 7590c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 7600c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 7610c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 7620c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 7630c7d97c5SJed Brown 7640c7d97c5SJed Brown if(pcbddc->prec_type || check_flag ) { 7650c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 7660c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7670c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] == one) { aux_array1[s] = i; s++; } } 7680c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7690c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 7700c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 7710c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 7720c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 7730c7d97c5SJed Brown } 7740c7d97c5SJed Brown 7750c7d97c5SJed Brown /* Check scatters */ 7760c7d97c5SJed Brown if(check_flag) { 7770c7d97c5SJed Brown 7780c7d97c5SJed Brown Vec vec_aux; 7790c7d97c5SJed Brown 7800c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 7810c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_B scatter\n");CHKERRQ(ierr); 7820c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 783*d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 784*d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL);CHKERRQ(ierr); 785*d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux);CHKERRQ(ierr); 786*d49ef151SStefano Zampini ierr = VecCopy(pcbddc->vec1_R,vec_aux);CHKERRQ(ierr); 787*d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 788*d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 789*d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 790*d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 791*d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 792*d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 7930c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 794*d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 7950c7d97c5SJed Brown 796*d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 797*d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL);CHKERRQ(ierr); 798*d49ef151SStefano Zampini ierr = VecDuplicate(pcis->vec1_B,&vec_aux);CHKERRQ(ierr); 799*d49ef151SStefano Zampini ierr = VecCopy(pcis->vec1_B,vec_aux);CHKERRQ(ierr); 800*d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 801*d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 802*d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 803*d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 804*d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcis->vec1_B);CHKERRQ(ierr); 805*d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 8060c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 807*d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 8080c7d97c5SJed Brown 8090c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8100c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_D scatter\n");CHKERRQ(ierr); 8110c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8120c7d97c5SJed Brown 813*d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 814*d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 815*d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux);CHKERRQ(ierr); 816*d49ef151SStefano Zampini ierr = VecCopy(pcbddc->vec1_R,vec_aux);CHKERRQ(ierr); 817*d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 818*d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 819*d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 820*d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 821*d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 822*d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 8230c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 824*d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 8250c7d97c5SJed Brown 826*d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 827*d49ef151SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL);CHKERRQ(ierr); 828*d49ef151SStefano Zampini ierr = VecDuplicate(pcis->vec1_D,&vec_aux);CHKERRQ(ierr); 829*d49ef151SStefano Zampini ierr = VecCopy(pcis->vec1_D,vec_aux);CHKERRQ(ierr); 830*d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 831*d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 832*d49ef151SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 833*d49ef151SStefano Zampini ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 834*d49ef151SStefano Zampini ierr = VecAXPY(vec_aux,m_one,pcis->vec1_D);CHKERRQ(ierr); 835*d49ef151SStefano Zampini ierr = VecNorm(vec_aux,NORM_INFINITY,&value);CHKERRQ(ierr); 8360c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 837*d49ef151SStefano Zampini ierr = VecDestroy(&vec_aux);CHKERRQ(ierr); 8380c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8390c7d97c5SJed Brown 8400c7d97c5SJed Brown } 8410c7d97c5SJed Brown } 8420c7d97c5SJed Brown 8430c7d97c5SJed Brown /* vertices in boundary numbering */ 8440c7d97c5SJed Brown if(pcbddc->n_vertices) { 845*d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,m_one);CHKERRQ(ierr); 8460c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8470c7d97c5SJed Brown for (i=0; i<pcbddc->n_vertices; i++) { array[ pcbddc->vertices[i] ] = i; } 8480c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 849*d49ef151SStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 850*d49ef151SStefano Zampini ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8510c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 8520c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 8530c7d97c5SJed Brown //printf("vertices in boundary numbering\n"); 8540c7d97c5SJed Brown for (i=0; i<pcbddc->n_vertices; i++) { 8550c7d97c5SJed Brown s=0; 8560c7d97c5SJed Brown while (array[s] != i ) {s++;} 8570c7d97c5SJed Brown idx_V_B[i]=s; 8580c7d97c5SJed Brown //printf("idx_V_B[%d]=%d\n",i,s); 8590c7d97c5SJed Brown } 8600c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 8610c7d97c5SJed Brown } 8620c7d97c5SJed Brown 8630c7d97c5SJed Brown 8640c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 8650c7d97c5SJed Brown { 8660c7d97c5SJed Brown Mat A_RR; 86753cdbc3dSStefano Zampini PC pc_temp; 8680c7d97c5SJed Brown /* Matrix for Dirichlet problem is A_II -> we already have it from pcis.c code */ 86953cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 87053cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 87153cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 87253cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 87353cdbc3dSStefano Zampini //ierr = KSPSetOptionsPrefix(pcbddc->pc_D,"pc_bddc_localD_");CHKERRQ(ierr); 8740c7d97c5SJed Brown /* default */ 87553cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 87653cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 8770c7d97c5SJed Brown /* Allow user's customization */ 87853cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 87953cdbc3dSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 88053cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 8810c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 8820c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 88353cdbc3dSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 88453cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 88553cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 88653cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 88753cdbc3dSStefano Zampini //ierr = PCSetOptionsPrefix(pcbddc->pc_R,"pc_bddc_localN_");CHKERRQ(ierr); 8880c7d97c5SJed Brown /* default */ 88953cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 89053cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 8910c7d97c5SJed Brown /* Allow user's customization */ 89253cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 89353cdbc3dSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 89453cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 8950c7d97c5SJed Brown /* check Neumann solve */ 8960c7d97c5SJed Brown if(pcbddc->check_flag) { 8970c7d97c5SJed Brown Vec temp_vec; 8980c7d97c5SJed Brown PetscScalar value; 8990c7d97c5SJed Brown 900*d49ef151SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec);CHKERRQ(ierr); 901*d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL);CHKERRQ(ierr); 902*d49ef151SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 903*d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,temp_vec);CHKERRQ(ierr); 904*d49ef151SStefano Zampini ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R);CHKERRQ(ierr); 905*d49ef151SStefano Zampini ierr = VecNorm(temp_vec,NORM_INFINITY,&value);CHKERRQ(ierr); 906*d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 9070c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 9080c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Neumann problem\n");CHKERRQ(ierr); 9090c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 910*d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 911*d49ef151SStefano Zampini ierr = VecDestroy(&temp_vec);CHKERRQ(ierr); 9120c7d97c5SJed Brown } 9130c7d97c5SJed Brown /* free Neumann problem's matrix */ 9140c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 9150c7d97c5SJed Brown } 9160c7d97c5SJed Brown 9170c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 9180c7d97c5SJed Brown { 9190c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 9200c7d97c5SJed Brown Mat M1,M2; 9210c7d97c5SJed Brown Mat C_CR; 9220c7d97c5SJed Brown Mat CMAT,AUXMAT; 9230c7d97c5SJed Brown Vec vec1_C; 9240c7d97c5SJed Brown Vec vec2_C; 9250c7d97c5SJed Brown Vec vec1_V; 9260c7d97c5SJed Brown Vec vec2_V; 9270c7d97c5SJed Brown PetscInt *nnz; 9280c7d97c5SJed Brown PetscInt *auxindices; 92953cdbc3dSStefano Zampini PetscInt index; 9300c7d97c5SJed Brown PetscScalar* array2; 9310c7d97c5SJed Brown MatFactorInfo matinfo; 9320c7d97c5SJed Brown 9330c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 9340c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 9350c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 9360c7d97c5SJed Brown for(i=0;i<pcis->n;i++) {auxindices[i]=i;} 9370c7d97c5SJed Brown 9380c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 9390c7d97c5SJed Brown if(pcbddc->n_vertices) { 9400c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 9410c7d97c5SJed Brown ierr = VecSetSizes(vec1_V,pcbddc->n_vertices,pcbddc->n_vertices);CHKERRQ(ierr); 9420c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 9430c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 9440c7d97c5SJed Brown } 9450c7d97c5SJed Brown if(pcbddc->n_constraints) { 9460c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 9470c7d97c5SJed Brown ierr = VecSetSizes(vec1_C,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 9480c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 9490c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C);CHKERRQ(ierr); 9500c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C);CHKERRQ(ierr); 9510c7d97c5SJed Brown } 9520c7d97c5SJed Brown /* Create C matrix [I 0; 0 const] */ 953*d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&CMAT);CHKERRQ(ierr); 9540c7d97c5SJed Brown ierr = MatSetType(CMAT,MATSEQAIJ);CHKERRQ(ierr); 9550c7d97c5SJed Brown ierr = MatSetSizes(CMAT,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 9560c7d97c5SJed Brown /* nonzeros */ 9570c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { nnz[i]= 1; } 9580c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { nnz[i+pcbddc->n_vertices]=pcbddc->sizes_of_constraint[i];} 9590c7d97c5SJed Brown ierr = MatSeqAIJSetPreallocation(CMAT,0,nnz);CHKERRQ(ierr); 9600c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { 9610c7d97c5SJed Brown ierr = MatSetValue(CMAT,i,pcbddc->vertices[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 9620c7d97c5SJed Brown } 9630c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 96453cdbc3dSStefano Zampini index=i+pcbddc->n_vertices; 96553cdbc3dSStefano Zampini ierr = MatSetValues(CMAT,1,&index,pcbddc->sizes_of_constraint[i],pcbddc->indices_to_constraint[i],pcbddc->quadrature_constraint[i],INSERT_VALUES);CHKERRQ(ierr); 9660c7d97c5SJed Brown } 9670c7d97c5SJed Brown //if(check_flag) printf("CMAT assembling\n"); 9680c7d97c5SJed Brown ierr = MatAssemblyBegin(CMAT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9690c7d97c5SJed Brown ierr = MatAssemblyEnd(CMAT,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9700c7d97c5SJed Brown //ierr = MatView(CMAT,PETSC_VIEWER_STDOUT_SELF); 9710c7d97c5SJed Brown 9720c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 9730c7d97c5SJed Brown 9740c7d97c5SJed Brown if(pcbddc->n_constraints) { 9750c7d97c5SJed Brown /* some work vectors */ 9760c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 9770c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,pcbddc->n_constraints,n_R,pcbddc->n_constraints);CHKERRQ(ierr); 9780c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 9790c7d97c5SJed Brown 9800c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 9810c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 982*d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 9830c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 9840c7d97c5SJed Brown for(j=0;j<pcbddc->sizes_of_constraint[i];j++) { array[ pcbddc->indices_to_constraint[i][j] ] = - pcbddc->quadrature_constraint[i][j]; } 9850c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 9860c7d97c5SJed Brown for(j=0;j<n_R;j++) { array2[j] = array[ idx_R_local[j] ]; } 9870c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 9880c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 98953cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 9900c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 99153cdbc3dSStefano Zampini index=i; 99253cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 9930c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 9940c7d97c5SJed Brown } 9950c7d97c5SJed Brown //if(check_flag) printf("pcbddc->local_auxmat2 assembling\n"); 9960c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9970c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9980c7d97c5SJed Brown 9990c7d97c5SJed Brown /* Create Constraint matrix on R nodes: C_{CR} */ 10000c7d97c5SJed Brown ierr = MatGetSubMatrix(CMAT,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 10010c7d97c5SJed Brown ierr = ISDestroy(&is_C_local);CHKERRQ(ierr); 10020c7d97c5SJed Brown 10030c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 10040c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT);CHKERRQ(ierr); 1005*d49ef151SStefano Zampini ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); 10060c7d97c5SJed Brown ierr = ISCreateStride (PETSC_COMM_SELF,pcbddc->n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 10070c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 10080c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 10090c7d97c5SJed Brown 10100c7d97c5SJed Brown /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc (should be dense) */ 1011*d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M1);CHKERRQ(ierr); 10120c7d97c5SJed Brown ierr = MatSetSizes(M1,pcbddc->n_constraints,pcbddc->n_constraints,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 10130c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 10140c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 10150c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 10160c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 10170c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 10180c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 10190c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 10200c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 10210c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 102253cdbc3dSStefano Zampini index=i; 102353cdbc3dSStefano Zampini ierr = MatSetValues(M1,pcbddc->n_constraints,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 10240c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 10250c7d97c5SJed Brown } 10260c7d97c5SJed Brown //if(check_flag) printf("M1 assembling\n"); 10270c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10280c7d97c5SJed Brown ierr = MatAssemblyEnd (M1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10290c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 10300c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 10310c7d97c5SJed Brown //if(check_flag) printf("pcbddc->local_auxmat1 computing and assembling\n"); 10320c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 10330c7d97c5SJed Brown 10340c7d97c5SJed Brown } 10350c7d97c5SJed Brown 10360c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 10370c7d97c5SJed Brown if(pcbddc->n_vertices){ 10380c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 10390c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 10400c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 10410c7d97c5SJed Brown /* Assemble M2 = A_RR^{-1}A_RV */ 1042*d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&M2);CHKERRQ(ierr); 10430c7d97c5SJed Brown ierr = MatSetSizes(M2,n_R,pcbddc->n_vertices,n_R,pcbddc->n_vertices);CHKERRQ(ierr); 10440c7d97c5SJed Brown ierr = MatSetType(M2,impMatType);CHKERRQ(ierr); 10450c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { 10460c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 10470c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 10480c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 10490c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 10500c7d97c5SJed Brown ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 105153cdbc3dSStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 105253cdbc3dSStefano Zampini index=i; 10530c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 105453cdbc3dSStefano Zampini ierr = MatSetValues(M2,n_R,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 10550c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 10560c7d97c5SJed Brown } 10570c7d97c5SJed Brown //if(check_flag) printf("M2 assembling\n"); 10580c7d97c5SJed Brown ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10590c7d97c5SJed Brown ierr = MatAssemblyEnd (M2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10600c7d97c5SJed Brown } 10610c7d97c5SJed Brown 10620c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1063*d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 10640c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 10650c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 10660c7d97c5SJed Brown if(pcbddc->prec_type || check_flag ) { 1067*d49ef151SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 10680c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 10690c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 10700c7d97c5SJed Brown } 10710c7d97c5SJed Brown 10720c7d97c5SJed Brown /* Subdomain contribution (Non-overlapping) to coarse matrix */ 10730c7d97c5SJed Brown if(check_flag) { 10740c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 10750c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 10760c7d97c5SJed Brown } 10770c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 10780c7d97c5SJed Brown 10790c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 10800c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++){ 10810c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 10820c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 10830c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 10840c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 10850c7d97c5SJed Brown /* solution of saddle point problem */ 10860c7d97c5SJed Brown ierr = MatMult(M2,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 10870c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 10880c7d97c5SJed Brown if(pcbddc->n_constraints) { 10890c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 10900c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 10910c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 10920c7d97c5SJed Brown } 10930c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 10940c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 10950c7d97c5SJed Brown 10960c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 10970c7d97c5SJed Brown /* coarse basis functions */ 109853cdbc3dSStefano Zampini index=i; 10990c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 11000c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11010c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11020c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 110353cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 11040c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 11050c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 11060c7d97c5SJed Brown if( pcbddc->prec_type || check_flag ) { 11070c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11080c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11090c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 111053cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 11110c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 11120c7d97c5SJed Brown } 11130c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 11140c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 11150c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) {coarse_submat_vals[i*pcbddc->local_primal_size+j]=array[j];} //WARNING -> column major ordering 11160c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 11170c7d97c5SJed Brown if( pcbddc->n_constraints) { 11180c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 11190c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) {coarse_submat_vals[i*pcbddc->local_primal_size+j+pcbddc->n_vertices]=array[j];} //WARNING -> column major ordering 11200c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 11210c7d97c5SJed Brown } 11220c7d97c5SJed Brown 11230c7d97c5SJed Brown if( check_flag ) { 11240c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1125*d49ef151SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 11260c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11270c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 11280c7d97c5SJed Brown for(j=0;j<n_R;j++) { array[idx_R_local[j]] = array2[j]; } 11290c7d97c5SJed Brown array[ pcbddc->vertices[i] ] = one; 11300c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 11310c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11320c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1133*d49ef151SStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 11340c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 11350c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 11360c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) { array2[j]=array[j]; } 11370c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 11380c7d97c5SJed Brown if(pcbddc->n_constraints) { 11390c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 11400c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) { array2[j+pcbddc->n_vertices]=array[j]; } 11410c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 11420c7d97c5SJed Brown } 11430c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 11440c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 11450c7d97c5SJed Brown /* check saddle point solution */ 11460c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 114753cdbc3dSStefano Zampini ierr = MatMultTransposeAdd(CMAT,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 114853cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 11490c7d97c5SJed Brown ierr = MatMult(CMAT,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 11500c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 115153cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 11520c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 115353cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 11540c7d97c5SJed Brown } 11550c7d97c5SJed Brown } 11560c7d97c5SJed Brown 11570c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++){ 1158*d49ef151SStefano Zampini ierr = VecSet(vec2_C,zero);CHKERRQ(ierr); 11590c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 11600c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 11610c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 11620c7d97c5SJed Brown /* solution of saddle point problem */ 11630c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 11640c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 11650c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 11660c7d97c5SJed Brown if(pcbddc->n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 11670c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 11680c7d97c5SJed Brown /* coarse basis functions */ 116953cdbc3dSStefano Zampini index=i+pcbddc->n_vertices; 11700c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 11710c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11720c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11730c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 117453cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 11750c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 11760c7d97c5SJed Brown if( pcbddc->prec_type || check_flag ) { 11770c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11780c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 11790c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 118053cdbc3dSStefano Zampini ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,&index,array,INSERT_VALUES);CHKERRQ(ierr); 11810c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 11820c7d97c5SJed Brown } 11830c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 11840c7d97c5SJed Brown if(pcbddc->n_vertices) { 11850c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 118653cdbc3dSStefano Zampini for(j=0;j<pcbddc->n_vertices;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j]=array[j];} //WARNING -> column major ordering 11870c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 11880c7d97c5SJed Brown } 11890c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 119053cdbc3dSStefano Zampini for(j=0;j<pcbddc->n_constraints;j++) {coarse_submat_vals[index*pcbddc->local_primal_size+j+pcbddc->n_vertices]=array[j];} //WARNING -> column major ordering 11910c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 11920c7d97c5SJed Brown 11930c7d97c5SJed Brown if( check_flag ) { 11940c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 119553cdbc3dSStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 11960c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 11970c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 11980c7d97c5SJed Brown for(j=0;j<n_R;j++){ array[ idx_R_local[j] ] = array2[j]; } 11990c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 12000c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 12010c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 120253cdbc3dSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 12030c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 12040c7d97c5SJed Brown if( pcbddc->n_vertices) { 12050c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 12060c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) {array2[j]=-array[j];} 12070c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 12080c7d97c5SJed Brown } 12090c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 12100c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) {array2[j+pcbddc->n_vertices]=-array[j];} 12110c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 12120c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 12130c7d97c5SJed Brown /* check saddle point solution */ 12140c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 1215*d49ef151SStefano Zampini ierr = MatMultTransposeAdd(CMAT,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N);CHKERRQ(ierr); 121653cdbc3dSStefano Zampini ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index]);CHKERRQ(ierr); 12170c7d97c5SJed Brown ierr = MatMult(CMAT,pcis->vec1_N,pcbddc->vec1_P);CHKERRQ(ierr); 12180c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 121953cdbc3dSStefano Zampini array[index]=array[index]+m_one; /* shift by the identity matrix */ 12200c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 122153cdbc3dSStefano Zampini ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index]);CHKERRQ(ierr); 12220c7d97c5SJed Brown } 12230c7d97c5SJed Brown } 12240c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12250c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12260c7d97c5SJed Brown if( pcbddc->prec_type || check_flag ) { 12270c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12280c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12290c7d97c5SJed Brown } 12300c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 12310c7d97c5SJed Brown /* It shuld be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 12320c7d97c5SJed Brown if(check_flag) { 12330c7d97c5SJed Brown 12340c7d97c5SJed Brown Mat coarse_sub_mat; 12350c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 12360c7d97c5SJed Brown Mat coarse_phi_D,coarse_phi_B,A_II,A_BB,A_IB,A_BI; 12370c7d97c5SJed Brown const MatType checkmattype; 12380c7d97c5SJed Brown PetscScalar value; 12390c7d97c5SJed Brown 12400c7d97c5SJed Brown ierr = MatGetType(matis->A,&checkmattype);CHKERRQ(ierr); 12410c7d97c5SJed Brown ierr = MatGetType(pcis->A_II,&checkmattype);CHKERRQ(ierr); 12420c7d97c5SJed Brown checkmattype = MATSEQAIJ; 1243c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 1244c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 1245c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 1246c042a7c3SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 1247c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 1248c042a7c3SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 1249c042a7c3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 1250c042a7c3SStefano Zampini ierr = MatConvert(coarse_sub_mat,checkmattype,MAT_REUSE_MATRIX,&coarse_sub_mat);CHKERRQ(ierr); 12510c7d97c5SJed Brown 12520c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 12530c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 12540c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 125553cdbc3dSStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 125653cdbc3dSStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 125753cdbc3dSStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1258c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 125953cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 126053cdbc3dSStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 1261c042a7c3SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 126253cdbc3dSStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 126353cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 126453cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 126553cdbc3dSStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 126653cdbc3dSStefano Zampini ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 126753cdbc3dSStefano Zampini ierr = MatNorm(TM1,NORM_INFINITY,&value);CHKERRQ(ierr); 12680c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 12690c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 12700c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 12710c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions errors\n");CHKERRQ(ierr); 127253cdbc3dSStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,coarsefunctions_errors[i]);CHKERRQ(ierr); } 12730c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints errors\n");CHKERRQ(ierr); 127453cdbc3dSStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,constraints_errors[i]);CHKERRQ(ierr); } 12750c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 127653cdbc3dSStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 127753cdbc3dSStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 127853cdbc3dSStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 127953cdbc3dSStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 128053cdbc3dSStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 128153cdbc3dSStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 128253cdbc3dSStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 128353cdbc3dSStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 128453cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 128553cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 128653cdbc3dSStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 12870c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 12880c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 12890c7d97c5SJed Brown } 12900c7d97c5SJed Brown 12910c7d97c5SJed Brown /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 12920c7d97c5SJed Brown ierr = PCBDDCSetupCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 12930c7d97c5SJed Brown /* free memory */ 12940c7d97c5SJed Brown ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 12950c7d97c5SJed Brown ierr = PetscFree(auxindices);CHKERRQ(ierr); 12960c7d97c5SJed Brown ierr = PetscFree(nnz);CHKERRQ(ierr); 12970c7d97c5SJed Brown if(pcbddc->n_vertices) { 12980c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 12990c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 13000c7d97c5SJed Brown ierr = MatDestroy(&M2);CHKERRQ(ierr); 13010c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 13020c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 13030c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 13040c7d97c5SJed Brown } 13050c7d97c5SJed Brown if(pcbddc->n_constraints) { 13060c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 13070c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 13080c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 13090c7d97c5SJed Brown ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 13100c7d97c5SJed Brown } 13110c7d97c5SJed Brown ierr = MatDestroy(&CMAT);CHKERRQ(ierr); 13120c7d97c5SJed Brown } 13130c7d97c5SJed Brown /* free memory */ 13140c7d97c5SJed Brown if(pcbddc->n_vertices) { 13150c7d97c5SJed Brown ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 13160c7d97c5SJed Brown ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 13170c7d97c5SJed Brown } 13180c7d97c5SJed Brown ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 13190c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 13200c7d97c5SJed Brown 13210c7d97c5SJed Brown PetscFunctionReturn(0); 13220c7d97c5SJed Brown } 13230c7d97c5SJed Brown 13240c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 13250c7d97c5SJed Brown 13260c7d97c5SJed Brown #undef __FUNCT__ 13270c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetupCoarseEnvironment" 132853cdbc3dSStefano Zampini static PetscErrorCode PCBDDCSetupCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 13290c7d97c5SJed Brown { 13300c7d97c5SJed Brown 13310c7d97c5SJed Brown 13320c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 13330c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 13340c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 13350c7d97c5SJed Brown MPI_Comm prec_comm = ((PetscObject)pc)->comm; 13360c7d97c5SJed Brown MPI_Comm coarse_comm; 13370c7d97c5SJed Brown 13380c7d97c5SJed Brown /* common to all choiches */ 13390c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 13400c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 13410c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 13420c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 13430c7d97c5SJed Brown PetscMPIInt size_prec_comm; 13440c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 13450c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 13460c7d97c5SJed Brown PetscMPIInt master_proc=0; 13470c7d97c5SJed Brown PetscInt ins_local_primal_size; 13480c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 13490c7d97c5SJed Brown PetscMPIInt *ranks_recv; 13500c7d97c5SJed Brown PetscMPIInt count_recv=0; 13510c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 13520c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 13530c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 13540c7d97c5SJed Brown /* some other variables */ 13550c7d97c5SJed Brown PetscErrorCode ierr; 13560c7d97c5SJed Brown const MatType coarse_mat_type; 13570c7d97c5SJed Brown const PCType coarse_pc_type; 135853cdbc3dSStefano Zampini const KSPType coarse_ksp_type; 135953cdbc3dSStefano Zampini PC pc_temp; 13600c7d97c5SJed Brown PetscInt i,j,k,bs; 13610c7d97c5SJed Brown 13620c7d97c5SJed Brown PetscFunctionBegin; 13630c7d97c5SJed Brown 13640c7d97c5SJed Brown ins_local_primal_indices = 0; 13650c7d97c5SJed Brown ins_coarse_mat_vals = 0; 13660c7d97c5SJed Brown localsizes2 = 0; 13670c7d97c5SJed Brown localdispl2 = 0; 13680c7d97c5SJed Brown temp_coarse_mat_vals = 0; 13690c7d97c5SJed Brown coarse_ISLG = 0; 13700c7d97c5SJed Brown 137153cdbc3dSStefano Zampini ierr = MPI_Comm_size(prec_comm,&size_prec_comm);CHKERRQ(ierr); 137253cdbc3dSStefano Zampini ierr = MPI_Comm_rank(prec_comm,&rank_prec_comm);CHKERRQ(ierr); 13730c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 13740c7d97c5SJed Brown 1375beed3852SStefano Zampini /* Assign global numbering to coarse dofs */ 1376beed3852SStefano Zampini { 1377beed3852SStefano Zampini PetscScalar coarsesum,one=1.,zero=0.; 1378beed3852SStefano Zampini PetscScalar *array; 1379beed3852SStefano Zampini PetscMPIInt *auxlocal_primal; 1380beed3852SStefano Zampini PetscMPIInt *auxglobal_primal; 1381beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal; 1382beed3852SStefano Zampini PetscMPIInt *all_auxglobal_primal_dummy; 1383beed3852SStefano Zampini PetscMPIInt mpi_local_primal_size = (PetscMPIInt)pcbddc->local_primal_size; 1384beed3852SStefano Zampini 1385beed3852SStefano Zampini /* Construct needed data structures for message passing */ 1386beed3852SStefano Zampini ierr = PetscMalloc(mpi_local_primal_size*sizeof(PetscMPIInt),&pcbddc->local_primal_indices);CHKERRQ(ierr); 1387beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_sizes);CHKERRQ(ierr); 1388beed3852SStefano Zampini ierr = PetscMalloc(size_prec_comm*sizeof(PetscMPIInt),&pcbddc->local_primal_displacements);CHKERRQ(ierr); 1389beed3852SStefano Zampini /* Gather local_primal_size information for all processes */ 1390beed3852SStefano Zampini ierr = MPI_Gather(&mpi_local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1391beed3852SStefano Zampini pcbddc->replicated_primal_size = 0; 1392beed3852SStefano Zampini if(rank_prec_comm == 0) { 1393beed3852SStefano Zampini for (i=0; i<size_prec_comm; i++) { 1394beed3852SStefano Zampini pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 1395beed3852SStefano Zampini pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 1396beed3852SStefano Zampini } 1397beed3852SStefano Zampini /* allocate some auxiliary space */ 1398beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal),&all_auxglobal_primal);CHKERRQ(ierr); 1399beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->replicated_primal_size*sizeof(*all_auxglobal_primal_dummy),&all_auxglobal_primal_dummy);CHKERRQ(ierr); 1400beed3852SStefano Zampini } 1401beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxlocal_primal);CHKERRQ(ierr); 1402beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->local_primal_size*sizeof(PetscMPIInt),&auxglobal_primal);CHKERRQ(ierr); 1403beed3852SStefano Zampini 1404beed3852SStefano Zampini /* First let's count coarse dofs: note that we allow to have a constraint on a subdomain and not its counterpart on the neighbour subdomain (if user wants) 1405beed3852SStefano Zampini This code fragment assumes that the number of local constraints per connected component 1406beed3852SStefano Zampini is not greater than the number of nodes defined for the connected component 1407beed3852SStefano Zampini (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 1408beed3852SStefano Zampini /* auxlocal_primal : primal indices in local nodes numbering (internal and interface) */ 1409beed3852SStefano Zampini ierr = VecSet(pcis->vec1_N,zero);CHKERRQ(ierr); 1410beed3852SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1411beed3852SStefano Zampini for(i=0;i<pcbddc->n_vertices;i++) { 1412beed3852SStefano Zampini array[ pcbddc->vertices[i] ] = one; 1413beed3852SStefano Zampini auxlocal_primal[i] = pcbddc->vertices[i]; 1414beed3852SStefano Zampini } 1415beed3852SStefano Zampini for(i=0;i<pcbddc->n_constraints;i++) { 1416beed3852SStefano Zampini for (j=0; j<pcbddc->sizes_of_constraint[i]; j++) { 1417beed3852SStefano Zampini k = pcbddc->indices_to_constraint[i][j]; 1418beed3852SStefano Zampini if( array[k] == zero ) { 1419beed3852SStefano Zampini array[k] = one; 1420beed3852SStefano Zampini auxlocal_primal[i+pcbddc->n_vertices] = k; 1421beed3852SStefano Zampini break; 1422beed3852SStefano Zampini } 1423beed3852SStefano Zampini } 1424beed3852SStefano Zampini } 1425beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1426beed3852SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1427beed3852SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1428beed3852SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1429beed3852SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1430beed3852SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1431beed3852SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1432*d49ef151SStefano Zampini for(i=0;i<pcis->n;i++) { if(array[i] > 0.0) array[i] = one/array[i]; } 1433beed3852SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1434beed3852SStefano Zampini ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 1435beed3852SStefano Zampini ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1436beed3852SStefano Zampini ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1437beed3852SStefano Zampini 1438beed3852SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 1439beed3852SStefano Zampini pcbddc->coarse_size = (PetscInt) coarsesum; 1440beed3852SStefano Zampini //if(check_flag) { 1441beed3852SStefano Zampini // ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1442beed3852SStefano Zampini // ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem = %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 1443beed3852SStefano Zampini // ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1444beed3852SStefano Zampini //} 1445beed3852SStefano Zampini /* Now assign them a global numbering */ 1446beed3852SStefano Zampini /* auxglobal_primal contains indices in global nodes numbering (internal and interface) */ 1447beed3852SStefano Zampini ierr = ISLocalToGlobalMappingApply(matis->mapping,pcbddc->local_primal_size,auxlocal_primal,auxglobal_primal);CHKERRQ(ierr); 1448beed3852SStefano Zampini /* all_auxglobal_primal contains all primal nodes indices in global nodes numbering (internal and interface) */ 1449beed3852SStefano Zampini ierr = MPI_Gatherv(&auxglobal_primal[0],pcbddc->local_primal_size,MPIU_INT,&all_auxglobal_primal[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1450beed3852SStefano Zampini 1451beed3852SStefano Zampini /* After this block all_auxglobal_primal should contains one copy of each primal node's indices in global nodes numbering */ 1452beed3852SStefano Zampini /* It implements a function similar to PetscSortRemoveDupsInt */ 1453beed3852SStefano Zampini if(rank_prec_comm==0) { 1454beed3852SStefano Zampini /* dummy argument since PetscSortMPIInt doesn't exist! */ 1455beed3852SStefano Zampini ierr = PetscSortMPIIntWithArray(pcbddc->replicated_primal_size,all_auxglobal_primal,all_auxglobal_primal_dummy);CHKERRQ(ierr); 1456beed3852SStefano Zampini k=1; 1457beed3852SStefano Zampini j=all_auxglobal_primal[0]; /* first dof in global numbering */ 1458beed3852SStefano Zampini for(i=1;i< pcbddc->replicated_primal_size ;i++) { 1459beed3852SStefano Zampini if(j != all_auxglobal_primal[i] ) { 1460beed3852SStefano Zampini all_auxglobal_primal[k]=all_auxglobal_primal[i]; 1461beed3852SStefano Zampini k++; 1462beed3852SStefano Zampini j=all_auxglobal_primal[i]; 1463beed3852SStefano Zampini } 1464beed3852SStefano Zampini } 1465beed3852SStefano Zampini } else { 1466beed3852SStefano Zampini ierr = PetscMalloc(pcbddc->coarse_size*sizeof(PetscMPIInt),&all_auxglobal_primal);CHKERRQ(ierr); 1467beed3852SStefano Zampini } 1468beed3852SStefano Zampini /* We only need to broadcast the indices from 0 to pcbddc->coarse_size. Remaning elements of array are garbage. */ 1469beed3852SStefano Zampini ierr = MPI_Bcast(all_auxglobal_primal,pcbddc->coarse_size,MPIU_INT,0,prec_comm);CHKERRQ(ierr); 1470beed3852SStefano Zampini 1471beed3852SStefano Zampini /* Now get global coarse numbering of local primal nodes */ 1472beed3852SStefano Zampini for(i=0;i<pcbddc->local_primal_size;i++) { 1473beed3852SStefano Zampini k=0; 1474beed3852SStefano Zampini while( all_auxglobal_primal[k] != auxglobal_primal[i] ) { k++;} 1475beed3852SStefano Zampini pcbddc->local_primal_indices[i]=k; 1476beed3852SStefano Zampini } 1477beed3852SStefano Zampini //if(check_flag) { 1478beed3852SStefano Zampini // ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1479beed3852SStefano Zampini // ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 1480beed3852SStefano Zampini // ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1481beed3852SStefano Zampini // ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 1482beed3852SStefano Zampini // for(i=0;i<pcbddc->local_primal_size;i++) { 1483beed3852SStefano Zampini // ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 1484beed3852SStefano Zampini // } 1485beed3852SStefano Zampini // ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1486beed3852SStefano Zampini //} 1487beed3852SStefano Zampini /* free allocated memory */ 1488beed3852SStefano Zampini ierr = PetscFree(auxlocal_primal);CHKERRQ(ierr); 1489beed3852SStefano Zampini ierr = PetscFree(auxglobal_primal);CHKERRQ(ierr); 1490beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal);CHKERRQ(ierr); 1491beed3852SStefano Zampini ierr = PetscFree(all_auxglobal_primal_dummy);CHKERRQ(ierr); 1492beed3852SStefano Zampini } 1493beed3852SStefano Zampini 14940c7d97c5SJed Brown /* adapt coarse problem type */ 14950c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC && pcbddc->active_procs < MIN_PROCS_FOR_BDDC ) 14960c7d97c5SJed Brown pcbddc->coarse_problem_type = PARALLEL_BDDC; 14970c7d97c5SJed Brown 14980c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 14990c7d97c5SJed Brown 15000c7d97c5SJed Brown case(MULTILEVEL_BDDC): //we define a coarse mesh where subdomains are elements 15010c7d97c5SJed Brown { 15020c7d97c5SJed Brown /* we need additional variables */ 15030c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 15040c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 15050c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 15060c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 15070c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 15080c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 15090c7d97c5SJed Brown PetscMPIInt *total_count_recv; 15100c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 15110c7d97c5SJed Brown PetscMPIInt *displacements_recv; 15120c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 15130c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 15140c7d97c5SJed Brown MetisInt *faces_adjncy; 15150c7d97c5SJed Brown MetisInt *faces_xadj; 15160c7d97c5SJed Brown PetscMPIInt *number_of_faces; 15170c7d97c5SJed Brown PetscMPIInt *faces_displacements; 15180c7d97c5SJed Brown PetscInt *array_int; 15190c7d97c5SJed Brown PetscMPIInt my_faces=0; 15200c7d97c5SJed Brown PetscMPIInt total_faces=0; 15210c7d97c5SJed Brown 15220c7d97c5SJed Brown /* this code has a bug (see below) for more then three levels -> I can solve it quickly */ 15230c7d97c5SJed Brown 15240c7d97c5SJed Brown /* define some quantities */ 15250c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 15260c7d97c5SJed Brown coarse_mat_type = MATIS; 15270c7d97c5SJed Brown coarse_pc_type = PCBDDC; 152853cdbc3dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 15290c7d97c5SJed Brown 15300c7d97c5SJed Brown /* details of coarse decomposition */ 15310c7d97c5SJed Brown n_subdomains = pcbddc->active_procs; 15320c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 15330c7d97c5SJed Brown procs_jumps_coarse_comm = pcbddc->coarsening_ratio*(size_prec_comm/pcbddc->active_procs); 15340c7d97c5SJed Brown 15350c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 153653cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&pcbddc->local_primal_indices[0],pcbddc->local_primal_size,MPIU_INT,&pcbddc->replicated_local_primal_indices[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_INT,prec_comm);CHKERRQ(ierr); 15370c7d97c5SJed Brown 15380c7d97c5SJed Brown /* build CSR graph of subdomains' connectivity through faces */ 15390c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 15400c7d97c5SJed Brown PetscMemzero(array_int,pcis->n*sizeof(PetscInt)); 15410c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 15420c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 15430c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 15440c7d97c5SJed Brown } 15450c7d97c5SJed Brown } 15460c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 15470c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 15480c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 15490c7d97c5SJed Brown my_faces++; 15500c7d97c5SJed Brown break; 15510c7d97c5SJed Brown } 15520c7d97c5SJed Brown } 15530c7d97c5SJed Brown } 15540c7d97c5SJed Brown //printf("I found %d faces.\n",my_faces); 15550c7d97c5SJed Brown 155653cdbc3dSStefano Zampini ierr = MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm);CHKERRQ(ierr); 15570c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 15580c7d97c5SJed Brown my_faces=0; 15590c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 15600c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 15610c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 15620c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 15630c7d97c5SJed Brown my_faces++; 15640c7d97c5SJed Brown break; 15650c7d97c5SJed Brown } 15660c7d97c5SJed Brown } 15670c7d97c5SJed Brown } 15680c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 15690c7d97c5SJed Brown //printf("I found %d total faces.\n",total_faces); 15700c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 15710c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 15720c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 15730c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 15740c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 15750c7d97c5SJed Brown } 157653cdbc3dSStefano Zampini ierr = MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 15770c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 15780c7d97c5SJed Brown faces_xadj[0]=0; 15790c7d97c5SJed Brown faces_displacements[0]=0; 15800c7d97c5SJed Brown j=0; 15810c7d97c5SJed Brown for(i=1;i<size_prec_comm+1;i++) { 15820c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 15830c7d97c5SJed Brown if(number_of_faces[i-1]) { 15840c7d97c5SJed Brown j++; 15850c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 15860c7d97c5SJed Brown } 15870c7d97c5SJed Brown } 15880c7d97c5SJed Brown printf("The J I count is %d and should be %d\n",j,n_subdomains); 15890c7d97c5SJed Brown printf("Total faces seem %d and should be %d\n",faces_xadj[j],total_faces); 15900c7d97c5SJed Brown } 159153cdbc3dSStefano Zampini ierr = MPI_Gatherv(&my_faces_connectivity[0],my_faces,MPIU_INT,&petsc_faces_adjncy[0],number_of_faces,faces_displacements,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 15920c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 15930c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 15940c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 15950c7d97c5SJed Brown for(i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]); ///procs_jumps_coarse_comm); // cast to MetisInt 15960c7d97c5SJed Brown printf("This is the face connectivity (%d)\n",procs_jumps_coarse_comm); 15970c7d97c5SJed Brown for(i=0;i<n_subdomains;i++){ 15980c7d97c5SJed Brown printf("proc %d is connected with \n",i); 15990c7d97c5SJed Brown for(j=faces_xadj[i];j<faces_xadj[i+1];j++) 16000c7d97c5SJed Brown printf("%d ",faces_adjncy[j]); 16010c7d97c5SJed Brown printf("\n"); 16020c7d97c5SJed Brown } 16030c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 16040c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 16050c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 16060c7d97c5SJed Brown } 16070c7d97c5SJed Brown 16080c7d97c5SJed Brown if( rank_prec_comm == master_proc ) { 16090c7d97c5SJed Brown 16100c7d97c5SJed Brown ncon=1; 16110c7d97c5SJed Brown faces_nvtxs=n_subdomains; 16120c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 16130c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 16140c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 16150c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 16160c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 16170c7d97c5SJed Brown options[METIS_OPTION_DBGLVL]=1; 16180c7d97c5SJed Brown options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 16190c7d97c5SJed Brown options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 16200c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 16210c7d97c5SJed Brown //options[METIS_OPTION_NCUTS]=1; 16220c7d97c5SJed Brown //printf("METIS PART GRAPH\n"); 16230c7d97c5SJed Brown /* BUG: faces_xadj and faces_adjncy content must be adapted using the coarsening factor*/ 16240c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 16250c7d97c5SJed Brown //printf("OKOKOKOKOKOKOKOK\n"); 16260c7d97c5SJed Brown if(ierr != METIS_OK) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in METIS_PartGraphKway (metis error code %D) called from PCBDDCSetupCoarseEnvironment\n",ierr); 16270c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 16280c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 16290c7d97c5SJed Brown coarse_subdivision = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); /* calloc for contiguous memory since we need to scatter these values later */ 16300c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 16310c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL;; 16320c7d97c5SJed Brown k=size_prec_comm/pcbddc->active_procs; 16330c7d97c5SJed Brown for(i=0;i<n_subdomains;i++) coarse_subdivision[k*i]=(PetscInt)(metis_coarse_subdivision[i]); 16340c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 16350c7d97c5SJed Brown 16360c7d97c5SJed Brown } 16370c7d97c5SJed Brown 16380c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 16390c7d97c5SJed Brown if( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 16400c7d97c5SJed Brown coarse_color=0; //for communicator splitting 16410c7d97c5SJed Brown active_rank=rank_prec_comm; //for insertion of matrix values 16420c7d97c5SJed Brown } 16430c7d97c5SJed Brown // procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 16440c7d97c5SJed Brown // key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator 164553cdbc3dSStefano Zampini ierr = MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm);CHKERRQ(ierr); 16460c7d97c5SJed Brown 16470c7d97c5SJed Brown if( coarse_color == 0 ) { 164853cdbc3dSStefano Zampini ierr = MPI_Comm_size(coarse_comm,&size_coarse_comm);CHKERRQ(ierr); 164953cdbc3dSStefano Zampini ierr = MPI_Comm_rank(coarse_comm,&rank_coarse_comm);CHKERRQ(ierr); 16500c7d97c5SJed Brown //printf("Details of coarse comm\n"); 16510c7d97c5SJed Brown //printf("size = %d, myrank = %d\n",size_coarse_comm,rank_coarse_comm); 16520c7d97c5SJed Brown //printf("jumps = %d, coarse_color = %d, n_parts = %d\n",procs_jumps_coarse_comm,coarse_color,n_parts); 16530c7d97c5SJed Brown } else { 16540c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 16550c7d97c5SJed Brown } 16560c7d97c5SJed Brown 16570c7d97c5SJed Brown /* master proc take care of arranging and distributing coarse informations */ 16580c7d97c5SJed Brown if(rank_coarse_comm == master_proc) { 16590c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 16600c7d97c5SJed Brown //ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 16610c7d97c5SJed Brown //ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 16620c7d97c5SJed Brown total_count_recv = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); 16630c7d97c5SJed Brown total_ranks_recv = (PetscMPIInt*)calloc(n_subdomains,sizeof(PetscMPIInt)); 16640c7d97c5SJed Brown /* some initializations */ 16650c7d97c5SJed Brown displacements_recv[0]=0; 16660c7d97c5SJed Brown //PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt)); not needed -> calloc initializes to zero 16670c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 16680c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) 16690c7d97c5SJed Brown for(i=0;i<n_subdomains;i++) 16700c7d97c5SJed Brown if(coarse_subdivision[i]==j) 16710c7d97c5SJed Brown total_count_recv[j]++; 16720c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 16730c7d97c5SJed Brown for(i=1;i<size_coarse_comm;i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 16740c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 16750c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 16760c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) { 16770c7d97c5SJed Brown for(i=0;i<n_subdomains;i++) { 16780c7d97c5SJed Brown if(coarse_subdivision[i]==j) { 16790c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 16800c7d97c5SJed Brown total_count_recv[j]=total_count_recv[j]+1; 16810c7d97c5SJed Brown } 16820c7d97c5SJed Brown } 16830c7d97c5SJed Brown } 16840c7d97c5SJed Brown //for(j=0;j<size_coarse_comm;j++) { 16850c7d97c5SJed Brown // printf("process %d in new rank will receive from %d processes (ranks follows)\n",j,total_count_recv[j]); 16860c7d97c5SJed Brown // for(i=0;i<total_count_recv[j];i++) { 16870c7d97c5SJed Brown // printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 16880c7d97c5SJed Brown // } 16890c7d97c5SJed Brown // printf("\n"); 16900c7d97c5SJed Brown // } 16910c7d97c5SJed Brown 16920c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 16930c7d97c5SJed Brown k=size_prec_comm/pcbddc->active_procs; 16940c7d97c5SJed Brown for(i=0;i<n_subdomains;i++) coarse_subdivision[k*i]=coarse_subdivision[k*i]*procs_jumps_coarse_comm; 16950c7d97c5SJed Brown printf("coarse_subdivision in old end new ranks\n"); 16960c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) 16970c7d97c5SJed Brown printf("(%d %d) ",coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 16980c7d97c5SJed Brown printf("\n"); 16990c7d97c5SJed Brown } 17000c7d97c5SJed Brown 17010c7d97c5SJed Brown /* Scatter new decomposition for send details */ 170253cdbc3dSStefano Zampini ierr = MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 17030c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 17040c7d97c5SJed Brown if( coarse_color == 0) { 170553cdbc3dSStefano Zampini ierr = MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 17060c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 170753cdbc3dSStefano Zampini ierr = MPI_Scatterv(&total_ranks_recv[0],total_count_recv,displacements_recv,MPIU_INT,&ranks_recv[0],count_recv,MPIU_INT,master_proc,coarse_comm);CHKERRQ(ierr); 17080c7d97c5SJed Brown } 17090c7d97c5SJed Brown 17100c7d97c5SJed Brown //printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 17110c7d97c5SJed Brown //if(coarse_color == 0) { 17120c7d97c5SJed Brown // printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 17130c7d97c5SJed Brown // for(i=0;i<count_recv;i++) 17140c7d97c5SJed Brown // printf("%d ",ranks_recv[i]); 17150c7d97c5SJed Brown // printf("\n"); 17160c7d97c5SJed Brown //} 17170c7d97c5SJed Brown 17180c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 17190c7d97c5SJed Brown //ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 17200c7d97c5SJed Brown //ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 17210c7d97c5SJed Brown //ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 17220c7d97c5SJed Brown free(coarse_subdivision); 17230c7d97c5SJed Brown free(total_count_recv); 17240c7d97c5SJed Brown free(total_ranks_recv); 17250c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 17260c7d97c5SJed Brown } 17270c7d97c5SJed Brown break; 17280c7d97c5SJed Brown } 17290c7d97c5SJed Brown 17300c7d97c5SJed Brown case(REPLICATED_BDDC): 17310c7d97c5SJed Brown 17320c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 17330c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 17340c7d97c5SJed Brown coarse_pc_type = PCLU; 173553cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 17360c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 17370c7d97c5SJed Brown active_rank = rank_prec_comm; 17380c7d97c5SJed Brown break; 17390c7d97c5SJed Brown 17400c7d97c5SJed Brown case(PARALLEL_BDDC): 17410c7d97c5SJed Brown 17420c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 17430c7d97c5SJed Brown coarse_mat_type = MATMPIAIJ; 17440c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 174553cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 17460c7d97c5SJed Brown coarse_comm = prec_comm; 17470c7d97c5SJed Brown active_rank = rank_prec_comm; 17480c7d97c5SJed Brown break; 17490c7d97c5SJed Brown 17500c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 17510c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 17520c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 17530c7d97c5SJed Brown coarse_pc_type = PCLU; 175453cdbc3dSStefano Zampini coarse_ksp_type = KSPPREONLY; 17550c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 17560c7d97c5SJed Brown active_rank = master_proc; 17570c7d97c5SJed Brown break; 17580c7d97c5SJed Brown } 17590c7d97c5SJed Brown 17600c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 17610c7d97c5SJed Brown 17620c7d97c5SJed Brown case(SCATTERS_BDDC): 17630c7d97c5SJed Brown { 17640c7d97c5SJed Brown if(pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 17650c7d97c5SJed Brown 17660c7d97c5SJed Brown PetscMPIInt send_size; 17670c7d97c5SJed Brown PetscInt *aux_ins_indices; 17680c7d97c5SJed Brown PetscInt ii,jj; 17690c7d97c5SJed Brown MPI_Request *requests; 17700c7d97c5SJed Brown 17710c7d97c5SJed Brown /* allocate auxiliary space */ 17720c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 17730c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 17740c7d97c5SJed Brown /* allocate stuffs for message massing */ 17750c7d97c5SJed Brown ierr = PetscMalloc ( (count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 17760c7d97c5SJed Brown for(i=0;i<count_recv+1;i++) requests[i]=MPI_REQUEST_NULL; 17770c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 17780c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 17790c7d97c5SJed Brown /* fill up quantities */ 17800c7d97c5SJed Brown j=0; 17810c7d97c5SJed Brown for(i=0;i<count_recv;i++){ 17820c7d97c5SJed Brown ii = ranks_recv[i]; 17830c7d97c5SJed Brown localsizes2[i]=pcbddc->local_primal_sizes[ii]*pcbddc->local_primal_sizes[ii]; 17840c7d97c5SJed Brown localdispl2[i]=j; 17850c7d97c5SJed Brown j+=localsizes2[i]; 17860c7d97c5SJed Brown jj = pcbddc->local_primal_displacements[ii]; 17870c7d97c5SJed Brown for(k=0;k<pcbddc->local_primal_sizes[ii];k++) aux_ins_indices[pcbddc->replicated_local_primal_indices[jj+k]]+=1; // it counts the coarse subdomains sharing the coarse node 17880c7d97c5SJed Brown } 17890c7d97c5SJed Brown //printf("aux_ins_indices 1\n"); 17900c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 17910c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 17920c7d97c5SJed Brown //printf("\n"); 17930c7d97c5SJed Brown /* temp_coarse_mat_vals used to store temporarly received matrix values */ 17940c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 17950c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 17960c7d97c5SJed Brown ins_local_primal_size=0; 17970c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 17980c7d97c5SJed Brown if(aux_ins_indices[i]) 17990c7d97c5SJed Brown ins_local_primal_size++; 18000c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 18010c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 18020c7d97c5SJed Brown j=0; 18030c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 18040c7d97c5SJed Brown if(aux_ins_indices[i]) 18050c7d97c5SJed Brown ins_local_primal_indices[j++]=i; 18060c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 18070c7d97c5SJed Brown j=0; 18080c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 18090c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 18100c7d97c5SJed Brown aux_ins_indices[i]=-1; 18110c7d97c5SJed Brown } else { 18120c7d97c5SJed Brown aux_ins_indices[i]=j; 18130c7d97c5SJed Brown j++; 18140c7d97c5SJed Brown } 18150c7d97c5SJed Brown } 18160c7d97c5SJed Brown 18170c7d97c5SJed Brown //printf("New details localsizes2 localdispl2\n"); 18180c7d97c5SJed Brown //for(i=0;i<count_recv;i++) 18190c7d97c5SJed Brown // printf("(%d %d) ",localsizes2[i],localdispl2[i]); 18200c7d97c5SJed Brown //printf("\n"); 18210c7d97c5SJed Brown //printf("aux_ins_indices 2\n"); 18220c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 18230c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 18240c7d97c5SJed Brown //printf("\n"); 18250c7d97c5SJed Brown //printf("ins_local_primal_indices\n"); 18260c7d97c5SJed Brown //for(i=0;i<ins_local_primal_size;i++) 18270c7d97c5SJed Brown // printf("%d ",ins_local_primal_indices[i]); 18280c7d97c5SJed Brown //printf("\n"); 18290c7d97c5SJed Brown //printf("coarse_submat_vals\n"); 18300c7d97c5SJed Brown //for(i=0;i<pcbddc->local_primal_size;i++) 18310c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_size;j++) 18320c7d97c5SJed Brown // printf("(%lf %d %d)\n",coarse_submat_vals[j*pcbddc->local_primal_size+i],pcbddc->local_primal_indices[i],pcbddc->local_primal_indices[j]); 18330c7d97c5SJed Brown //printf("\n"); 18340c7d97c5SJed Brown 18350c7d97c5SJed Brown /* processes partecipating in coarse problem receive matrix data from their friends */ 183653cdbc3dSStefano Zampini for(i=0;i<count_recv;i++) ierr = MPI_Irecv(&temp_coarse_mat_vals[localdispl2[i]],localsizes2[i],MPIU_SCALAR,ranks_recv[i],666,prec_comm,&requests[i]);CHKERRQ(ierr); 18370c7d97c5SJed Brown if(rank_coarse_proc_send_to != MPI_PROC_NULL ) { 18380c7d97c5SJed Brown send_size=pcbddc->local_primal_size*pcbddc->local_primal_size; 183953cdbc3dSStefano Zampini ierr = MPI_Isend(&coarse_submat_vals[0],send_size,MPIU_SCALAR,rank_coarse_proc_send_to,666,prec_comm,&requests[count_recv]);CHKERRQ(ierr); 18400c7d97c5SJed Brown } 184153cdbc3dSStefano Zampini ierr = MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 18420c7d97c5SJed Brown 18430c7d97c5SJed Brown //if(coarse_color == 0) { 18440c7d97c5SJed Brown // printf("temp_coarse_mat_vals\n"); 18450c7d97c5SJed Brown // for(k=0;k<count_recv;k++){ 18460c7d97c5SJed Brown // printf("---- %d ----\n",ranks_recv[k]); 18470c7d97c5SJed Brown // for(i=0;i<pcbddc->local_primal_sizes[ranks_recv[k]];i++) 18480c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_sizes[ranks_recv[k]];j++) 18490c7d97c5SJed Brown // printf("(%lf %d %d)\n",temp_coarse_mat_vals[localdispl2[k]+j*pcbddc->local_primal_sizes[ranks_recv[k]]+i],pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[ranks_recv[k]]+i],pcbddc->replicated_local_primal_indices[pcbddc->local_primal_displacements[ranks_recv[k]]+j]); 18500c7d97c5SJed Brown // printf("\n"); 18510c7d97c5SJed Brown // } 18520c7d97c5SJed Brown //} 18530c7d97c5SJed Brown /* calculate data to insert in coarse mat */ 18540c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 18550c7d97c5SJed Brown PetscMemzero(ins_coarse_mat_vals,ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar)); 18560c7d97c5SJed Brown 18570c7d97c5SJed Brown PetscMPIInt rr,kk,lps,lpd; 18580c7d97c5SJed Brown PetscInt row_ind,col_ind; 18590c7d97c5SJed Brown for(k=0;k<count_recv;k++){ 18600c7d97c5SJed Brown rr = ranks_recv[k]; 18610c7d97c5SJed Brown kk = localdispl2[k]; 18620c7d97c5SJed Brown lps = pcbddc->local_primal_sizes[rr]; 18630c7d97c5SJed Brown lpd = pcbddc->local_primal_displacements[rr]; 18640c7d97c5SJed Brown //printf("Inserting the following indices (received from %d)\n",rr); 18650c7d97c5SJed Brown for(j=0;j<lps;j++){ 18660c7d97c5SJed Brown col_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+j]]; 18670c7d97c5SJed Brown for(i=0;i<lps;i++){ 18680c7d97c5SJed Brown row_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+i]]; 18690c7d97c5SJed Brown //printf("%d %d\n",row_ind,col_ind); 18700c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*ins_local_primal_size+row_ind]+=temp_coarse_mat_vals[kk+j*lps+i]; 18710c7d97c5SJed Brown } 18720c7d97c5SJed Brown } 18730c7d97c5SJed Brown } 18740c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 18750c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 18760c7d97c5SJed Brown ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); 18770c7d97c5SJed Brown if(coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 18780c7d97c5SJed Brown 18790c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 18800c7d97c5SJed Brown { 18810c7d97c5SJed Brown IS coarse_IS; 188253cdbc3dSStefano Zampini if(coarse_comm != MPI_COMM_NULL ) ierr = MPI_Comm_free(&coarse_comm);CHKERRQ(ierr); 18830c7d97c5SJed Brown coarse_comm = prec_comm; 18840c7d97c5SJed Brown active_rank=rank_prec_comm; 18850c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 18860c7d97c5SJed Brown //ierr = ISSetBlockSize(coarse_IS,bs);CHKERRQ(ierr); 18870c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 18880c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 18890c7d97c5SJed Brown } 18900c7d97c5SJed Brown } 18910c7d97c5SJed Brown if(pcbddc->coarse_problem_type==PARALLEL_BDDC) { 18920c7d97c5SJed Brown /* arrays for values insertion */ 18930c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 18940c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 18950c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 18960c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 18970c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 18980c7d97c5SJed Brown for(i=0;i<ins_local_primal_size;i++) ins_coarse_mat_vals[j*ins_local_primal_size+i]=coarse_submat_vals[j*ins_local_primal_size+i]; 18990c7d97c5SJed Brown } 19000c7d97c5SJed Brown } 19010c7d97c5SJed Brown break; 19020c7d97c5SJed Brown 19030c7d97c5SJed Brown } 19040c7d97c5SJed Brown 19050c7d97c5SJed Brown case(GATHERS_BDDC): 19060c7d97c5SJed Brown { 19070c7d97c5SJed Brown 19080c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 19090c7d97c5SJed Brown 19100c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 19110c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 19120c7d97c5SJed Brown pcbddc->replicated_local_primal_values = (PetscScalar*)calloc(pcbddc->replicated_primal_size,sizeof(PetscScalar)); 19130c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 19140c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 19150c7d97c5SJed Brown /* arrays for values insertion */ 19160c7d97c5SJed Brown ins_local_primal_size = pcbddc->coarse_size; 19170c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 19180c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 19190c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 19200c7d97c5SJed Brown localdispl2[0]=0; 19210c7d97c5SJed Brown for(i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 19220c7d97c5SJed Brown j=0; 19230c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 19240c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 19250c7d97c5SJed Brown } 19260c7d97c5SJed Brown 19270c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 19280c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 19290c7d97c5SJed Brown if(pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 193053cdbc3dSStefano Zampini ierr = MPI_Gatherv(&pcbddc->local_primal_indices[0],mysize,MPIU_INT,&pcbddc->replicated_local_primal_indices[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_INT,master_proc,prec_comm);CHKERRQ(ierr); 193153cdbc3dSStefano Zampini ierr = MPI_Gatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,master_proc,prec_comm);CHKERRQ(ierr); 19320c7d97c5SJed Brown } else { 193353cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&pcbddc->local_primal_indices[0],mysize,MPIU_INT,&pcbddc->replicated_local_primal_indices[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_INT,prec_comm);CHKERRQ(ierr); 193453cdbc3dSStefano Zampini ierr = MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm);CHKERRQ(ierr); 19350c7d97c5SJed Brown } 19360c7d97c5SJed Brown 19370c7d97c5SJed Brown /* free data structures no longer needed and allocate some space which will be needed in BDDC application */ 19380c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 19390c7d97c5SJed Brown PetscInt offset,offset2,row_ind,col_ind; 19400c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 19410c7d97c5SJed Brown ins_local_primal_indices[j]=j; 19420c7d97c5SJed Brown for(i=0;i<ins_local_primal_size;i++) ins_coarse_mat_vals[j*ins_local_primal_size+i]=0.0; 19430c7d97c5SJed Brown } 19440c7d97c5SJed Brown for(k=0;k<size_prec_comm;k++){ 19450c7d97c5SJed Brown offset=pcbddc->local_primal_displacements[k]; 19460c7d97c5SJed Brown offset2=localdispl2[k]; 19470c7d97c5SJed Brown for(j=0;j<pcbddc->local_primal_sizes[k];j++){ 19480c7d97c5SJed Brown col_ind=pcbddc->replicated_local_primal_indices[offset+j]; 19490c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_sizes[k];i++){ 19500c7d97c5SJed Brown row_ind=pcbddc->replicated_local_primal_indices[offset+i]; 19510c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*pcbddc->coarse_size+row_ind]+=temp_coarse_mat_vals[offset2+j*pcbddc->local_primal_sizes[k]+i]; 19520c7d97c5SJed Brown } 19530c7d97c5SJed Brown } 19540c7d97c5SJed Brown } 19550c7d97c5SJed Brown } 19560c7d97c5SJed Brown break; 19570c7d97c5SJed Brown }//switch on coarse problem and communications associated with finished 19580c7d97c5SJed Brown } 19590c7d97c5SJed Brown 19600c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 19610c7d97c5SJed Brown if( rank_prec_comm == active_rank ) { 19620c7d97c5SJed Brown if(pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 19630c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 19640c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 19650c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 19660c7d97c5SJed Brown ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 19670c7d97c5SJed Brown ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 19680c7d97c5SJed Brown } else { 19690c7d97c5SJed Brown Mat matis_coarse_local_mat; 19700c7d97c5SJed Brown ierr = MatCreateIS(coarse_comm,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 19710c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 19720c7d97c5SJed Brown ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 19730c7d97c5SJed Brown ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 19740c7d97c5SJed Brown ierr = MatSetOption(matis_coarse_local_mat,MAT_USE_INODES,PETSC_FALSE);CHKERRQ(ierr); 19750c7d97c5SJed Brown } 19760c7d97c5SJed Brown ierr = MatSetValues(pcbddc->coarse_mat,ins_local_primal_size,ins_local_primal_indices,ins_local_primal_size,ins_local_primal_indices,ins_coarse_mat_vals,ADD_VALUES);CHKERRQ(ierr); 19770c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19780c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19790c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 19800c7d97c5SJed Brown Mat matis_coarse_local_mat; 19810c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 19820c7d97c5SJed Brown ierr = MatSetBlockSize(matis_coarse_local_mat,bs);CHKERRQ(ierr); 19830c7d97c5SJed Brown } 19840c7d97c5SJed Brown 19850c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 19860c7d97c5SJed Brown /* Preconditioner for coarse problem */ 198753cdbc3dSStefano Zampini ierr = KSPCreate(coarse_comm,&pcbddc->coarse_ksp);CHKERRQ(ierr); 198853cdbc3dSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 198953cdbc3dSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 199053cdbc3dSStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 199153cdbc3dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 199253cdbc3dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 199353cdbc3dSStefano Zampini //ierr = PCSetOptionsPrefix(pcbddc->coarse_pc,"pc_bddc_coarse_");CHKERRQ(ierr); 19940c7d97c5SJed Brown /* Allow user's customization */ 199553cdbc3dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 19960c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 19970c7d97c5SJed Brown //if(pcbddc->check_flag && pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 199853cdbc3dSStefano Zampini if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 199953cdbc3dSStefano Zampini PetscPrintf(PETSC_COMM_WORLD,"----------------Setting up a new level---------------\n"); 200053cdbc3dSStefano Zampini ierr = PCBDDCSetCoarseProblemType(pc_temp,MULTILEVEL_BDDC);CHKERRQ(ierr); 200153cdbc3dSStefano Zampini } 200253cdbc3dSStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 20030c7d97c5SJed Brown } 20040c7d97c5SJed Brown if(pcbddc->coarse_communications_type == SCATTERS_BDDC) { 20050c7d97c5SJed Brown IS local_IS,global_IS; 20060c7d97c5SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 20070c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 20080c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 20090c7d97c5SJed Brown ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 20100c7d97c5SJed Brown ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 20110c7d97c5SJed Brown } 20120c7d97c5SJed Brown 20130c7d97c5SJed Brown 20140c7d97c5SJed Brown /* Check condition number of coarse problem */ 201553cdbc3dSStefano Zampini if( pcbddc->check_flag && rank_prec_comm == active_rank ) { 20160c7d97c5SJed Brown PetscScalar m_one=-1.0; 20170c7d97c5SJed Brown PetscReal infty_error,lambda_min,lambda_max; 20180c7d97c5SJed Brown 2019*d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_TRUE);CHKERRQ(ierr); 2020*d49ef151SStefano Zampini ierr = VecSetRandom(pcbddc->coarse_rhs,PETSC_NULL);CHKERRQ(ierr); 2021*d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 2022*d49ef151SStefano Zampini ierr = MatMult(pcbddc->coarse_mat,pcbddc->coarse_vec,pcbddc->coarse_rhs);CHKERRQ(ierr); 2023*d49ef151SStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,pcbddc->coarse_rhs,pcbddc->coarse_rhs);CHKERRQ(ierr); 2024*d49ef151SStefano Zampini ierr = KSPComputeExtremeSingularValues(pcbddc->coarse_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); 2025*d49ef151SStefano Zampini ierr = VecAXPY(pcbddc->coarse_rhs,m_one,pcbddc->coarse_vec);CHKERRQ(ierr); 2026*d49ef151SStefano Zampini ierr = VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 20270c7d97c5SJed Brown printf("eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max); 20280c7d97c5SJed Brown printf("Error on coarse ksp %1.14e\n",infty_error); 2029*d49ef151SStefano Zampini ierr = KSPSetComputeSingularValues(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 203053cdbc3dSStefano Zampini } 20310c7d97c5SJed Brown 20320c7d97c5SJed Brown /* free data structures no longer needed */ 20330c7d97c5SJed Brown if(coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 20340c7d97c5SJed Brown if(ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 20350c7d97c5SJed Brown if(ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr);} 20360c7d97c5SJed Brown if(localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr);} 20370c7d97c5SJed Brown if(localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr);} 20380c7d97c5SJed Brown if(temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr);} 20390c7d97c5SJed Brown 20400c7d97c5SJed Brown PetscFunctionReturn(0); 20410c7d97c5SJed Brown } 20420c7d97c5SJed Brown 20430c7d97c5SJed Brown #undef __FUNCT__ 20440c7d97c5SJed Brown #define __FUNCT__ "PCBDDCManageLocalBoundaries" 204553cdbc3dSStefano Zampini static PetscErrorCode PCBDDCManageLocalBoundaries(PC pc) 20460c7d97c5SJed Brown { 20470c7d97c5SJed Brown 20480c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 20490c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 20500c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 20510c7d97c5SJed Brown PetscInt *distinct_values; 205253cdbc3dSStefano Zampini PetscInt **neighbours_set; 205353cdbc3dSStefano Zampini PetscInt bs,ierr,i,j,s,k,iindex; 20540c7d97c5SJed Brown PetscInt total_counts; 20550c7d97c5SJed Brown PetscBool flg_row; 20560c7d97c5SJed Brown PCBDDCGraph mat_graph; 205753cdbc3dSStefano Zampini PetscInt neumann_bsize; 205853cdbc3dSStefano Zampini const PetscInt* neumann_nodes; 20590c7d97c5SJed Brown Mat mat_adj; 20600c7d97c5SJed Brown 20610c7d97c5SJed Brown PetscFunctionBegin; 20620c7d97c5SJed Brown 20630c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 20640c7d97c5SJed Brown // allocate and initialize needed graph structure 20650c7d97c5SJed Brown ierr = PetscMalloc(sizeof(*mat_graph),&mat_graph);CHKERRQ(ierr); 20660c7d97c5SJed Brown ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 20670c7d97c5SJed Brown ierr = MatGetRowIJ(mat_adj,0,PETSC_FALSE,PETSC_FALSE,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 20680c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called from PCBDDCManageLocalBoundaries.\n"); 20690c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&mat_graph->where);CHKERRQ(ierr); 20700c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&mat_graph->count);CHKERRQ(ierr); 20710c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&mat_graph->which_dof);CHKERRQ(ierr); 20720c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&mat_graph->queue);CHKERRQ(ierr); 20730c7d97c5SJed Brown ierr = PetscMalloc((mat_graph->nvtxs+1)*sizeof(PetscInt),&mat_graph->cptr);CHKERRQ(ierr); 20740c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscBool),&mat_graph->touched);CHKERRQ(ierr); 20750c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++){ 20760c7d97c5SJed Brown mat_graph->count[i]=0; 20770c7d97c5SJed Brown mat_graph->touched[i]=PETSC_FALSE; 20780c7d97c5SJed Brown } 20790c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs/bs;i++) { 20800c7d97c5SJed Brown for(s=0;s<bs;s++) { 20810c7d97c5SJed Brown mat_graph->which_dof[i*bs+s]=s; 20820c7d97c5SJed Brown } 20830c7d97c5SJed Brown } 20840c7d97c5SJed Brown //printf("nvtxs = %d\n",mat_graph->nvtxs); 20850c7d97c5SJed Brown //printf("these are my IS data with n_neigh = %d\n",pcis->n_neigh); 20860c7d97c5SJed Brown //for(i=0;i<pcis->n_neigh;i++){ 20870c7d97c5SJed Brown // printf("number of shared nodes with rank %d is %d \n",pcis->neigh[i],pcis->n_shared[i]); 20880c7d97c5SJed Brown // } 20890c7d97c5SJed Brown 20900c7d97c5SJed Brown total_counts=0; 20910c7d97c5SJed Brown for(i=0;i<pcis->n_neigh;i++){ 20920c7d97c5SJed Brown s=pcis->n_shared[i]; 20930c7d97c5SJed Brown total_counts+=s; 20940c7d97c5SJed Brown //printf("computing neigh %d (rank = %d, n_shared = %d)\n",i,pcis->neigh[i],s); 209553cdbc3dSStefano Zampini for(j=0;j<s;j++){ 20960c7d97c5SJed Brown mat_graph->count[pcis->shared[i][j]] += 1; 20970c7d97c5SJed Brown } 20980c7d97c5SJed Brown } 20990c7d97c5SJed Brown /* Take into account Neumann data incrementing number of sharing subdomains for all but faces nodes lying on the interface */ 210053cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 210153cdbc3dSStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundaries,&neumann_bsize);CHKERRQ(ierr); 210253cdbc3dSStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundaries,&neumann_nodes);CHKERRQ(ierr); 210353cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 210453cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 210553cdbc3dSStefano Zampini if(mat_graph->count[iindex] > 2){ 210653cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 21070c7d97c5SJed Brown total_counts++; 21080c7d97c5SJed Brown } 21090c7d97c5SJed Brown } 21100c7d97c5SJed Brown } 21110c7d97c5SJed Brown 211253cdbc3dSStefano Zampini ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt*),&neighbours_set);CHKERRQ(ierr); 211353cdbc3dSStefano Zampini if(mat_graph->nvtxs) ierr = PetscMalloc(total_counts*sizeof(PetscInt),&neighbours_set[0]);CHKERRQ(ierr); 211453cdbc3dSStefano Zampini for(i=1;i<mat_graph->nvtxs;i++) neighbours_set[i]=neighbours_set[i-1]+mat_graph->count[i-1]; 21150c7d97c5SJed Brown 21160c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++) mat_graph->count[i]=0; 21170c7d97c5SJed Brown for(i=0;i<pcis->n_neigh;i++){ 21180c7d97c5SJed Brown s=pcis->n_shared[i]; 21190c7d97c5SJed Brown for(j=0;j<s;j++) { 21200c7d97c5SJed Brown k=pcis->shared[i][j]; 212153cdbc3dSStefano Zampini neighbours_set[k][mat_graph->count[k]] = pcis->neigh[i]; 21220c7d97c5SJed Brown mat_graph->count[k]+=1; 21230c7d97c5SJed Brown } 21240c7d97c5SJed Brown } 21250c7d97c5SJed Brown /* set -1 fake neighbour */ 212653cdbc3dSStefano Zampini if(pcbddc->NeumannBoundaries) { 212753cdbc3dSStefano Zampini for(i=0;i<neumann_bsize;i++){ 212853cdbc3dSStefano Zampini iindex = neumann_nodes[i]; 212953cdbc3dSStefano Zampini if( mat_graph->count[iindex] > 2){ 213053cdbc3dSStefano Zampini neighbours_set[iindex][mat_graph->count[iindex]] = -1; //An additional fake neighbour (with rank -1) 213153cdbc3dSStefano Zampini mat_graph->count[iindex]+=1; 21320c7d97c5SJed Brown } 21330c7d97c5SJed Brown } 213453cdbc3dSStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundaries,&neumann_nodes);CHKERRQ(ierr); 21350c7d97c5SJed Brown } 21360c7d97c5SJed Brown 21370c7d97c5SJed Brown /* sort sharing subdomains */ 213853cdbc3dSStefano Zampini for(i=0;i<mat_graph->nvtxs;i++) { ierr = PetscSortInt(mat_graph->count[i],neighbours_set[i]);CHKERRQ(ierr); } 21390c7d97c5SJed Brown 214053cdbc3dSStefano Zampini /* Prepare for FindConnectedComponents 214153cdbc3dSStefano Zampini Vertices will be eliminated later (if needed) */ 21420c7d97c5SJed Brown PetscInt nodes_touched=0; 21430c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++){ 21440c7d97c5SJed Brown if(!mat_graph->count[i]){ //internal nodes 21450c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 21460c7d97c5SJed Brown mat_graph->where[i]=0; 21470c7d97c5SJed Brown nodes_touched++; 21480c7d97c5SJed Brown } 21490c7d97c5SJed Brown if(pcbddc->faces_flag){ 21500c7d97c5SJed Brown if(mat_graph->count[i]>2){ //all but faces 21510c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 21520c7d97c5SJed Brown mat_graph->where[i]=0; 21530c7d97c5SJed Brown nodes_touched++; 21540c7d97c5SJed Brown } 21550c7d97c5SJed Brown } 21560c7d97c5SJed Brown if(pcbddc->edges_flag){ 21570c7d97c5SJed Brown if(mat_graph->count[i]==2){ //faces 21580c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 21590c7d97c5SJed Brown mat_graph->where[i]=0; 21600c7d97c5SJed Brown nodes_touched++; 21610c7d97c5SJed Brown } 21620c7d97c5SJed Brown } 21630c7d97c5SJed Brown } 21640c7d97c5SJed Brown 21650c7d97c5SJed Brown PetscInt rvalue=1; 21660c7d97c5SJed Brown PetscBool same_set; 21670c7d97c5SJed Brown mat_graph->ncmps = 0; 21680c7d97c5SJed Brown while(nodes_touched<mat_graph->nvtxs) { 21690c7d97c5SJed Brown // find first untouched node in local ordering 21700c7d97c5SJed Brown i=0; 21710c7d97c5SJed Brown while(mat_graph->touched[i]) i++; 21720c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 21730c7d97c5SJed Brown mat_graph->where[i]=rvalue; 21740c7d97c5SJed Brown nodes_touched++; 21750c7d97c5SJed Brown // now find other connected nodes shared by the same set of subdomains 21760c7d97c5SJed Brown for(j=i+1;j<mat_graph->nvtxs;j++){ 21770c7d97c5SJed Brown // check for same number of sharing subdomains and dof number 21780c7d97c5SJed Brown if(mat_graph->count[i]==mat_graph->count[j] && mat_graph->which_dof[i] == mat_graph->which_dof[j] ){ 21790c7d97c5SJed Brown // check for same set of sharing subdomains 21800c7d97c5SJed Brown same_set=PETSC_TRUE; 21810c7d97c5SJed Brown for(k=0;k<mat_graph->count[j];k++){ 218253cdbc3dSStefano Zampini if(neighbours_set[i][k]!=neighbours_set[j][k]) { 21830c7d97c5SJed Brown same_set=PETSC_FALSE; 21840c7d97c5SJed Brown } 21850c7d97c5SJed Brown } 21860c7d97c5SJed Brown // OK, I found a friend of mine 21870c7d97c5SJed Brown if(same_set) { 21880c7d97c5SJed Brown mat_graph->where[j]=rvalue; 21890c7d97c5SJed Brown mat_graph->touched[j]=PETSC_TRUE; 21900c7d97c5SJed Brown nodes_touched++; 21910c7d97c5SJed Brown } 21920c7d97c5SJed Brown } 21930c7d97c5SJed Brown } 21940c7d97c5SJed Brown rvalue++; 21950c7d97c5SJed Brown } 21960c7d97c5SJed Brown // printf("where and count contains %d distinct values\n",rvalue); 21970c7d97c5SJed Brown // for(j=0;j<mat_graph->nvtxs;j++) 21980c7d97c5SJed Brown // printf("[%d %d %d]\n",j,mat_graph->where[j],mat_graph->count[j]); 21990c7d97c5SJed Brown 22000c7d97c5SJed Brown if(mat_graph->nvtxs) { 220153cdbc3dSStefano Zampini ierr = PetscFree(neighbours_set[0]);CHKERRQ(ierr); 220253cdbc3dSStefano Zampini ierr = PetscFree(neighbours_set);CHKERRQ(ierr); 22030c7d97c5SJed Brown } 22040c7d97c5SJed Brown 22050c7d97c5SJed Brown rvalue--; 22060c7d97c5SJed Brown ierr = PetscMalloc ( rvalue*sizeof(PetscInt),&distinct_values);CHKERRQ(ierr); 22070c7d97c5SJed Brown for(i=0;i<rvalue;i++) distinct_values[i]=i+1; //initializiation 22080c7d97c5SJed Brown if(rvalue) ierr = PCBDDCFindConnectedComponents(mat_graph, rvalue, distinct_values); 22090c7d97c5SJed Brown //printf("total number of connected components %d \n",mat_graph->ncmps); 22100c7d97c5SJed Brown //for (i=0; i<mat_graph->ncmps; i++) { 22110c7d97c5SJed Brown // printf("[queue num %d] ptr %d, length %d, start index %d\n",i,mat_graph->cptr[i],mat_graph->cptr[i+1]-mat_graph->cptr[i],mat_graph->queue[mat_graph->cptr[i]]); 22120c7d97c5SJed Brown //} 22130c7d97c5SJed Brown PetscInt nfc=0; 22140c7d97c5SJed Brown PetscInt nec=0; 22150c7d97c5SJed Brown PetscInt nvc=0; 22160c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 22170c7d97c5SJed Brown // sort each connected component (by local ordering) 22180c7d97c5SJed Brown ierr = PetscSortInt(mat_graph->cptr[i+1]-mat_graph->cptr[i],&mat_graph->queue[mat_graph->cptr[i]]);CHKERRQ(ierr); 22190c7d97c5SJed Brown // count edge and faces 22200c7d97c5SJed Brown if( !pcbddc->vertices_flag ) { 22210c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 22220c7d97c5SJed Brown if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==2){ 22230c7d97c5SJed Brown nfc++; 22240c7d97c5SJed Brown } else { 22250c7d97c5SJed Brown nec++; 22260c7d97c5SJed Brown } 22270c7d97c5SJed Brown } 22280c7d97c5SJed Brown } 22290c7d97c5SJed Brown // count vertices 22300c7d97c5SJed Brown if( !pcbddc->constraints_flag ){ 22310c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] == 1 ){ 22320c7d97c5SJed Brown nvc++; 22330c7d97c5SJed Brown } 22340c7d97c5SJed Brown } 22350c7d97c5SJed Brown } 22360c7d97c5SJed Brown 22370c7d97c5SJed Brown pcbddc->n_constraints = nec+nfc; 22380c7d97c5SJed Brown pcbddc->n_vertices = nvc; 22390c7d97c5SJed Brown 22400c7d97c5SJed Brown if(pcbddc->n_constraints){ 22410c7d97c5SJed Brown /* allocate space for local constraints of BDDC */ 22420c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscInt*),&pcbddc->indices_to_constraint);CHKERRQ(ierr); 22430c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscScalar*),&pcbddc->quadrature_constraint);CHKERRQ(ierr); 22440c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscInt),&pcbddc->sizes_of_constraint);CHKERRQ(ierr); 22450c7d97c5SJed Brown k=0; 22460c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 22470c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 22480c7d97c5SJed Brown pcbddc->sizes_of_constraint[k] = mat_graph->cptr[i+1]-mat_graph->cptr[i]; 22490c7d97c5SJed Brown k++; 22500c7d97c5SJed Brown } 22510c7d97c5SJed Brown } 22520c7d97c5SJed Brown // printf("check constraints %d (should be %d)\n",k,pcbddc->n_constraints); 22530c7d97c5SJed Brown // for(i=0;i<k;i++) 22540c7d97c5SJed Brown // printf("%d ",pcbddc->sizes_of_constraint[i]); 22550c7d97c5SJed Brown // printf("\n"); 22560c7d97c5SJed Brown k=0; 22570c7d97c5SJed Brown for (i=0; i<pcbddc->n_constraints; i++) k+=pcbddc->sizes_of_constraint[i]; 22580c7d97c5SJed Brown ierr = PetscMalloc (k*sizeof(PetscInt),&pcbddc->indices_to_constraint[0]);CHKERRQ(ierr); 22590c7d97c5SJed Brown ierr = PetscMalloc (k*sizeof(PetscScalar),&pcbddc->quadrature_constraint[0]);CHKERRQ(ierr); 22600c7d97c5SJed Brown for (i=1; i<pcbddc->n_constraints; i++) { 22610c7d97c5SJed Brown pcbddc->indices_to_constraint[i] = pcbddc->indices_to_constraint[i-1] + pcbddc->sizes_of_constraint[i-1]; 22620c7d97c5SJed Brown pcbddc->quadrature_constraint[i] = pcbddc->quadrature_constraint[i-1] + pcbddc->sizes_of_constraint[i-1]; 22630c7d97c5SJed Brown } 22640c7d97c5SJed Brown k=0; 22650c7d97c5SJed Brown PetscScalar quad_value; 22660c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 22670c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 22680c7d97c5SJed Brown quad_value=1.0/( (PetscScalar) (mat_graph->cptr[i+1]-mat_graph->cptr[i]) ); 22690c7d97c5SJed Brown for(j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++) { 22700c7d97c5SJed Brown pcbddc->indices_to_constraint[k][j] = mat_graph->queue[mat_graph->cptr[i]+j]; 22710c7d97c5SJed Brown pcbddc->quadrature_constraint[k][j] = quad_value; 22720c7d97c5SJed Brown } 22730c7d97c5SJed Brown k++; 22740c7d97c5SJed Brown } 22750c7d97c5SJed Brown } 22760c7d97c5SJed Brown } 22770c7d97c5SJed Brown if(pcbddc->n_vertices){ 22780c7d97c5SJed Brown /* allocate space for local vertices of BDDC */ 22790c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_vertices*sizeof(PetscInt),&pcbddc->vertices);CHKERRQ(ierr); 22800c7d97c5SJed Brown k=0; 22810c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 22820c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] == 1 ){ 22830c7d97c5SJed Brown pcbddc->vertices[k] = mat_graph->queue[mat_graph->cptr[i]]; 22840c7d97c5SJed Brown k++; 22850c7d97c5SJed Brown } 22860c7d97c5SJed Brown } 22870c7d97c5SJed Brown // sort vertex set (by local ordering) 22880c7d97c5SJed Brown ierr = PetscSortInt(pcbddc->n_vertices,pcbddc->vertices);CHKERRQ(ierr); 22890c7d97c5SJed Brown } 22900c7d97c5SJed Brown 22910c7d97c5SJed Brown if(pcbddc->check_flag) { 22920c7d97c5SJed Brown PetscViewer viewer; 2293*d49ef151SStefano Zampini ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&viewer);CHKERRQ(ierr); 2294*d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 2295*d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 2296*d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Details from PCBDDCManageLocalBoundaries for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 2297*d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 22980c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"Graph (adjacency structure) of local Neumann mat\n"); 22990c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n"); 23000c7d97c5SJed Brown // for(i=0;i<mat_graph->nvtxs;i++) { 23010c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"Nodes connected to node number %d are %d\n",i,mat_graph->xadj[i+1]-mat_graph->xadj[i]); 23020c7d97c5SJed Brown // for(j=mat_graph->xadj[i];j<mat_graph->xadj[i+1];j++){ 23030c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->adjncy[j]); 23040c7d97c5SJed Brown // } 23050c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n"); 23060c7d97c5SJed Brown // } 23070c7d97c5SJed Brown // TODO: APPLY Local to Global Mapping from IS object? 2308*d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Matrix graph has %d connected components", mat_graph->ncmps);CHKERRQ(ierr); 23090c7d97c5SJed Brown for(i=0;i<mat_graph->ncmps;i++) { 2310*d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\nSize and count for connected component %02d : %04d %01d\n", i,mat_graph->cptr[i+1]-mat_graph->cptr[i],mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]);CHKERRQ(ierr); 23110c7d97c5SJed Brown for (j=mat_graph->cptr[i]; j<mat_graph->cptr[i+1]; j++){ 2312*d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->queue[j]);CHKERRQ(ierr); 23130c7d97c5SJed Brown } 23140c7d97c5SJed Brown } 2315*d49ef151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n");CHKERRQ(ierr); 2316*d49ef151SStefano Zampini if( pcbddc->n_vertices ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local vertices\n",PetscGlobalRank,pcbddc->n_vertices);CHKERRQ(ierr); } 2317*d49ef151SStefano Zampini if( nfc ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local faces\n",PetscGlobalRank,nfc);CHKERRQ(ierr); } 2318*d49ef151SStefano Zampini if( nec ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local edges\n",PetscGlobalRank,nec);CHKERRQ(ierr); } 2319*d49ef151SStefano Zampini if( pcbddc->n_vertices ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain vertices follows\n",PetscGlobalRank,pcbddc->n_vertices);CHKERRQ(ierr); } 2320*d49ef151SStefano Zampini for(i=0;i<pcbddc->n_vertices;i++){ ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%d ",pcbddc->vertices[i]);CHKERRQ(ierr); } 2321*d49ef151SStefano Zampini if( pcbddc->n_vertices ) { ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); } 23220c7d97c5SJed Brown // if( pcbddc->n_constraints ) PetscViewerASCIISynchronizedPrintf(viewer,"Indices and quadrature constraints"); 23230c7d97c5SJed Brown // for(i=0;i<pcbddc->n_constraints;i++){ 23240c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"\nConstraint number %d\n",i); 23250c7d97c5SJed Brown // for(j=0;j<pcbddc->sizes_of_constraint[i];j++) { 23260c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"(%d, %f) ",pcbddc->indices_to_constraint[i][j],pcbddc->quadrature_constraint[i][j]); 23270c7d97c5SJed Brown // } 23280c7d97c5SJed Brown // } 23290c7d97c5SJed Brown // if( pcbddc->n_constraints ) PetscViewerASCIISynchronizedPrintf(viewer,"\n"); 2330*d49ef151SStefano Zampini ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 23310c7d97c5SJed Brown } 23320c7d97c5SJed Brown 23330c7d97c5SJed Brown // Restore CSR structure into sequantial matrix and free memory space no longer needed 23340c7d97c5SJed Brown ierr = MatRestoreRowIJ(mat_adj,0,PETSC_FALSE,PETSC_TRUE,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 23350c7d97c5SJed Brown ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 23360c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from PCBDDCManageLocalBoundaries.\n"); 23370c7d97c5SJed Brown ierr = PetscFree(distinct_values);CHKERRQ(ierr); 23380c7d97c5SJed Brown // Free graph structure 23390c7d97c5SJed Brown if(mat_graph->nvtxs){ 23400c7d97c5SJed Brown ierr = PetscFree(mat_graph->where);CHKERRQ(ierr); 23410c7d97c5SJed Brown ierr = PetscFree(mat_graph->touched);CHKERRQ(ierr); 23420c7d97c5SJed Brown ierr = PetscFree(mat_graph->which_dof);CHKERRQ(ierr); 23430c7d97c5SJed Brown ierr = PetscFree(mat_graph->queue);CHKERRQ(ierr); 23440c7d97c5SJed Brown ierr = PetscFree(mat_graph->cptr);CHKERRQ(ierr); 23450c7d97c5SJed Brown ierr = PetscFree(mat_graph->count);CHKERRQ(ierr); 23460c7d97c5SJed Brown } 23470c7d97c5SJed Brown ierr = PetscFree(mat_graph);CHKERRQ(ierr); 23480c7d97c5SJed Brown 23490c7d97c5SJed Brown PetscFunctionReturn(0); 23500c7d97c5SJed Brown 23510c7d97c5SJed Brown } 23520c7d97c5SJed Brown 23530c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 23540c7d97c5SJed Brown 23550c7d97c5SJed Brown /* The following code has been adapted from function IsConnectedSubdomain contained 23560c7d97c5SJed Brown in source file contig.c of METIS library (version 5.0.1) */ 23570c7d97c5SJed Brown 23580c7d97c5SJed Brown #undef __FUNCT__ 23590c7d97c5SJed Brown #define __FUNCT__ "PCBDDCFindConnectedComponents" 236053cdbc3dSStefano Zampini static PetscErrorCode PCBDDCFindConnectedComponents(PCBDDCGraph graph, PetscInt n_dist, PetscInt *dist_vals) 23610c7d97c5SJed Brown { 23620c7d97c5SJed Brown PetscInt i, j, k, nvtxs, first, last, nleft, ncmps,pid,cum_queue,n,ncmps_pid; 23630c7d97c5SJed Brown PetscInt *xadj, *adjncy, *where, *queue; 23640c7d97c5SJed Brown PetscInt *cptr; 23650c7d97c5SJed Brown PetscBool *touched; 23660c7d97c5SJed Brown 23670c7d97c5SJed Brown PetscFunctionBegin; 23680c7d97c5SJed Brown 23690c7d97c5SJed Brown nvtxs = graph->nvtxs; 23700c7d97c5SJed Brown xadj = graph->xadj; 23710c7d97c5SJed Brown adjncy = graph->adjncy; 23720c7d97c5SJed Brown where = graph->where; 23730c7d97c5SJed Brown touched = graph->touched; 23740c7d97c5SJed Brown queue = graph->queue; 23750c7d97c5SJed Brown cptr = graph->cptr; 23760c7d97c5SJed Brown 23770c7d97c5SJed Brown for (i=0; i<nvtxs; i++) 23780c7d97c5SJed Brown touched[i] = PETSC_FALSE; 23790c7d97c5SJed Brown 23800c7d97c5SJed Brown cum_queue=0; 23810c7d97c5SJed Brown ncmps=0; 23820c7d97c5SJed Brown 23830c7d97c5SJed Brown for(n=0; n<n_dist; n++) { 23840c7d97c5SJed Brown pid = dist_vals[n]; 23850c7d97c5SJed Brown nleft = 0; 23860c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 23870c7d97c5SJed Brown if (where[i] == pid) 23880c7d97c5SJed Brown nleft++; 23890c7d97c5SJed Brown } 23900c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 23910c7d97c5SJed Brown if (where[i] == pid) 23920c7d97c5SJed Brown break; 23930c7d97c5SJed Brown } 23940c7d97c5SJed Brown touched[i] = PETSC_TRUE; 23950c7d97c5SJed Brown queue[cum_queue] = i; 23960c7d97c5SJed Brown first = 0; last = 1; 23970c7d97c5SJed Brown cptr[ncmps] = cum_queue; /* This actually points to queue */ 23980c7d97c5SJed Brown ncmps_pid = 0; 23990c7d97c5SJed Brown while (first != nleft) { 24000c7d97c5SJed Brown if (first == last) { /* Find another starting vertex */ 24010c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 24020c7d97c5SJed Brown ncmps_pid++; 24030c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 24040c7d97c5SJed Brown if (where[i] == pid && !touched[i]) 24050c7d97c5SJed Brown break; 24060c7d97c5SJed Brown } 24070c7d97c5SJed Brown queue[cum_queue+last] = i; 24080c7d97c5SJed Brown last++; 24090c7d97c5SJed Brown touched[i] = PETSC_TRUE; 24100c7d97c5SJed Brown } 24110c7d97c5SJed Brown i = queue[cum_queue+first]; 24120c7d97c5SJed Brown first++; 24130c7d97c5SJed Brown for (j=xadj[i]; j<xadj[i+1]; j++) { 24140c7d97c5SJed Brown k = adjncy[j]; 24150c7d97c5SJed Brown if (where[k] == pid && !touched[k]) { 24160c7d97c5SJed Brown queue[cum_queue+last] = k; 24170c7d97c5SJed Brown last++; 24180c7d97c5SJed Brown touched[k] = PETSC_TRUE; 24190c7d97c5SJed Brown } 24200c7d97c5SJed Brown } 24210c7d97c5SJed Brown } 24220c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 24230c7d97c5SJed Brown ncmps_pid++; 24240c7d97c5SJed Brown cum_queue=cptr[ncmps]; 24250c7d97c5SJed Brown } 24260c7d97c5SJed Brown graph->ncmps = ncmps; 24270c7d97c5SJed Brown 24280c7d97c5SJed Brown PetscFunctionReturn(0); 24290c7d97c5SJed Brown } 24300c7d97c5SJed Brown 2431