1*0c7d97c5SJed Brown 2*0c7d97c5SJed Brown #include "bddc.h" 3*0c7d97c5SJed Brown 4*0c7d97c5SJed Brown /* 5*0c7d97c5SJed Brown Implementation of BDDC preconditioner based on: 6*0c7d97c5SJed Brown C. Dohrmann "An approximate BDDC preconditioner", Numerical Linear Algebra with Applications Volume 14, Issue 2, pages 149-168, March 2007 7*0c7d97c5SJed Brown */ 8*0c7d97c5SJed Brown 9*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 10*0c7d97c5SJed Brown #undef __FUNCT__ 11*0c7d97c5SJed Brown #define __FUNCT__ "PCSetFromOptions_BDDC" 12*0c7d97c5SJed Brown PetscErrorCode PCSetFromOptions_BDDC(PC pc) 13*0c7d97c5SJed Brown { 14*0c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15*0c7d97c5SJed Brown PetscErrorCode ierr; 16*0c7d97c5SJed Brown 17*0c7d97c5SJed Brown PetscFunctionBegin; 18*0c7d97c5SJed Brown ierr = PetscOptionsHead("BDDC options");CHKERRQ(ierr); 19*0c7d97c5SJed Brown /* Verbose debugging of main data structures */ 20*0c7d97c5SJed Brown ierr = PetscOptionsBool("-pc_bddc_check_all" ,"Verbose (debugging) output for PCBDDC" ,"none",pcbddc->check_flag ,&pcbddc->check_flag ,PETSC_NULL);CHKERRQ(ierr); 21*0c7d97c5SJed Brown /* Some customization for default primal space */ 22*0c7d97c5SJed 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); 23*0c7d97c5SJed 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); 24*0c7d97c5SJed 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); 25*0c7d97c5SJed 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); 26*0c7d97c5SJed Brown /* Coarse solver context */ 27*0c7d97c5SJed Brown static const char *avail_coarse_problems[] = {"sequential","replicated","parallel","multilevel",""}; //order of choiches depends on ENUM defined in bddc.h 28*0c7d97c5SJed 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); 29*0c7d97c5SJed Brown /* Two different application of BDDC to the whole set of dofs, internal and interface */ 30*0c7d97c5SJed 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); 31*0c7d97c5SJed 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); 32*0c7d97c5SJed Brown ierr = PetscOptionsTail();CHKERRQ(ierr); 33*0c7d97c5SJed Brown PetscFunctionReturn(0); 34*0c7d97c5SJed Brown } 35*0c7d97c5SJed Brown 36*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 37*0c7d97c5SJed Brown EXTERN_C_BEGIN 38*0c7d97c5SJed Brown #undef __FUNCT__ 39*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType_BDDC" 40*0c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType_BDDC(PC pc, CoarseProblemType CPT) 41*0c7d97c5SJed Brown { 42*0c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 43*0c7d97c5SJed Brown 44*0c7d97c5SJed Brown PetscFunctionBegin; 45*0c7d97c5SJed Brown pcbddc->coarse_problem_type = CPT; 46*0c7d97c5SJed Brown PetscFunctionReturn(0); 47*0c7d97c5SJed Brown } 48*0c7d97c5SJed Brown EXTERN_C_END 49*0c7d97c5SJed Brown 50*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 51*0c7d97c5SJed Brown #undef __FUNCT__ 52*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetCoarseProblemType" 53*0c7d97c5SJed Brown /* 54*0c7d97c5SJed Brown SZ INSERT COMMENT HERE 55*0c7d97c5SJed Brown */ 56*0c7d97c5SJed Brown PetscErrorCode PCBDDCSetCoarseProblemType(PC pc, CoarseProblemType CPT) 57*0c7d97c5SJed Brown { 58*0c7d97c5SJed Brown PetscErrorCode ierr; 59*0c7d97c5SJed Brown 60*0c7d97c5SJed Brown PetscFunctionBegin; 61*0c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 62*0c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetCoarseProblemType_C",(PC,CoarseProblemType),(pc,CPT));CHKERRQ(ierr); 63*0c7d97c5SJed Brown PetscFunctionReturn(0); 64*0c7d97c5SJed Brown } 65*0c7d97c5SJed Brown 66*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 67*0c7d97c5SJed Brown EXTERN_C_BEGIN 68*0c7d97c5SJed Brown #undef __FUNCT__ 69*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries_BDDC" 70*0c7d97c5SJed Brown PetscErrorCode PCBDDCSetNeumannBoundaries_BDDC(PC pc,Vec input_vec) 71*0c7d97c5SJed Brown { 72*0c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 73*0c7d97c5SJed Brown 74*0c7d97c5SJed Brown PetscFunctionBegin; 75*0c7d97c5SJed Brown VecDuplicate(input_vec,&pcbddc->Vec_Neumann); 76*0c7d97c5SJed Brown VecCopy(input_vec,pcbddc->Vec_Neumann); 77*0c7d97c5SJed Brown PetscFunctionReturn(0); 78*0c7d97c5SJed Brown } 79*0c7d97c5SJed Brown EXTERN_C_END 80*0c7d97c5SJed Brown 81*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 82*0c7d97c5SJed Brown #undef __FUNCT__ 83*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetNeumannBoundaries" 84*0c7d97c5SJed Brown /* 85*0c7d97c5SJed Brown SZ INSERT COMMENT HERE 86*0c7d97c5SJed Brown */ 87*0c7d97c5SJed Brown PetscErrorCode PCBDDCSetNeumannBoundaries(PC pc,Vec input_vec) 88*0c7d97c5SJed Brown { 89*0c7d97c5SJed Brown PetscErrorCode ierr; 90*0c7d97c5SJed Brown 91*0c7d97c5SJed Brown PetscFunctionBegin; 92*0c7d97c5SJed Brown PetscValidHeaderSpecific(pc,PC_CLASSID,1); 93*0c7d97c5SJed Brown ierr = PetscTryMethod(pc,"PCBDDCSetNeumannBoundaries_C",(PC,Vec),(pc,input_vec));CHKERRQ(ierr); 94*0c7d97c5SJed Brown PetscFunctionReturn(0); 95*0c7d97c5SJed Brown } 96*0c7d97c5SJed Brown 97*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 98*0c7d97c5SJed Brown /* 99*0c7d97c5SJed Brown PCSetUp_BDDC - Prepares for the use of the BDDC preconditioner 100*0c7d97c5SJed Brown by setting data structures and options. 101*0c7d97c5SJed Brown 102*0c7d97c5SJed Brown Input Parameter: 103*0c7d97c5SJed Brown . pc - the preconditioner context 104*0c7d97c5SJed Brown 105*0c7d97c5SJed Brown Application Interface Routine: PCSetUp() 106*0c7d97c5SJed Brown 107*0c7d97c5SJed Brown Notes: 108*0c7d97c5SJed Brown The interface routine PCSetUp() is not usually called directly by 109*0c7d97c5SJed Brown the user, but instead is called by PCApply() if necessary. 110*0c7d97c5SJed Brown */ 111*0c7d97c5SJed Brown #undef __FUNCT__ 112*0c7d97c5SJed Brown #define __FUNCT__ "PCSetUp_BDDC" 113*0c7d97c5SJed Brown static PetscErrorCode PCSetUp_BDDC(PC pc) 114*0c7d97c5SJed Brown { 115*0c7d97c5SJed Brown PetscErrorCode ierr; 116*0c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 117*0c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 118*0c7d97c5SJed Brown 119*0c7d97c5SJed Brown PetscFunctionBegin; 120*0c7d97c5SJed Brown if (!pc->setupcalled) { 121*0c7d97c5SJed Brown 122*0c7d97c5SJed Brown /* For BDDC we need to define a local "Neumann" to that defined in PCISSetup 123*0c7d97c5SJed Brown So, we set to pcnone the Neumann problem of pcid in order to avoid unneeded computation 124*0c7d97c5SJed Brown Also, we decide to directly build the (same) Dirichlet problem */ 125*0c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localN_pc_type","none");CHKERRQ(ierr); 126*0c7d97c5SJed Brown ierr = PetscOptionsSetValue("-is_localD_pc_type","none");CHKERRQ(ierr); 127*0c7d97c5SJed Brown /* Set up all the "iterative substructuring" common block */ 128*0c7d97c5SJed Brown ierr = PCISSetUp(pc);CHKERRQ(ierr); 129*0c7d97c5SJed Brown /* Destroy some PC_IS data which is not needed by BDDC */ 130*0c7d97c5SJed Brown //if (pcis->ksp_D) {ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr);} 131*0c7d97c5SJed Brown //if (pcis->ksp_N) {ierr = KSPDestroy(&pcis->ksp_N);CHKERRQ(ierr);} 132*0c7d97c5SJed Brown //if (pcis->vec2_B) {ierr = VecDestroy(&pcis->vec2_B);CHKERRQ(ierr);} 133*0c7d97c5SJed Brown //if (pcis->vec3_B) {ierr = VecDestroy(&pcis->vec3_B);CHKERRQ(ierr);} 134*0c7d97c5SJed Brown //pcis->ksp_D = 0; 135*0c7d97c5SJed Brown //pcis->ksp_N = 0; 136*0c7d97c5SJed Brown //pcis->vec2_B = 0; 137*0c7d97c5SJed Brown //pcis->vec3_B = 0; 138*0c7d97c5SJed Brown 139*0c7d97c5SJed Brown //TODO MOVE CODE FRAGMENT 140*0c7d97c5SJed Brown PetscInt im_active=0; 141*0c7d97c5SJed Brown if(pcis->n) im_active = 1; 142*0c7d97c5SJed Brown MPI_Allreduce(&im_active,&pcbddc->active_procs,1,MPIU_INT,MPI_SUM,((PetscObject)pc)->comm); 143*0c7d97c5SJed Brown //printf("Calling PCBDDC MANAGE with active procs %d (im_active = %d)\n",pcbddc->active_procs,im_active); 144*0c7d97c5SJed Brown /* Set up grid quantities for BDDC */ 145*0c7d97c5SJed Brown //TODO only active procs must call this -> remove synchronized print inside (the only point of sync) 146*0c7d97c5SJed Brown ierr = PCBDDCManageLocalBoundaries(pc);CHKERRQ(ierr); 147*0c7d97c5SJed Brown 148*0c7d97c5SJed Brown /* Create coarse and local stuffs used for evaluating action of preconditioner */ 149*0c7d97c5SJed Brown ierr = PCBDDCCoarseSetUp(pc);CHKERRQ(ierr); 150*0c7d97c5SJed Brown 151*0c7d97c5SJed Brown if ( !pcis->n_neigh ) pcis->ISLocalToGlobalMappingGetInfoWasCalled=PETSC_FALSE; //processes fakely involved in multilevel should not call ISLocalToGlobalMappingRestoreInfo 152*0c7d97c5SJed Brown /* We no more need this matrix */ 153*0c7d97c5SJed Brown //if (pcis->A_BB) {ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr);} 154*0c7d97c5SJed Brown //pcis->A_BB = 0; 155*0c7d97c5SJed Brown 156*0c7d97c5SJed Brown //printf("Using coarse problem type %d\n",pcbddc->coarse_problem_type); 157*0c7d97c5SJed Brown //printf("Using coarse communications type %d\n",pcbddc->coarse_communications_type); 158*0c7d97c5SJed Brown //printf("Using coarsening ratio %d\n",pcbddc->coarsening_ratio); 159*0c7d97c5SJed Brown } 160*0c7d97c5SJed Brown 161*0c7d97c5SJed Brown PetscFunctionReturn(0); 162*0c7d97c5SJed Brown } 163*0c7d97c5SJed Brown 164*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 165*0c7d97c5SJed Brown /* 166*0c7d97c5SJed Brown PCApply_BDDC - Applies the BDDC preconditioner to a vector. 167*0c7d97c5SJed Brown 168*0c7d97c5SJed Brown Input Parameters: 169*0c7d97c5SJed Brown . pc - the preconditioner context 170*0c7d97c5SJed Brown . r - input vector (global) 171*0c7d97c5SJed Brown 172*0c7d97c5SJed Brown Output Parameter: 173*0c7d97c5SJed Brown . z - output vector (global) 174*0c7d97c5SJed Brown 175*0c7d97c5SJed Brown Application Interface Routine: PCApply() 176*0c7d97c5SJed Brown */ 177*0c7d97c5SJed Brown #undef __FUNCT__ 178*0c7d97c5SJed Brown #define __FUNCT__ "PCApply_BDDC" 179*0c7d97c5SJed Brown static PetscErrorCode PCApply_BDDC(PC pc,Vec r,Vec z) 180*0c7d97c5SJed Brown { 181*0c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)(pc->data); 182*0c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 183*0c7d97c5SJed Brown PetscErrorCode ierr; 184*0c7d97c5SJed Brown PetscScalar one = 1.0; 185*0c7d97c5SJed Brown PetscScalar m_one = -1.0; 186*0c7d97c5SJed Brown 187*0c7d97c5SJed Brown /* This code is similar to that provided in nn.c for PCNN 188*0c7d97c5SJed Brown NN interface preconditioner changed to BDDC 189*0c7d97c5SJed Brown Added support for M_3 preconditioenr in the reference article (code is active if pcbddc->prec_type = PETSC_TRUE) */ 190*0c7d97c5SJed Brown 191*0c7d97c5SJed Brown PetscFunctionBegin; 192*0c7d97c5SJed Brown /* First Dirichlet solve */ 193*0c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 194*0c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 195*0c7d97c5SJed Brown ierr = PCApply(pcbddc->pc_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 196*0c7d97c5SJed Brown /* 197*0c7d97c5SJed Brown Assembling right hand side for BDDC operator 198*0c7d97c5SJed Brown - vec1_D for the Dirichlet part (if needed, i.e. prec_flag=PETSC_TRUE) 199*0c7d97c5SJed Brown - the interface part of the global vector z 200*0c7d97c5SJed Brown */ 201*0c7d97c5SJed Brown //ierr = VecScatterBegin(pcis->global_to_B,r,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 202*0c7d97c5SJed Brown //ierr = VecScatterEnd (pcis->global_to_B,r,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 203*0c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 204*0c7d97c5SJed Brown ierr = MatMult(pcis->A_BI,pcis->vec2_D,pcis->vec1_B);CHKERRQ(ierr); 205*0c7d97c5SJed Brown //ierr = MatMultAdd(pcis->A_BI,pcis->vec2_D,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 206*0c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec2_D,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 207*0c7d97c5SJed Brown ierr = VecScale(pcis->vec2_D,m_one);CHKERRQ(ierr); 208*0c7d97c5SJed Brown ierr = VecCopy(r,z);CHKERRQ(ierr); 209*0c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 210*0c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 211*0c7d97c5SJed Brown 212*0c7d97c5SJed Brown /* 213*0c7d97c5SJed Brown Apply interface preconditioner 214*0c7d97c5SJed Brown Results are stored in: 215*0c7d97c5SJed Brown - vec1_D (if needed, i.e. with prec_type = PETSC_TRUE) 216*0c7d97c5SJed Brown - the interface part of the global vector z 217*0c7d97c5SJed Brown */ 218*0c7d97c5SJed Brown ierr = PCBDDCApplyInterfacePreconditioner(pc,z); CHKERRQ(ierr); 219*0c7d97c5SJed Brown 220*0c7d97c5SJed Brown /* Second Dirichlet solves and assembling of output */ 221*0c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 222*0c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 223*0c7d97c5SJed Brown ierr = MatMult(pcis->A_IB,pcis->vec1_B,pcis->vec3_D);CHKERRQ(ierr); 224*0c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcis->A_II,pcis->vec1_D,pcis->vec3_D,pcis->vec3_D);CHKERRQ(ierr); } 225*0c7d97c5SJed Brown ierr = PCApply(pcbddc->pc_D,pcis->vec3_D,pcbddc->vec4_D);CHKERRQ(ierr); 226*0c7d97c5SJed Brown ierr = VecScale(pcbddc->vec4_D,m_one);CHKERRQ(ierr); 227*0c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = VecAXPY (pcbddc->vec4_D,one,pcis->vec1_D);CHKERRQ(ierr); } 228*0c7d97c5SJed Brown ierr = VecAXPY (pcis->vec2_D,one,pcbddc->vec4_D);CHKERRQ(ierr); 229*0c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 230*0c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 231*0c7d97c5SJed Brown 232*0c7d97c5SJed Brown PetscFunctionReturn(0); 233*0c7d97c5SJed Brown 234*0c7d97c5SJed Brown } 235*0c7d97c5SJed Brown 236*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 237*0c7d97c5SJed Brown /* 238*0c7d97c5SJed Brown PCBDDCApplyInterfacePreconditioner - Apply the BDDC preconditioner at the interface. 239*0c7d97c5SJed Brown 240*0c7d97c5SJed Brown */ 241*0c7d97c5SJed Brown #undef __FUNCT__ 242*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 243*0c7d97c5SJed Brown PetscErrorCode PCBDDCApplyInterfacePreconditioner (PC pc, Vec z) 244*0c7d97c5SJed Brown { 245*0c7d97c5SJed Brown PetscErrorCode ierr; 246*0c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 247*0c7d97c5SJed Brown PC_IS* pcis = (PC_IS*) (pc->data); 248*0c7d97c5SJed Brown PetscScalar zero = 0.0; 249*0c7d97c5SJed Brown 250*0c7d97c5SJed Brown PetscFunctionBegin; 251*0c7d97c5SJed Brown /* Get Local boundary and apply partition of unity */ 252*0c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 253*0c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,z,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 254*0c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 255*0c7d97c5SJed Brown 256*0c7d97c5SJed Brown /* Application of PHI^T */ 257*0c7d97c5SJed Brown ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 258*0c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 259*0c7d97c5SJed Brown 260*0c7d97c5SJed Brown /* Scatter data of coarse_rhs */ 261*0c7d97c5SJed Brown if(pcbddc->coarse_rhs) ierr = VecSet(pcbddc->coarse_rhs,zero);CHKERRQ(ierr); 262*0c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 263*0c7d97c5SJed Brown 264*0c7d97c5SJed Brown /* Local solution on R nodes */ 265*0c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_R,zero);CHKERRQ(ierr); 266*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 267*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 268*0c7d97c5SJed Brown if(pcbddc->prec_type) { 269*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 270*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 271*0c7d97c5SJed Brown } 272*0c7d97c5SJed Brown ierr = PCBDDCSolveSaddlePoint(pc);CHKERRQ(ierr); 273*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 274*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 275*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec2_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 276*0c7d97c5SJed Brown if(pcbddc->prec_type) { 277*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 278*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec2_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 279*0c7d97c5SJed Brown } 280*0c7d97c5SJed Brown 281*0c7d97c5SJed Brown /* Coarse solution */ 282*0c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd(pc,pcbddc->vec1_P,pcbddc->coarse_rhs,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 283*0c7d97c5SJed Brown if(pcbddc->coarse_rhs) ierr = PCApply(pcbddc->coarse_pc,pcbddc->coarse_rhs,pcbddc->coarse_vec);CHKERRQ(ierr); 284*0c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataBegin(pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 285*0c7d97c5SJed Brown ierr = PCBDDCScatterCoarseDataEnd (pc,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 286*0c7d97c5SJed Brown 287*0c7d97c5SJed Brown /* Sum contributions from two levels */ 288*0c7d97c5SJed Brown /* Apply partition of unity and sum boundary values */ 289*0c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 290*0c7d97c5SJed Brown ierr = VecPointwiseMult(pcis->vec1_B,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 291*0c7d97c5SJed Brown if(pcbddc->prec_type) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 292*0c7d97c5SJed Brown ierr = VecSet(z,zero);CHKERRQ(ierr); 293*0c7d97c5SJed Brown ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 294*0c7d97c5SJed Brown ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 295*0c7d97c5SJed Brown 296*0c7d97c5SJed Brown PetscFunctionReturn(0); 297*0c7d97c5SJed Brown } 298*0c7d97c5SJed Brown 299*0c7d97c5SJed Brown 300*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 301*0c7d97c5SJed Brown /* 302*0c7d97c5SJed Brown PCBDDCSolveSaddlePoint 303*0c7d97c5SJed Brown 304*0c7d97c5SJed Brown */ 305*0c7d97c5SJed Brown #undef __FUNCT__ 306*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSolveSaddlePoint" 307*0c7d97c5SJed Brown PetscErrorCode PCBDDCSolveSaddlePoint(PC pc) 308*0c7d97c5SJed Brown 309*0c7d97c5SJed Brown { 310*0c7d97c5SJed Brown PetscErrorCode ierr; 311*0c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 312*0c7d97c5SJed Brown 313*0c7d97c5SJed Brown PetscFunctionBegin; 314*0c7d97c5SJed Brown 315*0c7d97c5SJed Brown ierr = PCApply(pcbddc->pc_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 316*0c7d97c5SJed Brown if(pcbddc->n_constraints) { 317*0c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec2_R,pcbddc->vec1_C);CHKERRQ(ierr); 318*0c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 319*0c7d97c5SJed Brown } 320*0c7d97c5SJed Brown 321*0c7d97c5SJed Brown PetscFunctionReturn(0); 322*0c7d97c5SJed Brown 323*0c7d97c5SJed Brown } 324*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 325*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 326*0c7d97c5SJed Brown /* 327*0c7d97c5SJed Brown PCBDDCScatterCoarseDataBegin 328*0c7d97c5SJed Brown 329*0c7d97c5SJed Brown */ 330*0c7d97c5SJed Brown #undef __FUNCT__ 331*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 332*0c7d97c5SJed Brown PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 333*0c7d97c5SJed Brown { 334*0c7d97c5SJed Brown PetscErrorCode ierr; 335*0c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 336*0c7d97c5SJed Brown 337*0c7d97c5SJed Brown PetscFunctionBegin; 338*0c7d97c5SJed Brown 339*0c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 340*0c7d97c5SJed Brown case SCATTERS_BDDC: 341*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 342*0c7d97c5SJed Brown break; 343*0c7d97c5SJed Brown case GATHERS_BDDC: 344*0c7d97c5SJed Brown break; 345*0c7d97c5SJed Brown } 346*0c7d97c5SJed Brown PetscFunctionReturn(0); 347*0c7d97c5SJed Brown 348*0c7d97c5SJed Brown } 349*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 350*0c7d97c5SJed Brown /* 351*0c7d97c5SJed Brown PCBDDCScatterCoarseDataEnd 352*0c7d97c5SJed Brown 353*0c7d97c5SJed Brown */ 354*0c7d97c5SJed Brown #undef __FUNCT__ 355*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 356*0c7d97c5SJed Brown PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc,Vec vec_from, Vec vec_to, InsertMode imode, ScatterMode smode) 357*0c7d97c5SJed Brown { 358*0c7d97c5SJed Brown PetscErrorCode ierr; 359*0c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 360*0c7d97c5SJed Brown PetscScalar* array_to; 361*0c7d97c5SJed Brown PetscScalar* array_from; 362*0c7d97c5SJed Brown MPI_Comm comm=((PetscObject)pc)->comm; 363*0c7d97c5SJed Brown PetscInt i; 364*0c7d97c5SJed Brown 365*0c7d97c5SJed Brown PetscFunctionBegin; 366*0c7d97c5SJed Brown 367*0c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 368*0c7d97c5SJed Brown case SCATTERS_BDDC: 369*0c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,vec_from,vec_to,imode,smode);CHKERRQ(ierr); 370*0c7d97c5SJed Brown break; 371*0c7d97c5SJed Brown case GATHERS_BDDC: 372*0c7d97c5SJed Brown if(vec_from) VecGetArray(vec_from,&array_from); 373*0c7d97c5SJed Brown if(vec_to) VecGetArray(vec_to,&array_to); 374*0c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 375*0c7d97c5SJed Brown case SEQUENTIAL_BDDC: 376*0c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 377*0c7d97c5SJed Brown 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); 378*0c7d97c5SJed Brown if(vec_to) { 379*0c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 380*0c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 381*0c7d97c5SJed Brown } 382*0c7d97c5SJed Brown } else { 383*0c7d97c5SJed Brown if(vec_from) 384*0c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 385*0c7d97c5SJed Brown pcbddc->replicated_local_primal_values[i]=array_from[pcbddc->replicated_local_primal_indices[i]]; 386*0c7d97c5SJed Brown 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); 387*0c7d97c5SJed Brown } 388*0c7d97c5SJed Brown break; 389*0c7d97c5SJed Brown case REPLICATED_BDDC: 390*0c7d97c5SJed Brown if(smode == SCATTER_FORWARD) { 391*0c7d97c5SJed Brown 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); 392*0c7d97c5SJed Brown for(i=0;i<pcbddc->replicated_primal_size;i++) 393*0c7d97c5SJed Brown array_to[pcbddc->replicated_local_primal_indices[i]]+=pcbddc->replicated_local_primal_values[i]; 394*0c7d97c5SJed Brown } else { /* no communications needed for SCATTER_REVERSE since needed data is already present */ 395*0c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) 396*0c7d97c5SJed Brown array_to[i]=array_from[pcbddc->local_primal_indices[i]]; 397*0c7d97c5SJed Brown } 398*0c7d97c5SJed Brown break; 399*0c7d97c5SJed Brown } 400*0c7d97c5SJed Brown if(vec_from) VecRestoreArray(vec_from,&array_from); 401*0c7d97c5SJed Brown if(vec_to) VecRestoreArray(vec_to,&array_to); 402*0c7d97c5SJed Brown break; 403*0c7d97c5SJed Brown } 404*0c7d97c5SJed Brown PetscFunctionReturn(0); 405*0c7d97c5SJed Brown 406*0c7d97c5SJed Brown } 407*0c7d97c5SJed Brown 408*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 409*0c7d97c5SJed Brown /* 410*0c7d97c5SJed Brown PCDestroy_BDDC - Destroys the private context for the NN preconditioner 411*0c7d97c5SJed Brown that was created with PCCreate_BDDC(). 412*0c7d97c5SJed Brown 413*0c7d97c5SJed Brown Input Parameter: 414*0c7d97c5SJed Brown . pc - the preconditioner context 415*0c7d97c5SJed Brown 416*0c7d97c5SJed Brown Application Interface Routine: PCDestroy() 417*0c7d97c5SJed Brown */ 418*0c7d97c5SJed Brown #undef __FUNCT__ 419*0c7d97c5SJed Brown #define __FUNCT__ "PCDestroy_BDDC" 420*0c7d97c5SJed Brown static PetscErrorCode PCDestroy_BDDC(PC pc) 421*0c7d97c5SJed Brown { 422*0c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 423*0c7d97c5SJed Brown PetscErrorCode ierr; 424*0c7d97c5SJed Brown 425*0c7d97c5SJed Brown PetscFunctionBegin; 426*0c7d97c5SJed Brown /* free data created by PCIS */ 427*0c7d97c5SJed Brown ierr = PCISDestroy(pc);CHKERRQ(ierr); 428*0c7d97c5SJed Brown /* free BDDC data */ 429*0c7d97c5SJed Brown if (pcbddc->coarse_vec) {ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr);} 430*0c7d97c5SJed Brown if (pcbddc->coarse_rhs) {ierr = VecDestroy(&pcbddc->coarse_rhs);CHKERRQ(ierr);} 431*0c7d97c5SJed Brown if (pcbddc->coarse_pc) {ierr = PCDestroy(&pcbddc->coarse_pc);CHKERRQ(ierr);} 432*0c7d97c5SJed Brown if (pcbddc->coarse_mat) {ierr = MatDestroy(&pcbddc->coarse_mat);CHKERRQ(ierr);} 433*0c7d97c5SJed Brown if (pcbddc->coarse_phi_B) {ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr);} 434*0c7d97c5SJed Brown if (pcbddc->coarse_phi_D) {ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr);} 435*0c7d97c5SJed Brown if (pcbddc->vec1_P) {ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr);} 436*0c7d97c5SJed Brown if (pcbddc->vec1_C) {ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr);} 437*0c7d97c5SJed Brown if (pcbddc->local_auxmat1) {ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr);} 438*0c7d97c5SJed Brown if (pcbddc->local_auxmat2) {ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr);} 439*0c7d97c5SJed Brown if (pcbddc->vec1_R) {ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr);} 440*0c7d97c5SJed Brown if (pcbddc->vec2_R) {ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr);} 441*0c7d97c5SJed Brown if (pcbddc->vec4_D) {ierr = VecDestroy(&pcbddc->vec4_D);CHKERRQ(ierr);} 442*0c7d97c5SJed Brown if (pcbddc->R_to_B) {ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr);} 443*0c7d97c5SJed Brown if (pcbddc->R_to_D) {ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr);} 444*0c7d97c5SJed Brown if (pcbddc->coarse_loc_to_glob) {ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr);} 445*0c7d97c5SJed Brown if (pcbddc->pc_D) {ierr = PCDestroy(&pcbddc->pc_D);CHKERRQ(ierr);} 446*0c7d97c5SJed Brown if (pcbddc->pc_R) {ierr = PCDestroy(&pcbddc->pc_R);CHKERRQ(ierr);} 447*0c7d97c5SJed Brown if (pcbddc->Vec_Neumann) {ierr = VecDestroy(&pcbddc->Vec_Neumann);CHKERRQ(ierr);} 448*0c7d97c5SJed Brown if (pcbddc->vertices) {ierr = PetscFree(pcbddc->vertices);CHKERRQ(ierr);} 449*0c7d97c5SJed Brown if (pcbddc->local_primal_indices) { ierr = PetscFree(pcbddc->local_primal_indices);CHKERRQ(ierr);} 450*0c7d97c5SJed Brown if (pcbddc->replicated_local_primal_indices) { ierr = PetscFree(pcbddc->replicated_local_primal_indices);CHKERRQ(ierr);} 451*0c7d97c5SJed Brown //if (pcbddc->replicated_local_primal_values) { ierr = PetscFree(pcbddc->replicated_local_primal_values);CHKERRQ(ierr);} 452*0c7d97c5SJed Brown if (pcbddc->replicated_local_primal_values) { free(pcbddc->replicated_local_primal_values); } 453*0c7d97c5SJed Brown if (pcbddc->local_primal_displacements) { ierr = PetscFree(pcbddc->local_primal_displacements);CHKERRQ(ierr);} 454*0c7d97c5SJed Brown if (pcbddc->local_primal_sizes) { ierr = PetscFree(pcbddc->local_primal_sizes);CHKERRQ(ierr);} 455*0c7d97c5SJed Brown if (pcbddc->n_constraints) { 456*0c7d97c5SJed Brown ierr = PetscFree(pcbddc->indices_to_constraint[0]);CHKERRQ(ierr); 457*0c7d97c5SJed Brown ierr = PetscFree(pcbddc->indices_to_constraint);CHKERRQ(ierr); 458*0c7d97c5SJed Brown ierr = PetscFree(pcbddc->quadrature_constraint[0]);CHKERRQ(ierr); 459*0c7d97c5SJed Brown ierr = PetscFree(pcbddc->quadrature_constraint);CHKERRQ(ierr); 460*0c7d97c5SJed Brown ierr = PetscFree(pcbddc->sizes_of_constraint);CHKERRQ(ierr); 461*0c7d97c5SJed Brown } 462*0c7d97c5SJed Brown /* Free the private data structure that was hanging off the PC */ 463*0c7d97c5SJed Brown ierr = PetscFree(pcbddc);CHKERRQ(ierr); 464*0c7d97c5SJed Brown PetscFunctionReturn(0); 465*0c7d97c5SJed Brown } 466*0c7d97c5SJed Brown 467*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 468*0c7d97c5SJed Brown /*MC 469*0c7d97c5SJed Brown PCBDDC - Balancing Domain Decomposition by Constraints. 470*0c7d97c5SJed Brown 471*0c7d97c5SJed Brown Options Database Keys: 472*0c7d97c5SJed Brown . -pc_is_damp_fixed <fact> - 473*0c7d97c5SJed Brown . -pc_is_remove_nullspace_fixed - 474*0c7d97c5SJed Brown . -pc_is_set_damping_factor_floating <fact> - 475*0c7d97c5SJed Brown . -pc_is_not_damp_floating - 476*0c7d97c5SJed Brown 477*0c7d97c5SJed Brown Level: intermediate 478*0c7d97c5SJed Brown 479*0c7d97c5SJed Brown Notes: The matrix used with this preconditioner must be of type MATIS 480*0c7d97c5SJed Brown 481*0c7d97c5SJed Brown Unlike more 'conventional' interface preconditioners, this iterates over ALL the 482*0c7d97c5SJed Brown degrees of freedom, NOT just those on the interface (this allows the use of approximate solvers 483*0c7d97c5SJed Brown on the subdomains). 484*0c7d97c5SJed Brown 485*0c7d97c5SJed Brown Options for the coarse grid preconditioner can be set with -pc_bddc_coarse_pc_xxx 486*0c7d97c5SJed Brown Options for the Dirichlet subproblem can be set with -pc_bddc_localD_xxx 487*0c7d97c5SJed Brown Options for the Neumann subproblem can be set with -pc_bddc_localN_xxx 488*0c7d97c5SJed Brown 489*0c7d97c5SJed Brown Contributed by Stefano Zampini 490*0c7d97c5SJed Brown 491*0c7d97c5SJed Brown .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, MATIS 492*0c7d97c5SJed Brown M*/ 493*0c7d97c5SJed Brown EXTERN_C_BEGIN 494*0c7d97c5SJed Brown #undef __FUNCT__ 495*0c7d97c5SJed Brown #define __FUNCT__ "PCCreate_BDDC" 496*0c7d97c5SJed Brown PetscErrorCode PCCreate_BDDC(PC pc) 497*0c7d97c5SJed Brown { 498*0c7d97c5SJed Brown PetscErrorCode ierr; 499*0c7d97c5SJed Brown PC_BDDC *pcbddc; 500*0c7d97c5SJed Brown 501*0c7d97c5SJed Brown PetscFunctionBegin; 502*0c7d97c5SJed Brown /* Creates the private data structure for this preconditioner and attach it to the PC object. */ 503*0c7d97c5SJed Brown ierr = PetscNewLog(pc,PC_BDDC,&pcbddc);CHKERRQ(ierr); 504*0c7d97c5SJed Brown pc->data = (void*)pcbddc; 505*0c7d97c5SJed Brown /* create PCIS data structure */ 506*0c7d97c5SJed Brown ierr = PCISCreate(pc);CHKERRQ(ierr); 507*0c7d97c5SJed Brown /* BDDC specific */ 508*0c7d97c5SJed Brown pcbddc->coarse_vec = 0; 509*0c7d97c5SJed Brown pcbddc->coarse_rhs = 0; 510*0c7d97c5SJed Brown pcbddc->coarse_pc = 0; 511*0c7d97c5SJed Brown pcbddc->coarse_phi_B = 0; 512*0c7d97c5SJed Brown pcbddc->coarse_phi_D = 0; 513*0c7d97c5SJed Brown pcbddc->vec1_P = 0; 514*0c7d97c5SJed Brown pcbddc->vec1_R = 0; 515*0c7d97c5SJed Brown pcbddc->vec2_R = 0; 516*0c7d97c5SJed Brown pcbddc->local_auxmat1 = 0; 517*0c7d97c5SJed Brown pcbddc->local_auxmat2 = 0; 518*0c7d97c5SJed Brown pcbddc->R_to_B = 0; 519*0c7d97c5SJed Brown pcbddc->R_to_D = 0; 520*0c7d97c5SJed Brown pcbddc->pc_D = 0; 521*0c7d97c5SJed Brown pcbddc->pc_R = 0; 522*0c7d97c5SJed Brown pcbddc->n_constraints = 0; 523*0c7d97c5SJed Brown pcbddc->n_vertices = 0; 524*0c7d97c5SJed Brown pcbddc->vertices = 0; 525*0c7d97c5SJed Brown pcbddc->indices_to_constraint = 0; 526*0c7d97c5SJed Brown pcbddc->quadrature_constraint = 0; 527*0c7d97c5SJed Brown pcbddc->sizes_of_constraint = 0; 528*0c7d97c5SJed Brown pcbddc->local_primal_indices = 0; 529*0c7d97c5SJed Brown pcbddc->prec_type = PETSC_FALSE; 530*0c7d97c5SJed Brown pcbddc->Vec_Neumann = 0; 531*0c7d97c5SJed Brown pcbddc->local_primal_sizes = 0; 532*0c7d97c5SJed Brown pcbddc->local_primal_displacements = 0; 533*0c7d97c5SJed Brown pcbddc->replicated_local_primal_indices = 0; 534*0c7d97c5SJed Brown pcbddc->replicated_local_primal_values = 0; 535*0c7d97c5SJed Brown pcbddc->coarse_loc_to_glob = 0; 536*0c7d97c5SJed Brown pcbddc->check_flag = PETSC_FALSE; 537*0c7d97c5SJed Brown pcbddc->vertices_flag = PETSC_FALSE; 538*0c7d97c5SJed Brown pcbddc->constraints_flag = PETSC_FALSE; 539*0c7d97c5SJed Brown pcbddc->faces_flag = PETSC_FALSE; 540*0c7d97c5SJed Brown pcbddc->edges_flag = PETSC_FALSE; 541*0c7d97c5SJed Brown pcbddc->coarsening_ratio = 8; 542*0c7d97c5SJed Brown /* function pointers */ 543*0c7d97c5SJed Brown pc->ops->apply = PCApply_BDDC; 544*0c7d97c5SJed Brown pc->ops->applytranspose = 0; 545*0c7d97c5SJed Brown pc->ops->setup = PCSetUp_BDDC; 546*0c7d97c5SJed Brown pc->ops->destroy = PCDestroy_BDDC; 547*0c7d97c5SJed Brown pc->ops->setfromoptions = PCSetFromOptions_BDDC; 548*0c7d97c5SJed Brown pc->ops->view = 0; 549*0c7d97c5SJed Brown pc->ops->applyrichardson = 0; 550*0c7d97c5SJed Brown pc->ops->applysymmetricleft = 0; 551*0c7d97c5SJed Brown pc->ops->applysymmetricright = 0; 552*0c7d97c5SJed Brown /* composing function */ 553*0c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetNeumannBoundaries_C","PCBDDCSetNeumannBoundaries_BDDC", 554*0c7d97c5SJed Brown PCBDDCSetNeumannBoundaries_BDDC);CHKERRQ(ierr); 555*0c7d97c5SJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCBDDCSetCoarseProblemType_C","PCBDDCSetCoarseProblemType_BDDC", 556*0c7d97c5SJed Brown PCBDDCSetCoarseProblemType_BDDC);CHKERRQ(ierr); 557*0c7d97c5SJed Brown PetscFunctionReturn(0); 558*0c7d97c5SJed Brown } 559*0c7d97c5SJed Brown EXTERN_C_END 560*0c7d97c5SJed Brown 561*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 562*0c7d97c5SJed Brown /* 563*0c7d97c5SJed Brown PCBDDCCoarseSetUp - 564*0c7d97c5SJed Brown */ 565*0c7d97c5SJed Brown #undef __FUNCT__ 566*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCCoarseSetUp" 567*0c7d97c5SJed Brown PetscErrorCode PCBDDCCoarseSetUp(PC pc) 568*0c7d97c5SJed Brown { 569*0c7d97c5SJed Brown PetscErrorCode ierr; 570*0c7d97c5SJed Brown 571*0c7d97c5SJed Brown PC_IS* pcis = (PC_IS*)(pc->data); 572*0c7d97c5SJed Brown PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 573*0c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 574*0c7d97c5SJed Brown IS is_R_local; 575*0c7d97c5SJed Brown IS is_V_local; 576*0c7d97c5SJed Brown IS is_C_local; 577*0c7d97c5SJed Brown IS is_aux1; 578*0c7d97c5SJed Brown IS is_aux2; 579*0c7d97c5SJed Brown PetscViewer viewer; 580*0c7d97c5SJed Brown PetscBool check_flag=pcbddc->check_flag; 581*0c7d97c5SJed Brown const VecType impVecType; 582*0c7d97c5SJed Brown const MatType impMatType; 583*0c7d97c5SJed Brown PetscInt n_R=0; 584*0c7d97c5SJed Brown PetscInt n_D=0; 585*0c7d97c5SJed Brown PetscInt n_B=0; 586*0c7d97c5SJed Brown PetscMPIInt totprocs; 587*0c7d97c5SJed Brown PetscScalar zero=0.0; 588*0c7d97c5SJed Brown PetscScalar one=1.0; 589*0c7d97c5SJed Brown PetscScalar m_one=-1.0; 590*0c7d97c5SJed Brown PetscScalar* array; 591*0c7d97c5SJed Brown PetscScalar *coarse_submat_vals; 592*0c7d97c5SJed Brown PetscInt *idx_R_local; 593*0c7d97c5SJed Brown PetscInt *idx_V_B; 594*0c7d97c5SJed Brown PetscScalar *coarsefunctions_errors; 595*0c7d97c5SJed Brown PetscScalar *constraints_errors; 596*0c7d97c5SJed Brown /* auxiliary indices */ 597*0c7d97c5SJed Brown PetscInt s,i,j,k; 598*0c7d97c5SJed Brown 599*0c7d97c5SJed Brown PetscFunctionBegin; 600*0c7d97c5SJed Brown // if ( !pcbddc->n_vertices && !pcbddc->n_constraints ) { 601*0c7d97c5SJed Brown // SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_WRONG,"BDDC preconditioner needs vertices and/or constraints!"); 602*0c7d97c5SJed Brown // } 603*0c7d97c5SJed Brown if(pcbddc->check_flag) { 604*0c7d97c5SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&viewer);CHKERRQ(ierr); 605*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 606*0c7d97c5SJed Brown } 607*0c7d97c5SJed Brown 608*0c7d97c5SJed Brown /* Set Non-overlapping dimensions */ 609*0c7d97c5SJed Brown n_B = pcis->n_B; n_D = pcis->n - n_B; 610*0c7d97c5SJed Brown /* Set local primal size */ 611*0c7d97c5SJed Brown pcbddc->local_primal_size = pcbddc->n_vertices + pcbddc->n_constraints; 612*0c7d97c5SJed Brown /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 613*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,one);CHKERRQ(ierr); 614*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 615*0c7d97c5SJed Brown for (i=0;i<pcbddc->n_vertices;i++) { array[ pcbddc->vertices[i] ] = zero; } 616*0c7d97c5SJed Brown ierr = PetscMalloc(( pcis->n - pcbddc->n_vertices )*sizeof(PetscInt),&idx_R_local);CHKERRQ(ierr); 617*0c7d97c5SJed Brown for (i=0, n_R=0; i<pcis->n; i++) { if (array[i] == one) { idx_R_local[n_R] = i; n_R++; } } 618*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 619*0c7d97c5SJed Brown if(check_flag) { 620*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 621*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 622*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 623*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 624*0c7d97c5SJed 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); 625*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 626*0c7d97c5SJed Brown } 627*0c7d97c5SJed Brown /* Allocate needed vectors */ 628*0c7d97c5SJed Brown /* Set Mat type for local matrices needed by BDDC precondtioner */ 629*0c7d97c5SJed Brown // ierr = MatGetType(matis->A,&impMatType);CHKERRQ(ierr); 630*0c7d97c5SJed Brown //ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 631*0c7d97c5SJed Brown impMatType = MATSEQDENSE; 632*0c7d97c5SJed Brown impVecType = VECSEQ; 633*0c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&pcbddc->vec4_D);CHKERRQ(ierr); 634*0c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_N,&pcis->vec2_N);CHKERRQ(ierr); 635*0c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_R);CHKERRQ(ierr); 636*0c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_R,n_R,n_R);CHKERRQ(ierr); 637*0c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 638*0c7d97c5SJed Brown ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R); 639*0c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&pcbddc->vec1_P);CHKERRQ(ierr); 640*0c7d97c5SJed Brown ierr = VecSetSizes(pcbddc->vec1_P,pcbddc->local_primal_size,pcbddc->local_primal_size);CHKERRQ(ierr); 641*0c7d97c5SJed Brown ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 642*0c7d97c5SJed Brown 643*0c7d97c5SJed Brown /* Creating some index sets needed */ 644*0c7d97c5SJed Brown /* For submatrices */ 645*0c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,n_R,idx_R_local,PETSC_COPY_VALUES,&is_R_local);CHKERRQ(ierr); 646*0c7d97c5SJed Brown if(pcbddc->n_vertices) { ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->vertices,PETSC_COPY_VALUES,&is_V_local);CHKERRQ(ierr); } 647*0c7d97c5SJed Brown if(pcbddc->n_constraints) { ierr = ISCreateStride (PETSC_COMM_SELF,pcbddc->n_constraints,pcbddc->n_vertices,1,&is_C_local);CHKERRQ(ierr); } 648*0c7d97c5SJed Brown /* For VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 649*0c7d97c5SJed Brown { 650*0c7d97c5SJed Brown PetscInt *aux_array1; 651*0c7d97c5SJed Brown PetscInt *aux_array2; 652*0c7d97c5SJed Brown PetscScalar value; 653*0c7d97c5SJed Brown 654*0c7d97c5SJed Brown ierr = PetscMalloc( (pcis->n_B-pcbddc->n_vertices)*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 655*0c7d97c5SJed Brown ierr = PetscMalloc( (pcis->n_B-pcbddc->n_vertices)*sizeof(PetscInt),&aux_array2);CHKERRQ(ierr); 656*0c7d97c5SJed Brown 657*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_global,zero); 658*0c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 659*0c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 660*0c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 661*0c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 662*0c7d97c5SJed Brown ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 663*0c7d97c5SJed Brown ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 664*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 665*0c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] > one) { aux_array1[s] = i; s++; } } 666*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 667*0c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 668*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 669*0c7d97c5SJed Brown for (i=0, s=0; i<n_B; i++) { if (array[i] > one) { aux_array2[s] = i; s++; } } 670*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 671*0c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array2,PETSC_COPY_VALUES,&is_aux2);CHKERRQ(ierr); 672*0c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 673*0c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 674*0c7d97c5SJed Brown ierr = PetscFree(aux_array2);CHKERRQ(ierr); 675*0c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 676*0c7d97c5SJed Brown ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 677*0c7d97c5SJed Brown 678*0c7d97c5SJed Brown if(pcbddc->prec_type || check_flag ) { 679*0c7d97c5SJed Brown ierr = PetscMalloc(n_D*sizeof(PetscInt),&aux_array1);CHKERRQ(ierr); 680*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 681*0c7d97c5SJed Brown for (i=0, s=0; i<n_R; i++) { if (array[idx_R_local[i]] == one) { aux_array1[s] = i; s++; } } 682*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 683*0c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,s,aux_array1,PETSC_COPY_VALUES,&is_aux1);CHKERRQ(ierr); 684*0c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 685*0c7d97c5SJed Brown ierr = PetscFree(aux_array1);CHKERRQ(ierr); 686*0c7d97c5SJed Brown ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 687*0c7d97c5SJed Brown } 688*0c7d97c5SJed Brown 689*0c7d97c5SJed Brown /* Check scatters */ 690*0c7d97c5SJed Brown if(check_flag) { 691*0c7d97c5SJed Brown 692*0c7d97c5SJed Brown Vec vec_aux; 693*0c7d97c5SJed Brown 694*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 695*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_B scatter\n");CHKERRQ(ierr); 696*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 697*0c7d97c5SJed Brown ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL); 698*0c7d97c5SJed Brown ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL); 699*0c7d97c5SJed Brown ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux); 700*0c7d97c5SJed Brown ierr = VecCopy(pcbddc->vec1_R,vec_aux); 701*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD); 702*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD); 703*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE); 704*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,vec_aux,INSERT_VALUES,SCATTER_REVERSE); 705*0c7d97c5SJed Brown ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R); 706*0c7d97c5SJed Brown ierr = VecNorm(vec_aux,NORM_INFINITY,&value); 707*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 708*0c7d97c5SJed Brown ierr = VecDestroy(&vec_aux); 709*0c7d97c5SJed Brown 710*0c7d97c5SJed Brown ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL); 711*0c7d97c5SJed Brown ierr = VecSetRandom(pcis->vec1_B,PETSC_NULL); 712*0c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_B,&vec_aux); 713*0c7d97c5SJed Brown ierr = VecCopy(pcis->vec1_B,vec_aux); 714*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE); 715*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcis->vec1_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE); 716*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD); 717*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD); 718*0c7d97c5SJed Brown ierr = VecAXPY(vec_aux,m_one,pcis->vec1_B); 719*0c7d97c5SJed Brown ierr = VecNorm(vec_aux,NORM_INFINITY,&value); 720*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_B REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 721*0c7d97c5SJed Brown ierr = VecDestroy(&vec_aux); 722*0c7d97c5SJed Brown 723*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 724*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking pcbddc->R_to_D scatter\n");CHKERRQ(ierr); 725*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 726*0c7d97c5SJed Brown 727*0c7d97c5SJed Brown ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL); 728*0c7d97c5SJed Brown ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL); 729*0c7d97c5SJed Brown ierr = VecDuplicate(pcbddc->vec1_R,&vec_aux); 730*0c7d97c5SJed Brown ierr = VecCopy(pcbddc->vec1_R,vec_aux); 731*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD); 732*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD); 733*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE); 734*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,vec_aux,INSERT_VALUES,SCATTER_REVERSE); 735*0c7d97c5SJed Brown ierr = VecAXPY(vec_aux,m_one,pcbddc->vec1_R); 736*0c7d97c5SJed Brown ierr = VecNorm(vec_aux,NORM_INFINITY,&value); 737*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D FORWARD error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 738*0c7d97c5SJed Brown ierr = VecDestroy(&vec_aux); 739*0c7d97c5SJed Brown 740*0c7d97c5SJed Brown ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL); 741*0c7d97c5SJed Brown ierr = VecSetRandom(pcis->vec1_D,PETSC_NULL); 742*0c7d97c5SJed Brown ierr = VecDuplicate(pcis->vec1_D,&vec_aux); 743*0c7d97c5SJed Brown ierr = VecCopy(pcis->vec1_D,vec_aux); 744*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE); 745*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcis->vec1_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE); 746*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD); 747*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_D,pcbddc->vec1_R,vec_aux,INSERT_VALUES,SCATTER_FORWARD); 748*0c7d97c5SJed Brown ierr = VecAXPY(vec_aux,m_one,pcis->vec1_D); 749*0c7d97c5SJed Brown ierr = VecNorm(vec_aux,NORM_INFINITY,&value); 750*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d R_to_D REVERSE error = % 1.14e\n",PetscGlobalRank,value);CHKERRQ(ierr); 751*0c7d97c5SJed Brown ierr = VecDestroy(&vec_aux); 752*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 753*0c7d97c5SJed Brown 754*0c7d97c5SJed Brown } 755*0c7d97c5SJed Brown } 756*0c7d97c5SJed Brown 757*0c7d97c5SJed Brown /* vertices in boundary numbering */ 758*0c7d97c5SJed Brown if(pcbddc->n_vertices) { 759*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,m_one); 760*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 761*0c7d97c5SJed Brown for (i=0; i<pcbddc->n_vertices; i++) { array[ pcbddc->vertices[i] ] = i; } 762*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 763*0c7d97c5SJed Brown ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD); 764*0c7d97c5SJed Brown ierr = VecScatterEnd (pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD); 765*0c7d97c5SJed Brown ierr = PetscMalloc(pcbddc->n_vertices*sizeof(PetscInt),&idx_V_B);CHKERRQ(ierr); 766*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 767*0c7d97c5SJed Brown //printf("vertices in boundary numbering\n"); 768*0c7d97c5SJed Brown for (i=0; i<pcbddc->n_vertices; i++) { 769*0c7d97c5SJed Brown s=0; 770*0c7d97c5SJed Brown while (array[s] != i ) {s++;} 771*0c7d97c5SJed Brown idx_V_B[i]=s; 772*0c7d97c5SJed Brown //printf("idx_V_B[%d]=%d\n",i,s); 773*0c7d97c5SJed Brown } 774*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 775*0c7d97c5SJed Brown } 776*0c7d97c5SJed Brown 777*0c7d97c5SJed Brown 778*0c7d97c5SJed Brown /* Assign global numbering to coarse dofs */ 779*0c7d97c5SJed Brown // TODO move this block before calling SetupCoarseEnvironment 780*0c7d97c5SJed Brown { 781*0c7d97c5SJed Brown PetscScalar coarsesum; 782*0c7d97c5SJed Brown PetscMPIInt *auxlocal_primal; 783*0c7d97c5SJed Brown PetscMPIInt *auxglobal_primal; 784*0c7d97c5SJed Brown PetscMPIInt *all_auxglobal_primal; 785*0c7d97c5SJed Brown PetscMPIInt *all_auxglobal_primal_type; /* dummy */ 786*0c7d97c5SJed Brown 787*0c7d97c5SJed Brown ierr = MPI_Comm_size(((PetscObject)pc)->comm,&totprocs);CHKERRQ(ierr); 788*0c7d97c5SJed Brown /* Construct needed data structures for message passing */ 789*0c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscMPIInt),&pcbddc->local_primal_indices);CHKERRQ(ierr); 790*0c7d97c5SJed Brown ierr = PetscMalloc( totprocs*sizeof(PetscMPIInt), &pcbddc->local_primal_sizes);CHKERRQ(ierr); 791*0c7d97c5SJed Brown ierr = PetscMalloc( totprocs*sizeof(PetscMPIInt), &pcbddc->local_primal_displacements);CHKERRQ(ierr); 792*0c7d97c5SJed Brown /* Gather local_primal_size information to all processes */ 793*0c7d97c5SJed Brown ierr = MPI_Allgather(&pcbddc->local_primal_size,1,MPIU_INT,&pcbddc->local_primal_sizes[0],1,MPIU_INT, ((PetscObject)pc)->comm );CHKERRQ(ierr); 794*0c7d97c5SJed Brown pcbddc->replicated_primal_size = 0; 795*0c7d97c5SJed Brown for (i=0; i<totprocs; i++) { 796*0c7d97c5SJed Brown pcbddc->local_primal_displacements[i] = pcbddc->replicated_primal_size ; 797*0c7d97c5SJed Brown pcbddc->replicated_primal_size += pcbddc->local_primal_sizes[i]; 798*0c7d97c5SJed Brown } 799*0c7d97c5SJed Brown /* allocate some auxiliary space */ 800*0c7d97c5SJed Brown ierr = PetscMalloc( (pcbddc->local_primal_size)*sizeof(PetscMPIInt), &auxlocal_primal);CHKERRQ(ierr); 801*0c7d97c5SJed Brown ierr = PetscMalloc( (pcbddc->local_primal_size)*sizeof(PetscMPIInt), &auxglobal_primal);CHKERRQ(ierr); 802*0c7d97c5SJed Brown ierr = PetscMalloc( (pcbddc->replicated_primal_size)*sizeof(PetscMPIInt), &all_auxglobal_primal);CHKERRQ(ierr); 803*0c7d97c5SJed Brown ierr = PetscMalloc( (pcbddc->replicated_primal_size)*sizeof(PetscMPIInt),&all_auxglobal_primal_type);CHKERRQ(ierr); 804*0c7d97c5SJed Brown 805*0c7d97c5SJed Brown /* 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) 806*0c7d97c5SJed Brown This code fragment assumes that the number of local constraints per connected component 807*0c7d97c5SJed Brown is not greater than the number of nodes on the connected component (for each dof) 808*0c7d97c5SJed Brown (otherwise we will surely have linear dependence between constraints and thus a singular coarse problem) */ 809*0c7d97c5SJed Brown /* auxlocal_primal : primal indices in local nodes numbering (internal and interface) */ 810*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,zero); 811*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 812*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { 813*0c7d97c5SJed Brown array[ pcbddc->vertices[i] ] = one; 814*0c7d97c5SJed Brown auxlocal_primal[i] = pcbddc->vertices[i]; 815*0c7d97c5SJed Brown } 816*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 817*0c7d97c5SJed Brown for (s=0; s<pcbddc->sizes_of_constraint[i]; s++) { 818*0c7d97c5SJed Brown k = pcbddc->indices_to_constraint[i][s]; 819*0c7d97c5SJed Brown if( array[k] == zero ) { 820*0c7d97c5SJed Brown array[k] = one; 821*0c7d97c5SJed Brown auxlocal_primal[i+pcbddc->n_vertices] = k; 822*0c7d97c5SJed Brown break; 823*0c7d97c5SJed Brown } 824*0c7d97c5SJed Brown } 825*0c7d97c5SJed Brown } 826*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 827*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 828*0c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 829*0c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 830*0c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 831*0c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 832*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 833*0c7d97c5SJed Brown for(i=0;i<pcis->n;i++) { 834*0c7d97c5SJed Brown if(array[i]) { array[i] = one/array[i]; } 835*0c7d97c5SJed Brown } 836*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 837*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_global,zero);CHKERRQ(ierr); 838*0c7d97c5SJed Brown ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 839*0c7d97c5SJed Brown ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 840*0c7d97c5SJed Brown 841*0c7d97c5SJed Brown ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 842*0c7d97c5SJed Brown pcbddc->coarse_size = (PetscInt) coarsesum; 843*0c7d97c5SJed Brown if(check_flag) { 844*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 845*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Size of coarse problem = %d\n",pcbddc->coarse_size);CHKERRQ(ierr); 846*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 847*0c7d97c5SJed Brown } 848*0c7d97c5SJed Brown /* Now assign them a global numbering */ 849*0c7d97c5SJed Brown /* auxglobal_primal contains indices in global nodes numbering (internal and interface) */ 850*0c7d97c5SJed Brown ierr = ISLocalToGlobalMappingApply(matis->mapping,pcbddc->local_primal_size,auxlocal_primal,auxglobal_primal);CHKERRQ(ierr); 851*0c7d97c5SJed Brown /* all_auxglobal_primal contains all primal nodes indices in global nodes numbering (internal and interface) */ 852*0c7d97c5SJed Brown ierr = MPI_Allgatherv(&auxglobal_primal[0],pcbddc->local_primal_size,MPIU_INT,&all_auxglobal_primal[0],pcbddc->local_primal_sizes,pcbddc->local_primal_displacements,MPIU_INT, ((PetscObject)pc)->comm );CHKERRQ(ierr); 853*0c7d97c5SJed Brown /* aux_global_type is a dummy argument (PetscSortMPIInt doesn't exist!) */ 854*0c7d97c5SJed Brown ierr = PetscSortMPIIntWithArray( pcbddc->replicated_primal_size,all_auxglobal_primal,all_auxglobal_primal_type);CHKERRQ(ierr); 855*0c7d97c5SJed Brown k=1; 856*0c7d97c5SJed Brown j=all_auxglobal_primal[0]; /* first dof in global numbering */ 857*0c7d97c5SJed Brown for(i=1;i< pcbddc->replicated_primal_size ;i++) { 858*0c7d97c5SJed Brown if(j != all_auxglobal_primal[i] ) { 859*0c7d97c5SJed Brown all_auxglobal_primal[k]=all_auxglobal_primal[i]; 860*0c7d97c5SJed Brown k++; 861*0c7d97c5SJed Brown j=all_auxglobal_primal[i]; 862*0c7d97c5SJed Brown } 863*0c7d97c5SJed Brown } 864*0c7d97c5SJed Brown /* At this point all_auxglobal_primal should contains one copy of each primal node's indices in global nodes numbering */ 865*0c7d97c5SJed Brown /* We need only the indices from 0 to pcbddc->coarse_size. Remaning elements of array are garbage. */ 866*0c7d97c5SJed Brown /* Now get global coarse numbering of local primal nodes */ 867*0c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) { 868*0c7d97c5SJed Brown k=0; 869*0c7d97c5SJed Brown while( all_auxglobal_primal[k] != auxglobal_primal[i] ) { k++;} 870*0c7d97c5SJed Brown pcbddc->local_primal_indices[i]=k; 871*0c7d97c5SJed Brown } 872*0c7d97c5SJed Brown if(check_flag) { 873*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 874*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 875*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 876*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 877*0c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) { 878*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local_primal_indices[%d]=%d \n",i,pcbddc->local_primal_indices[i]); 879*0c7d97c5SJed Brown } 880*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 881*0c7d97c5SJed Brown } 882*0c7d97c5SJed Brown /* free allocated memory */ 883*0c7d97c5SJed Brown ierr = PetscFree( auxlocal_primal);CHKERRQ(ierr); 884*0c7d97c5SJed Brown ierr = PetscFree( auxglobal_primal);CHKERRQ(ierr); 885*0c7d97c5SJed Brown ierr = PetscFree( all_auxglobal_primal);CHKERRQ(ierr); 886*0c7d97c5SJed Brown ierr = PetscFree(all_auxglobal_primal_type);CHKERRQ(ierr); 887*0c7d97c5SJed Brown 888*0c7d97c5SJed Brown } 889*0c7d97c5SJed Brown 890*0c7d97c5SJed Brown /* Creating PC contexts for local Dirichlet and Neumann problems */ 891*0c7d97c5SJed Brown { 892*0c7d97c5SJed Brown Mat A_RR; 893*0c7d97c5SJed Brown /* Matrix for Dirichlet problem is A_II -> we already have it from pcis.c code */ 894*0c7d97c5SJed Brown ierr = PCCreate(PETSC_COMM_SELF,&pcbddc->pc_D);CHKERRQ(ierr); 895*0c7d97c5SJed Brown ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->pc_D,(PetscObject)pc,1);CHKERRQ(ierr); 896*0c7d97c5SJed Brown ierr = PCSetOperators(pcbddc->pc_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 897*0c7d97c5SJed Brown ierr = PCSetOptionsPrefix(pcbddc->pc_D,"pc_bddc_localD_");CHKERRQ(ierr); 898*0c7d97c5SJed Brown /* default */ 899*0c7d97c5SJed Brown ierr = PCSetType(pcbddc->pc_D,PCLU);CHKERRQ(ierr); 900*0c7d97c5SJed Brown /* Allow user's customization */ 901*0c7d97c5SJed Brown ierr = PCSetFromOptions(pcbddc->pc_D);CHKERRQ(ierr); 902*0c7d97c5SJed Brown /* Set Up PC for Dirichlet problem of BDDC */ 903*0c7d97c5SJed Brown ierr = PCSetUp(pcbddc->pc_D);CHKERRQ(ierr); 904*0c7d97c5SJed Brown /* Matrix for Neumann problem is A_RR -> we need to create it */ 905*0c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 906*0c7d97c5SJed Brown ierr = PCCreate(PETSC_COMM_SELF,&pcbddc->pc_R);CHKERRQ(ierr); 907*0c7d97c5SJed Brown ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->pc_R,(PetscObject)pc,1);CHKERRQ(ierr); 908*0c7d97c5SJed Brown ierr = PCSetOperators(pcbddc->pc_R,A_RR,A_RR,SAME_PRECONDITIONER);CHKERRQ(ierr); 909*0c7d97c5SJed Brown ierr = PCSetOptionsPrefix(pcbddc->pc_R,"pc_bddc_localN_");CHKERRQ(ierr); 910*0c7d97c5SJed Brown /* default */ 911*0c7d97c5SJed Brown ierr = PCSetType(pcbddc->pc_R,PCLU);CHKERRQ(ierr); 912*0c7d97c5SJed Brown /* Allow user's customization */ 913*0c7d97c5SJed Brown ierr = PCSetFromOptions(pcbddc->pc_R);CHKERRQ(ierr); 914*0c7d97c5SJed Brown /* Set Up PC for Neumann problem of BDDC */ 915*0c7d97c5SJed Brown ierr = PCSetUp(pcbddc->pc_R);CHKERRQ(ierr); 916*0c7d97c5SJed Brown /* check Neumann solve */ 917*0c7d97c5SJed Brown if(pcbddc->check_flag) { 918*0c7d97c5SJed Brown Vec temp_vec; 919*0c7d97c5SJed Brown PetscScalar value; 920*0c7d97c5SJed Brown 921*0c7d97c5SJed Brown ierr = VecDuplicate(pcbddc->vec1_R,&temp_vec); 922*0c7d97c5SJed Brown ierr = VecSetRandom(pcbddc->vec1_R,PETSC_NULL); 923*0c7d97c5SJed Brown ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R); 924*0c7d97c5SJed Brown ierr = PCApply(pcbddc->pc_R,pcbddc->vec2_R,temp_vec); 925*0c7d97c5SJed Brown ierr = VecAXPY(temp_vec,m_one,pcbddc->vec1_R); 926*0c7d97c5SJed Brown ierr = VecNorm(temp_vec,NORM_INFINITY,&value); 927*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer); 928*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 929*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Checking solution of Neumann problem\n");CHKERRQ(ierr); 930*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d infinity error for Neumann solve = % 1.14e \n",PetscGlobalRank,value);CHKERRQ(ierr); 931*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer); 932*0c7d97c5SJed Brown ierr = VecDestroy(&temp_vec); 933*0c7d97c5SJed Brown } 934*0c7d97c5SJed Brown /* free Neumann problem's matrix */ 935*0c7d97c5SJed Brown ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 936*0c7d97c5SJed Brown } 937*0c7d97c5SJed Brown 938*0c7d97c5SJed Brown /* Assemble all remaining stuff needed to apply BDDC */ 939*0c7d97c5SJed Brown { 940*0c7d97c5SJed Brown Mat A_RV,A_VR,A_VV; 941*0c7d97c5SJed Brown Mat M1,M2; 942*0c7d97c5SJed Brown Mat C_CR; 943*0c7d97c5SJed Brown Mat CMAT,AUXMAT; 944*0c7d97c5SJed Brown Vec vec1_C; 945*0c7d97c5SJed Brown Vec vec2_C; 946*0c7d97c5SJed Brown Vec vec1_V; 947*0c7d97c5SJed Brown Vec vec2_V; 948*0c7d97c5SJed Brown PetscInt *nnz; 949*0c7d97c5SJed Brown PetscInt *auxindices; 950*0c7d97c5SJed Brown PetscInt index[0]; 951*0c7d97c5SJed Brown PetscScalar* array2; 952*0c7d97c5SJed Brown MatFactorInfo matinfo; 953*0c7d97c5SJed Brown 954*0c7d97c5SJed Brown /* Allocating some extra storage just to be safe */ 955*0c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 956*0c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&auxindices);CHKERRQ(ierr); 957*0c7d97c5SJed Brown for(i=0;i<pcis->n;i++) {auxindices[i]=i;} 958*0c7d97c5SJed Brown 959*0c7d97c5SJed Brown /* some work vectors on vertices and/or constraints */ 960*0c7d97c5SJed Brown if(pcbddc->n_vertices) { 961*0c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_V);CHKERRQ(ierr); 962*0c7d97c5SJed Brown ierr = VecSetSizes(vec1_V,pcbddc->n_vertices,pcbddc->n_vertices);CHKERRQ(ierr); 963*0c7d97c5SJed Brown ierr = VecSetType(vec1_V,impVecType);CHKERRQ(ierr); 964*0c7d97c5SJed Brown ierr = VecDuplicate(vec1_V,&vec2_V);CHKERRQ(ierr); 965*0c7d97c5SJed Brown } 966*0c7d97c5SJed Brown if(pcbddc->n_constraints) { 967*0c7d97c5SJed Brown ierr = VecCreate(PETSC_COMM_SELF,&vec1_C);CHKERRQ(ierr); 968*0c7d97c5SJed Brown ierr = VecSetSizes(vec1_C,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 969*0c7d97c5SJed Brown ierr = VecSetType(vec1_C,impVecType);CHKERRQ(ierr); 970*0c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&vec2_C); CHKERRQ(ierr); 971*0c7d97c5SJed Brown ierr = VecDuplicate(vec1_C,&pcbddc->vec1_C); CHKERRQ(ierr); 972*0c7d97c5SJed Brown } 973*0c7d97c5SJed Brown /* Create C matrix [I 0; 0 const] */ 974*0c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&CMAT); 975*0c7d97c5SJed Brown ierr = MatSetType(CMAT,MATSEQAIJ);CHKERRQ(ierr); 976*0c7d97c5SJed Brown ierr = MatSetSizes(CMAT,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 977*0c7d97c5SJed Brown /* nonzeros */ 978*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { nnz[i]= 1; } 979*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { nnz[i+pcbddc->n_vertices]=pcbddc->sizes_of_constraint[i];} 980*0c7d97c5SJed Brown ierr = MatSeqAIJSetPreallocation(CMAT,0,nnz);CHKERRQ(ierr); 981*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { 982*0c7d97c5SJed Brown ierr = MatSetValue(CMAT,i,pcbddc->vertices[i],1.0,INSERT_VALUES); CHKERRQ(ierr); 983*0c7d97c5SJed Brown } 984*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 985*0c7d97c5SJed Brown index[0]=i+pcbddc->n_vertices; 986*0c7d97c5SJed Brown ierr = MatSetValues(CMAT,1,index,pcbddc->sizes_of_constraint[i],pcbddc->indices_to_constraint[i],pcbddc->quadrature_constraint[i],INSERT_VALUES); CHKERRQ(ierr); 987*0c7d97c5SJed Brown } 988*0c7d97c5SJed Brown //if(check_flag) printf("CMAT assembling\n"); 989*0c7d97c5SJed Brown ierr = MatAssemblyBegin(CMAT,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 990*0c7d97c5SJed Brown ierr = MatAssemblyEnd(CMAT,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 991*0c7d97c5SJed Brown //ierr = MatView(CMAT,PETSC_VIEWER_STDOUT_SELF); 992*0c7d97c5SJed Brown 993*0c7d97c5SJed Brown /* Precompute stuffs needed for preprocessing and application of BDDC*/ 994*0c7d97c5SJed Brown 995*0c7d97c5SJed Brown if(pcbddc->n_constraints) { 996*0c7d97c5SJed Brown /* some work vectors */ 997*0c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->local_auxmat2);CHKERRQ(ierr); 998*0c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->local_auxmat2,n_R,pcbddc->n_constraints,n_R,pcbddc->n_constraints);CHKERRQ(ierr); 999*0c7d97c5SJed Brown ierr = MatSetType(pcbddc->local_auxmat2,impMatType);CHKERRQ(ierr); 1000*0c7d97c5SJed Brown 1001*0c7d97c5SJed Brown /* Assemble local_auxmat2 = - A_{RR}^{-1} C^T_{CR} needed by BDDC application */ 1002*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 1003*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,zero); 1004*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1005*0c7d97c5SJed Brown for(j=0;j<pcbddc->sizes_of_constraint[i];j++) { array[ pcbddc->indices_to_constraint[i][j] ] = - pcbddc->quadrature_constraint[i][j]; } 1006*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 1007*0c7d97c5SJed Brown for(j=0;j<n_R;j++) { array2[j] = array[ idx_R_local[j] ]; } 1008*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1009*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 1010*0c7d97c5SJed Brown ierr = PCApply(pcbddc->pc_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1011*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 1012*0c7d97c5SJed Brown index[0]=i; 1013*0c7d97c5SJed Brown ierr = MatSetValues(pcbddc->local_auxmat2,n_R,auxindices,1,index,array,INSERT_VALUES); CHKERRQ(ierr); 1014*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 1015*0c7d97c5SJed Brown } 1016*0c7d97c5SJed Brown //if(check_flag) printf("pcbddc->local_auxmat2 assembling\n"); 1017*0c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1018*0c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->local_auxmat2,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1019*0c7d97c5SJed Brown 1020*0c7d97c5SJed Brown /* Create Constraint matrix on R nodes: C_{CR} */ 1021*0c7d97c5SJed Brown ierr = MatGetSubMatrix(CMAT,is_C_local,is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 1022*0c7d97c5SJed Brown ierr = ISDestroy(&is_C_local); CHKERRQ(ierr); 1023*0c7d97c5SJed Brown 1024*0c7d97c5SJed Brown /* Assemble AUXMAT = ( LUFactor )( -C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 1025*0c7d97c5SJed Brown ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AUXMAT); CHKERRQ(ierr); 1026*0c7d97c5SJed Brown ierr = MatFactorInfoInitialize(&matinfo); 1027*0c7d97c5SJed Brown ierr = ISCreateStride (PETSC_COMM_SELF,pcbddc->n_constraints,0,1,&is_aux1);CHKERRQ(ierr); 1028*0c7d97c5SJed Brown ierr = MatLUFactor(AUXMAT,is_aux1,is_aux1,&matinfo);CHKERRQ(ierr); 1029*0c7d97c5SJed Brown ierr = ISDestroy(&is_aux1); CHKERRQ(ierr); 1030*0c7d97c5SJed Brown 1031*0c7d97c5SJed Brown /* Assemble explicitly M1 = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} needed in preproc (should be dense) */ 1032*0c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&M1); 1033*0c7d97c5SJed Brown ierr = MatSetSizes(M1,pcbddc->n_constraints,pcbddc->n_constraints,pcbddc->n_constraints,pcbddc->n_constraints);CHKERRQ(ierr); 1034*0c7d97c5SJed Brown ierr = MatSetType(M1,impMatType);CHKERRQ(ierr); 1035*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++) { 1036*0c7d97c5SJed Brown ierr = VecSet(vec1_C,zero);CHKERRQ(ierr); 1037*0c7d97c5SJed Brown ierr = VecSetValue(vec1_C,i,one,INSERT_VALUES);CHKERRQ(ierr); 1038*0c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_C);CHKERRQ(ierr); 1039*0c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_C);CHKERRQ(ierr); 1040*0c7d97c5SJed Brown ierr = MatSolve(AUXMAT,vec1_C,vec2_C);CHKERRQ(ierr); 1041*0c7d97c5SJed Brown ierr = VecScale(vec2_C,m_one);CHKERRQ(ierr); 1042*0c7d97c5SJed Brown ierr = VecGetArray(vec2_C,&array);CHKERRQ(ierr); 1043*0c7d97c5SJed Brown index[0]=i; 1044*0c7d97c5SJed Brown ierr = MatSetValues(M1,pcbddc->n_constraints,auxindices,1,index,array,INSERT_VALUES);CHKERRQ(ierr); 1045*0c7d97c5SJed Brown ierr = VecRestoreArray(vec2_C,&array);CHKERRQ(ierr); 1046*0c7d97c5SJed Brown } 1047*0c7d97c5SJed Brown //if(check_flag) printf("M1 assembling\n"); 1048*0c7d97c5SJed Brown ierr = MatAssemblyBegin(M1,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1049*0c7d97c5SJed Brown ierr = MatAssemblyEnd (M1,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1050*0c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 1051*0c7d97c5SJed Brown /* Assemble local_auxmat1 = M1*C_{CR} needed by BDDC application in KSP and in preproc */ 1052*0c7d97c5SJed Brown //if(check_flag) printf("pcbddc->local_auxmat1 computing and assembling\n"); 1053*0c7d97c5SJed Brown ierr = MatMatMult(M1,C_CR,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1); CHKERRQ(ierr); 1054*0c7d97c5SJed Brown 1055*0c7d97c5SJed Brown } 1056*0c7d97c5SJed Brown 1057*0c7d97c5SJed Brown /* Get submatrices from subdomain matrix */ 1058*0c7d97c5SJed Brown if(pcbddc->n_vertices){ 1059*0c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_R_local,is_V_local,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 1060*0c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 1061*0c7d97c5SJed Brown ierr = MatGetSubMatrix(matis->A,is_V_local,is_V_local,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 1062*0c7d97c5SJed Brown /* Assemble M2 = A_RR^{-1}A_RV */ 1063*0c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&M2); 1064*0c7d97c5SJed Brown ierr = MatSetSizes(M2,n_R,pcbddc->n_vertices,n_R,pcbddc->n_vertices);CHKERRQ(ierr); 1065*0c7d97c5SJed Brown ierr = MatSetType(M2,impMatType);CHKERRQ(ierr); 1066*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++) { 1067*0c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 1068*0c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 1069*0c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 1070*0c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 1071*0c7d97c5SJed Brown ierr = MatMult(A_RV,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 1072*0c7d97c5SJed Brown ierr = PCApply(pcbddc->pc_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 1073*0c7d97c5SJed Brown index[0]=i; 1074*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 1075*0c7d97c5SJed Brown ierr = MatSetValues(M2,n_R,auxindices,1,index,array,INSERT_VALUES);CHKERRQ(ierr); 1076*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec2_R,&array);CHKERRQ(ierr); 1077*0c7d97c5SJed Brown } 1078*0c7d97c5SJed Brown //if(check_flag) printf("M2 assembling\n"); 1079*0c7d97c5SJed Brown ierr = MatAssemblyBegin(M2,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1080*0c7d97c5SJed Brown ierr = MatAssemblyEnd (M2,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1081*0c7d97c5SJed Brown } 1082*0c7d97c5SJed Brown 1083*0c7d97c5SJed Brown /* Matrix of coarse basis functions (local) */ 1084*0c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_B); 1085*0c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_B,n_B,pcbddc->local_primal_size,n_B,pcbddc->local_primal_size);CHKERRQ(ierr); 1086*0c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_B,impMatType);CHKERRQ(ierr); 1087*0c7d97c5SJed Brown if(pcbddc->prec_type || check_flag ) { 1088*0c7d97c5SJed Brown ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->coarse_phi_D); 1089*0c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_phi_D,n_D,pcbddc->local_primal_size,n_D,pcbddc->local_primal_size);CHKERRQ(ierr); 1090*0c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_phi_D,impMatType);CHKERRQ(ierr); 1091*0c7d97c5SJed Brown } 1092*0c7d97c5SJed Brown 1093*0c7d97c5SJed Brown /* Subdomain contribution (Non-overlapping) to coarse matrix */ 1094*0c7d97c5SJed Brown if(check_flag) { 1095*0c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&coarsefunctions_errors);CHKERRQ(ierr); 1096*0c7d97c5SJed Brown ierr = PetscMalloc( pcbddc->local_primal_size*sizeof(PetscScalar),&constraints_errors);CHKERRQ(ierr); 1097*0c7d97c5SJed Brown } 1098*0c7d97c5SJed Brown ierr = PetscMalloc ((pcbddc->local_primal_size)*(pcbddc->local_primal_size)*sizeof(PetscScalar),&coarse_submat_vals);CHKERRQ(ierr); 1099*0c7d97c5SJed Brown 1100*0c7d97c5SJed Brown /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 1101*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++){ 1102*0c7d97c5SJed Brown ierr = VecSet(vec1_V,zero);CHKERRQ(ierr); 1103*0c7d97c5SJed Brown ierr = VecSetValue(vec1_V,i,one,INSERT_VALUES);CHKERRQ(ierr); 1104*0c7d97c5SJed Brown ierr = VecAssemblyBegin(vec1_V);CHKERRQ(ierr); 1105*0c7d97c5SJed Brown ierr = VecAssemblyEnd(vec1_V);CHKERRQ(ierr); 1106*0c7d97c5SJed Brown /* solution of saddle point problem */ 1107*0c7d97c5SJed Brown ierr = MatMult(M2,vec1_V,pcbddc->vec1_R);CHKERRQ(ierr); 1108*0c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_R,m_one);CHKERRQ(ierr); 1109*0c7d97c5SJed Brown if(pcbddc->n_constraints) { 1110*0c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat1,pcbddc->vec1_R,vec1_C);CHKERRQ(ierr); 1111*0c7d97c5SJed Brown ierr = MatMultAdd(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 1112*0c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 1113*0c7d97c5SJed Brown } 1114*0c7d97c5SJed Brown ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); 1115*0c7d97c5SJed Brown ierr = MatMultAdd(A_VV,vec1_V,vec2_V,vec2_V);CHKERRQ(ierr); 1116*0c7d97c5SJed Brown 1117*0c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 1118*0c7d97c5SJed Brown /* coarse basis functions */ 1119*0c7d97c5SJed Brown index[0]=i; 1120*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1121*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1122*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1123*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1124*0c7d97c5SJed Brown ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,index,array,INSERT_VALUES);CHKERRQ(ierr); 1125*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1126*0c7d97c5SJed Brown ierr = MatSetValue(pcbddc->coarse_phi_B,idx_V_B[i],i,one,INSERT_VALUES);CHKERRQ(ierr); 1127*0c7d97c5SJed Brown if( pcbddc->prec_type || check_flag ) { 1128*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1129*0c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1130*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 1131*0c7d97c5SJed Brown ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,index,array,INSERT_VALUES);CHKERRQ(ierr); 1132*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 1133*0c7d97c5SJed Brown } 1134*0c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 1135*0c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1136*0c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) {coarse_submat_vals[i*pcbddc->local_primal_size+j]=array[j];} //WARNING -> column major ordering 1137*0c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 1138*0c7d97c5SJed Brown if( pcbddc->n_constraints) { 1139*0c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1140*0c7d97c5SJed 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 1141*0c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 1142*0c7d97c5SJed Brown } 1143*0c7d97c5SJed Brown 1144*0c7d97c5SJed Brown if( check_flag ) { 1145*0c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1146*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,zero); 1147*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1148*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 1149*0c7d97c5SJed Brown for(j=0;j<n_R;j++) { array[idx_R_local[j]] = array2[j]; } 1150*0c7d97c5SJed Brown array[ pcbddc->vertices[i] ] = one; 1151*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 1152*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1153*0c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers (i.e. primal nodes) */ 1154*0c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_P,zero); 1155*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 1156*0c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1157*0c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) { array2[j]=array[j]; } 1158*0c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 1159*0c7d97c5SJed Brown if(pcbddc->n_constraints) { 1160*0c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1161*0c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) { array2[j+pcbddc->n_vertices]=array[j]; } 1162*0c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 1163*0c7d97c5SJed Brown } 1164*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 1165*0c7d97c5SJed Brown ierr = VecScale(pcbddc->vec1_P,m_one);CHKERRQ(ierr); 1166*0c7d97c5SJed Brown /* check saddle point solution */ 1167*0c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N); CHKERRQ(ierr); 1168*0c7d97c5SJed Brown ierr = MatMultTransposeAdd(CMAT,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N); 1169*0c7d97c5SJed Brown ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index[0]]); CHKERRQ(ierr); 1170*0c7d97c5SJed Brown ierr = MatMult(CMAT,pcis->vec1_N,pcbddc->vec1_P); CHKERRQ(ierr); 1171*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 1172*0c7d97c5SJed Brown array[index[0]]=array[index[0]]+m_one; /* shift by the identity matrix */ 1173*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 1174*0c7d97c5SJed Brown ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index[0]]); CHKERRQ(ierr); 1175*0c7d97c5SJed Brown } 1176*0c7d97c5SJed Brown } 1177*0c7d97c5SJed Brown 1178*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_constraints;i++){ 1179*0c7d97c5SJed Brown ierr = VecSet(vec2_C,zero); 1180*0c7d97c5SJed Brown ierr = VecSetValue(vec2_C,i,m_one,INSERT_VALUES);CHKERRQ(ierr); 1181*0c7d97c5SJed Brown ierr = VecAssemblyBegin(vec2_C);CHKERRQ(ierr); 1182*0c7d97c5SJed Brown ierr = VecAssemblyEnd(vec2_C);CHKERRQ(ierr); 1183*0c7d97c5SJed Brown /* solution of saddle point problem */ 1184*0c7d97c5SJed Brown ierr = MatMult(M1,vec2_C,vec1_C);CHKERRQ(ierr); 1185*0c7d97c5SJed Brown ierr = MatMult(pcbddc->local_auxmat2,vec1_C,pcbddc->vec1_R);CHKERRQ(ierr); 1186*0c7d97c5SJed Brown ierr = VecScale(vec1_C,m_one);CHKERRQ(ierr); 1187*0c7d97c5SJed Brown if(pcbddc->n_vertices) { ierr = MatMult(A_VR,pcbddc->vec1_R,vec2_V);CHKERRQ(ierr); } 1188*0c7d97c5SJed Brown /* Set values in coarse basis function and subdomain part of coarse_mat */ 1189*0c7d97c5SJed Brown /* coarse basis functions */ 1190*0c7d97c5SJed Brown index[0]=i+pcbddc->n_vertices; 1191*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_B,zero);CHKERRQ(ierr); 1192*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1193*0c7d97c5SJed Brown ierr = VecScatterEnd (pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1194*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1195*0c7d97c5SJed Brown ierr = MatSetValues(pcbddc->coarse_phi_B,n_B,auxindices,1,index,array,INSERT_VALUES);CHKERRQ(ierr); 1196*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_B,&array);CHKERRQ(ierr); 1197*0c7d97c5SJed Brown if( pcbddc->prec_type || check_flag ) { 1198*0c7d97c5SJed Brown ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1199*0c7d97c5SJed Brown ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1200*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_D,&array);CHKERRQ(ierr); 1201*0c7d97c5SJed Brown ierr = MatSetValues(pcbddc->coarse_phi_D,n_D,auxindices,1,index,array,INSERT_VALUES);CHKERRQ(ierr); 1202*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_D,&array);CHKERRQ(ierr); 1203*0c7d97c5SJed Brown } 1204*0c7d97c5SJed Brown /* subdomain contribution to coarse matrix */ 1205*0c7d97c5SJed Brown if(pcbddc->n_vertices) { 1206*0c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1207*0c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) {coarse_submat_vals[index[0]*pcbddc->local_primal_size+j]=array[j];} //WARNING -> column major ordering 1208*0c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 1209*0c7d97c5SJed Brown } 1210*0c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1211*0c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) {coarse_submat_vals[index[0]*pcbddc->local_primal_size+j+pcbddc->n_vertices]=array[j];} //WARNING -> column major ordering 1212*0c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 1213*0c7d97c5SJed Brown 1214*0c7d97c5SJed Brown if( check_flag ) { 1215*0c7d97c5SJed Brown /* assemble subdomain vector on nodes */ 1216*0c7d97c5SJed Brown ierr = VecSet(pcis->vec1_N,zero); 1217*0c7d97c5SJed Brown ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1218*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 1219*0c7d97c5SJed Brown for(j=0;j<n_R;j++){ array[ idx_R_local[j] ] = array2[j]; } 1220*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_R,&array2);CHKERRQ(ierr); 1221*0c7d97c5SJed Brown ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 1222*0c7d97c5SJed Brown /* assemble subdomain vector of lagrange multipliers */ 1223*0c7d97c5SJed Brown ierr = VecSet(pcbddc->vec1_P,zero); 1224*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 1225*0c7d97c5SJed Brown if( pcbddc->n_vertices) { 1226*0c7d97c5SJed Brown ierr = VecGetArray(vec2_V,&array);CHKERRQ(ierr); 1227*0c7d97c5SJed Brown for(j=0;j<pcbddc->n_vertices;j++) {array2[j]=-array[j];} 1228*0c7d97c5SJed Brown ierr = VecRestoreArray(vec2_V,&array);CHKERRQ(ierr); 1229*0c7d97c5SJed Brown } 1230*0c7d97c5SJed Brown ierr = VecGetArray(vec1_C,&array);CHKERRQ(ierr); 1231*0c7d97c5SJed Brown for(j=0;j<pcbddc->n_constraints;j++) {array2[j+pcbddc->n_vertices]=-array[j];} 1232*0c7d97c5SJed Brown ierr = VecRestoreArray(vec1_C,&array);CHKERRQ(ierr); 1233*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 1234*0c7d97c5SJed Brown /* check saddle point solution */ 1235*0c7d97c5SJed Brown ierr = MatMult(matis->A,pcis->vec1_N,pcis->vec2_N); CHKERRQ(ierr); 1236*0c7d97c5SJed Brown ierr = MatMultTransposeAdd(CMAT,pcbddc->vec1_P,pcis->vec2_N,pcis->vec2_N); 1237*0c7d97c5SJed Brown ierr = VecNorm(pcis->vec2_N,NORM_INFINITY,&coarsefunctions_errors[index[0]]); CHKERRQ(ierr); 1238*0c7d97c5SJed Brown ierr = MatMult(CMAT,pcis->vec1_N,pcbddc->vec1_P); CHKERRQ(ierr); 1239*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 1240*0c7d97c5SJed Brown array[index[0]]=array[index[0]]+m_one; /* shift by the identity matrix */ 1241*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 1242*0c7d97c5SJed Brown ierr = VecNorm(pcbddc->vec1_P,NORM_INFINITY,&constraints_errors[index[0]]); CHKERRQ(ierr); 1243*0c7d97c5SJed Brown } 1244*0c7d97c5SJed Brown } 1245*0c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1246*0c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1247*0c7d97c5SJed Brown if( pcbddc->prec_type || check_flag ) { 1248*0c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1249*0c7d97c5SJed Brown ierr = MatAssemblyEnd (pcbddc->coarse_phi_D,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1250*0c7d97c5SJed Brown } 1251*0c7d97c5SJed Brown /* Checking coarse_sub_mat and coarse basis functios */ 1252*0c7d97c5SJed Brown /* It shuld be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 1253*0c7d97c5SJed Brown if(check_flag) { 1254*0c7d97c5SJed Brown 1255*0c7d97c5SJed Brown Mat coarse_sub_mat; 1256*0c7d97c5SJed Brown Mat TM1,TM2,TM3,TM4; 1257*0c7d97c5SJed Brown Mat coarse_phi_D,coarse_phi_B,A_II,A_BB,A_IB,A_BI; 1258*0c7d97c5SJed Brown const MatType checkmattype; 1259*0c7d97c5SJed Brown PetscScalar value; 1260*0c7d97c5SJed Brown PetscInt bs; 1261*0c7d97c5SJed Brown 1262*0c7d97c5SJed Brown ierr = MatGetType(matis->A,&checkmattype);CHKERRQ(ierr); 1263*0c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 1264*0c7d97c5SJed Brown //printf("Mat type local ismat: %s\n",checkmattype); 1265*0c7d97c5SJed Brown //printf("Mat bs local ismat: %d\n",bs); 1266*0c7d97c5SJed Brown ierr = MatGetType(pcis->A_II,&checkmattype);CHKERRQ(ierr); 1267*0c7d97c5SJed Brown ierr = MatGetBlockSize(pcis->A_II,&bs);CHKERRQ(ierr); 1268*0c7d97c5SJed Brown //printf("Mat type local is D : %s\n",checkmattype); 1269*0c7d97c5SJed Brown //printf("Mat bs local is D : %d\n",bs); 1270*0c7d97c5SJed Brown checkmattype = MATSEQAIJ; 1271*0c7d97c5SJed Brown MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II); 1272*0c7d97c5SJed Brown MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB); 1273*0c7d97c5SJed Brown MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI); 1274*0c7d97c5SJed Brown MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB); 1275*0c7d97c5SJed Brown MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D); 1276*0c7d97c5SJed Brown MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B); 1277*0c7d97c5SJed Brown MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 1278*0c7d97c5SJed Brown MatConvert(coarse_sub_mat,checkmattype,MAT_REUSE_MATRIX,&coarse_sub_mat); 1279*0c7d97c5SJed Brown 1280*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 1281*0c7d97c5SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"Check coarse sub mat and local basis functions\n");CHKERRQ(ierr); 1282*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1283*0c7d97c5SJed Brown ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1); 1284*0c7d97c5SJed Brown ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2); 1285*0c7d97c5SJed Brown ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT); 1286*0c7d97c5SJed Brown ierr = MatMatTransposeMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3); 1287*0c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT); 1288*0c7d97c5SJed Brown ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT); 1289*0c7d97c5SJed Brown ierr = MatMatTransposeMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4); 1290*0c7d97c5SJed Brown ierr = MatDestroy(&AUXMAT); 1291*0c7d97c5SJed Brown ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN); 1292*0c7d97c5SJed Brown ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN); 1293*0c7d97c5SJed Brown ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN); 1294*0c7d97c5SJed Brown ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN); 1295*0c7d97c5SJed Brown ierr = MatNorm(TM1,NORM_INFINITY,&value); 1296*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"----------------------------------\n");CHKERRQ(ierr); 1297*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d \n",PetscGlobalRank);CHKERRQ(ierr); 1298*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"matrix error = % 1.14e\n",value);CHKERRQ(ierr); 1299*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"coarse functions errors\n");CHKERRQ(ierr); 1300*0c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) { 1301*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,coarsefunctions_errors[i]);CHKERRQ(ierr); 1302*0c7d97c5SJed Brown } 1303*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"constraints errors\n");CHKERRQ(ierr); 1304*0c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_size;i++) { 1305*0c7d97c5SJed Brown ierr = PetscViewerASCIISynchronizedPrintf(viewer,"local %02d-th function error = % 1.14e\n",i,constraints_errors[i]);CHKERRQ(ierr); 1306*0c7d97c5SJed Brown } 1307*0c7d97c5SJed Brown ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 1308*0c7d97c5SJed Brown ierr = MatDestroy(&A_II); 1309*0c7d97c5SJed Brown ierr = MatDestroy(&A_BB); 1310*0c7d97c5SJed Brown ierr = MatDestroy(&A_IB); 1311*0c7d97c5SJed Brown ierr = MatDestroy(&A_BI); 1312*0c7d97c5SJed Brown ierr = MatDestroy(&TM1); 1313*0c7d97c5SJed Brown ierr = MatDestroy(&TM2); 1314*0c7d97c5SJed Brown ierr = MatDestroy(&TM3); 1315*0c7d97c5SJed Brown ierr = MatDestroy(&TM4); 1316*0c7d97c5SJed Brown ierr = MatDestroy(&coarse_phi_D); 1317*0c7d97c5SJed Brown ierr = MatDestroy(&coarse_sub_mat); 1318*0c7d97c5SJed Brown ierr = MatDestroy(&coarse_phi_B); 1319*0c7d97c5SJed Brown ierr = PetscFree(coarsefunctions_errors);CHKERRQ(ierr); 1320*0c7d97c5SJed Brown ierr = PetscFree(constraints_errors);CHKERRQ(ierr); 1321*0c7d97c5SJed Brown } 1322*0c7d97c5SJed Brown 1323*0c7d97c5SJed Brown /* create coarse matrix and data structures for message passing associated actual choice of coarse problem type */ 1324*0c7d97c5SJed Brown ierr = PCBDDCSetupCoarseEnvironment(pc,coarse_submat_vals);CHKERRQ(ierr); 1325*0c7d97c5SJed Brown /* free memory */ 1326*0c7d97c5SJed Brown ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 1327*0c7d97c5SJed Brown ierr = PetscFree(auxindices);CHKERRQ(ierr); 1328*0c7d97c5SJed Brown ierr = PetscFree(nnz);CHKERRQ(ierr); 1329*0c7d97c5SJed Brown if(pcbddc->n_vertices) { 1330*0c7d97c5SJed Brown ierr = VecDestroy(&vec1_V);CHKERRQ(ierr); 1331*0c7d97c5SJed Brown ierr = VecDestroy(&vec2_V);CHKERRQ(ierr); 1332*0c7d97c5SJed Brown ierr = MatDestroy(&M2);CHKERRQ(ierr); 1333*0c7d97c5SJed Brown ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 1334*0c7d97c5SJed Brown ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 1335*0c7d97c5SJed Brown ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 1336*0c7d97c5SJed Brown } 1337*0c7d97c5SJed Brown if(pcbddc->n_constraints) { 1338*0c7d97c5SJed Brown ierr = VecDestroy(&vec1_C);CHKERRQ(ierr); 1339*0c7d97c5SJed Brown ierr = VecDestroy(&vec2_C);CHKERRQ(ierr); 1340*0c7d97c5SJed Brown ierr = MatDestroy(&M1);CHKERRQ(ierr); 1341*0c7d97c5SJed Brown ierr = MatDestroy(&C_CR); CHKERRQ(ierr); 1342*0c7d97c5SJed Brown } 1343*0c7d97c5SJed Brown ierr = MatDestroy(&CMAT); CHKERRQ(ierr); 1344*0c7d97c5SJed Brown } 1345*0c7d97c5SJed Brown /* free memory */ 1346*0c7d97c5SJed Brown if(pcbddc->n_vertices) { 1347*0c7d97c5SJed Brown ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 1348*0c7d97c5SJed Brown ierr = ISDestroy(&is_V_local);CHKERRQ(ierr); 1349*0c7d97c5SJed Brown } 1350*0c7d97c5SJed Brown ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 1351*0c7d97c5SJed Brown ierr = ISDestroy(&is_R_local);CHKERRQ(ierr); 1352*0c7d97c5SJed Brown //ierr = VecDestroy(&pcis->vec2_N);CHKERRQ(ierr); 1353*0c7d97c5SJed Brown //pcis->vec2_N = 0; 1354*0c7d97c5SJed Brown 1355*0c7d97c5SJed Brown PetscFunctionReturn(0); 1356*0c7d97c5SJed Brown 1357*0c7d97c5SJed Brown } 1358*0c7d97c5SJed Brown 1359*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 1360*0c7d97c5SJed Brown 1361*0c7d97c5SJed Brown #undef __FUNCT__ 1362*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCSetupCoarseEnvironment" 1363*0c7d97c5SJed Brown PetscErrorCode PCBDDCSetupCoarseEnvironment(PC pc,PetscScalar* coarse_submat_vals) 1364*0c7d97c5SJed Brown { 1365*0c7d97c5SJed Brown 1366*0c7d97c5SJed Brown 1367*0c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1368*0c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1369*0c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 1370*0c7d97c5SJed Brown MPI_Comm prec_comm = ((PetscObject)pc)->comm; 1371*0c7d97c5SJed Brown MPI_Comm coarse_comm; 1372*0c7d97c5SJed Brown 1373*0c7d97c5SJed Brown /* common to all choiches */ 1374*0c7d97c5SJed Brown PetscScalar *temp_coarse_mat_vals; 1375*0c7d97c5SJed Brown PetscScalar *ins_coarse_mat_vals; 1376*0c7d97c5SJed Brown PetscInt *ins_local_primal_indices; 1377*0c7d97c5SJed Brown PetscMPIInt *localsizes2,*localdispl2; 1378*0c7d97c5SJed Brown PetscMPIInt size_prec_comm; 1379*0c7d97c5SJed Brown PetscMPIInt rank_prec_comm; 1380*0c7d97c5SJed Brown PetscMPIInt active_rank=MPI_PROC_NULL; 1381*0c7d97c5SJed Brown PetscMPIInt master_proc=0; 1382*0c7d97c5SJed Brown PetscInt ins_local_primal_size; 1383*0c7d97c5SJed Brown /* specific to MULTILEVEL_BDDC */ 1384*0c7d97c5SJed Brown PetscMPIInt *ranks_recv; 1385*0c7d97c5SJed Brown PetscMPIInt count_recv=0; 1386*0c7d97c5SJed Brown PetscMPIInt rank_coarse_proc_send_to; 1387*0c7d97c5SJed Brown PetscMPIInt coarse_color = MPI_UNDEFINED; 1388*0c7d97c5SJed Brown ISLocalToGlobalMapping coarse_ISLG; 1389*0c7d97c5SJed Brown /* some other variables */ 1390*0c7d97c5SJed Brown PetscErrorCode ierr; 1391*0c7d97c5SJed Brown const MatType coarse_mat_type; 1392*0c7d97c5SJed Brown const PCType coarse_pc_type; 1393*0c7d97c5SJed Brown PetscInt i,j,k,bs; 1394*0c7d97c5SJed Brown 1395*0c7d97c5SJed Brown PetscFunctionBegin; 1396*0c7d97c5SJed Brown 1397*0c7d97c5SJed Brown ins_local_primal_indices = 0; 1398*0c7d97c5SJed Brown ins_coarse_mat_vals = 0; 1399*0c7d97c5SJed Brown localsizes2 = 0; 1400*0c7d97c5SJed Brown localdispl2 = 0; 1401*0c7d97c5SJed Brown temp_coarse_mat_vals = 0; 1402*0c7d97c5SJed Brown coarse_ISLG = 0; 1403*0c7d97c5SJed Brown 1404*0c7d97c5SJed Brown MPI_Comm_size(prec_comm,&size_prec_comm); 1405*0c7d97c5SJed Brown MPI_Comm_rank(prec_comm,&rank_prec_comm); 1406*0c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 1407*0c7d97c5SJed Brown 1408*0c7d97c5SJed Brown /* adapt coarse problem type */ 1409*0c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC && pcbddc->active_procs < MIN_PROCS_FOR_BDDC ) 1410*0c7d97c5SJed Brown pcbddc->coarse_problem_type = PARALLEL_BDDC; 1411*0c7d97c5SJed Brown 1412*0c7d97c5SJed Brown switch(pcbddc->coarse_problem_type){ 1413*0c7d97c5SJed Brown 1414*0c7d97c5SJed Brown case(MULTILEVEL_BDDC): //we define a coarse mesh where subdomains are elements 1415*0c7d97c5SJed Brown { 1416*0c7d97c5SJed Brown /* we need additional variables */ 1417*0c7d97c5SJed Brown MetisInt n_subdomains,n_parts,objval,ncon,faces_nvtxs; 1418*0c7d97c5SJed Brown MetisInt *metis_coarse_subdivision; 1419*0c7d97c5SJed Brown MetisInt options[METIS_NOPTIONS]; 1420*0c7d97c5SJed Brown PetscMPIInt size_coarse_comm,rank_coarse_comm; 1421*0c7d97c5SJed Brown PetscMPIInt procs_jumps_coarse_comm; 1422*0c7d97c5SJed Brown PetscMPIInt *coarse_subdivision; 1423*0c7d97c5SJed Brown PetscMPIInt *total_count_recv; 1424*0c7d97c5SJed Brown PetscMPIInt *total_ranks_recv; 1425*0c7d97c5SJed Brown PetscMPIInt *displacements_recv; 1426*0c7d97c5SJed Brown PetscMPIInt *my_faces_connectivity; 1427*0c7d97c5SJed Brown PetscMPIInt *petsc_faces_adjncy; 1428*0c7d97c5SJed Brown MetisInt *faces_adjncy; 1429*0c7d97c5SJed Brown MetisInt *faces_xadj; 1430*0c7d97c5SJed Brown PetscMPIInt *number_of_faces; 1431*0c7d97c5SJed Brown PetscMPIInt *faces_displacements; 1432*0c7d97c5SJed Brown PetscInt *array_int; 1433*0c7d97c5SJed Brown PetscMPIInt my_faces=0; 1434*0c7d97c5SJed Brown PetscMPIInt total_faces=0; 1435*0c7d97c5SJed Brown 1436*0c7d97c5SJed Brown /* this code has a bug (see below) for more then three levels -> I can solve it quickly */ 1437*0c7d97c5SJed Brown 1438*0c7d97c5SJed Brown /* define some quantities */ 1439*0c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 1440*0c7d97c5SJed Brown coarse_mat_type = MATIS; 1441*0c7d97c5SJed Brown coarse_pc_type = PCBDDC; 1442*0c7d97c5SJed Brown 1443*0c7d97c5SJed Brown /* details of coarse decomposition */ 1444*0c7d97c5SJed Brown n_subdomains = pcbddc->active_procs; 1445*0c7d97c5SJed Brown n_parts = n_subdomains/pcbddc->coarsening_ratio; 1446*0c7d97c5SJed Brown procs_jumps_coarse_comm = pcbddc->coarsening_ratio*(size_prec_comm/pcbddc->active_procs); 1447*0c7d97c5SJed Brown 1448*0c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 1449*0c7d97c5SJed Brown 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); 1450*0c7d97c5SJed Brown 1451*0c7d97c5SJed Brown /* build CSR graph of subdomains' connectivity through faces */ 1452*0c7d97c5SJed Brown ierr = PetscMalloc (pcis->n*sizeof(PetscInt),&array_int);CHKERRQ(ierr); 1453*0c7d97c5SJed Brown PetscMemzero(array_int,pcis->n*sizeof(PetscInt)); 1454*0c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){/* i=1 so I don't count myself -> faces nodes counts to 1 */ 1455*0c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 1456*0c7d97c5SJed Brown array_int[ pcis->shared[i][j] ]+=1; 1457*0c7d97c5SJed Brown } 1458*0c7d97c5SJed Brown } 1459*0c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 1460*0c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 1461*0c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 1462*0c7d97c5SJed Brown my_faces++; 1463*0c7d97c5SJed Brown break; 1464*0c7d97c5SJed Brown } 1465*0c7d97c5SJed Brown } 1466*0c7d97c5SJed Brown } 1467*0c7d97c5SJed Brown //printf("I found %d faces.\n",my_faces); 1468*0c7d97c5SJed Brown 1469*0c7d97c5SJed Brown MPI_Reduce(&my_faces,&total_faces,1,MPIU_INT,MPI_SUM,master_proc,prec_comm); 1470*0c7d97c5SJed Brown ierr = PetscMalloc (my_faces*sizeof(PetscInt),&my_faces_connectivity);CHKERRQ(ierr); 1471*0c7d97c5SJed Brown my_faces=0; 1472*0c7d97c5SJed Brown for(i=1;i<pcis->n_neigh;i++){ 1473*0c7d97c5SJed Brown for(j=0;j<pcis->n_shared[i];j++){ 1474*0c7d97c5SJed Brown if(array_int[ pcis->shared[i][j] ] == 1 ){ 1475*0c7d97c5SJed Brown my_faces_connectivity[my_faces]=pcis->neigh[i]; 1476*0c7d97c5SJed Brown my_faces++; 1477*0c7d97c5SJed Brown break; 1478*0c7d97c5SJed Brown } 1479*0c7d97c5SJed Brown } 1480*0c7d97c5SJed Brown } 1481*0c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 1482*0c7d97c5SJed Brown //printf("I found %d total faces.\n",total_faces); 1483*0c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(PetscMPIInt),&petsc_faces_adjncy);CHKERRQ(ierr); 1484*0c7d97c5SJed Brown ierr = PetscMalloc (size_prec_comm*sizeof(PetscMPIInt),&number_of_faces);CHKERRQ(ierr); 1485*0c7d97c5SJed Brown ierr = PetscMalloc (total_faces*sizeof(MetisInt),&faces_adjncy);CHKERRQ(ierr); 1486*0c7d97c5SJed Brown ierr = PetscMalloc ((n_subdomains+1)*sizeof(MetisInt),&faces_xadj);CHKERRQ(ierr); 1487*0c7d97c5SJed Brown ierr = PetscMalloc ((size_prec_comm+1)*sizeof(PetscMPIInt),&faces_displacements);CHKERRQ(ierr); 1488*0c7d97c5SJed Brown } 1489*0c7d97c5SJed Brown MPI_Gather(&my_faces,1,MPIU_INT,&number_of_faces[0],1,MPIU_INT,master_proc,prec_comm); 1490*0c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 1491*0c7d97c5SJed Brown faces_xadj[0]=0; 1492*0c7d97c5SJed Brown faces_displacements[0]=0; 1493*0c7d97c5SJed Brown j=0; 1494*0c7d97c5SJed Brown for(i=1;i<size_prec_comm+1;i++) { 1495*0c7d97c5SJed Brown faces_displacements[i]=faces_displacements[i-1]+number_of_faces[i-1]; 1496*0c7d97c5SJed Brown if(number_of_faces[i-1]) { 1497*0c7d97c5SJed Brown j++; 1498*0c7d97c5SJed Brown faces_xadj[j]=faces_xadj[j-1]+number_of_faces[i-1]; 1499*0c7d97c5SJed Brown } 1500*0c7d97c5SJed Brown } 1501*0c7d97c5SJed Brown printf("The J I count is %d and should be %d\n",j,n_subdomains); 1502*0c7d97c5SJed Brown printf("Total faces seem %d and should be %d\n",faces_xadj[j],total_faces); 1503*0c7d97c5SJed Brown } 1504*0c7d97c5SJed Brown 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); 1505*0c7d97c5SJed Brown ierr = PetscFree(my_faces_connectivity);CHKERRQ(ierr); 1506*0c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 1507*0c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 1508*0c7d97c5SJed Brown for(i=0;i<total_faces;i++) faces_adjncy[i]=(MetisInt)(petsc_faces_adjncy[i]); ///procs_jumps_coarse_comm); // cast to MetisInt 1509*0c7d97c5SJed Brown printf("This is the face connectivity (%d)\n",procs_jumps_coarse_comm); 1510*0c7d97c5SJed Brown for(i=0;i<n_subdomains;i++){ 1511*0c7d97c5SJed Brown printf("proc %d is connected with \n",i); 1512*0c7d97c5SJed Brown for(j=faces_xadj[i];j<faces_xadj[i+1];j++) 1513*0c7d97c5SJed Brown printf("%d ",faces_adjncy[j]); 1514*0c7d97c5SJed Brown printf("\n"); 1515*0c7d97c5SJed Brown } 1516*0c7d97c5SJed Brown ierr = PetscFree(faces_displacements);CHKERRQ(ierr); 1517*0c7d97c5SJed Brown ierr = PetscFree(number_of_faces);CHKERRQ(ierr); 1518*0c7d97c5SJed Brown ierr = PetscFree(petsc_faces_adjncy);CHKERRQ(ierr); 1519*0c7d97c5SJed Brown } 1520*0c7d97c5SJed Brown 1521*0c7d97c5SJed Brown if( rank_prec_comm == master_proc ) { 1522*0c7d97c5SJed Brown 1523*0c7d97c5SJed Brown ncon=1; 1524*0c7d97c5SJed Brown faces_nvtxs=n_subdomains; 1525*0c7d97c5SJed Brown /* partition graoh induced by face connectivity */ 1526*0c7d97c5SJed Brown ierr = PetscMalloc (n_subdomains*sizeof(MetisInt),&metis_coarse_subdivision);CHKERRQ(ierr); 1527*0c7d97c5SJed Brown ierr = METIS_SetDefaultOptions(options); 1528*0c7d97c5SJed Brown /* we need a contiguous partition of the coarse mesh */ 1529*0c7d97c5SJed Brown options[METIS_OPTION_CONTIG]=1; 1530*0c7d97c5SJed Brown options[METIS_OPTION_DBGLVL]=1; 1531*0c7d97c5SJed Brown options[METIS_OPTION_OBJTYPE]=METIS_OBJTYPE_CUT; 1532*0c7d97c5SJed Brown options[METIS_OPTION_IPTYPE]=METIS_IPTYPE_EDGE; 1533*0c7d97c5SJed Brown options[METIS_OPTION_NITER]=30; 1534*0c7d97c5SJed Brown //options[METIS_OPTION_NCUTS]=1; 1535*0c7d97c5SJed Brown //printf("METIS PART GRAPH\n"); 1536*0c7d97c5SJed Brown /* BUG: faces_xadj and faces_adjncy content must be adapted using the coarsening factor*/ 1537*0c7d97c5SJed Brown ierr = METIS_PartGraphKway(&faces_nvtxs,&ncon,faces_xadj,faces_adjncy,NULL,NULL,NULL,&n_parts,NULL,NULL,options,&objval,metis_coarse_subdivision); 1538*0c7d97c5SJed Brown //printf("OKOKOKOKOKOKOKOK\n"); 1539*0c7d97c5SJed 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); 1540*0c7d97c5SJed Brown ierr = PetscFree(faces_xadj);CHKERRQ(ierr); 1541*0c7d97c5SJed Brown ierr = PetscFree(faces_adjncy);CHKERRQ(ierr); 1542*0c7d97c5SJed Brown coarse_subdivision = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); /* calloc for contiguous memory since we need to scatter these values later */ 1543*0c7d97c5SJed Brown /* copy/cast values avoiding possible type conflicts between PETSc, MPI and METIS */ 1544*0c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) coarse_subdivision[i]=MPI_PROC_NULL;; 1545*0c7d97c5SJed Brown k=size_prec_comm/pcbddc->active_procs; 1546*0c7d97c5SJed Brown for(i=0;i<n_subdomains;i++) coarse_subdivision[k*i]=(PetscInt)(metis_coarse_subdivision[i]); 1547*0c7d97c5SJed Brown ierr = PetscFree(metis_coarse_subdivision);CHKERRQ(ierr); 1548*0c7d97c5SJed Brown 1549*0c7d97c5SJed Brown } 1550*0c7d97c5SJed Brown 1551*0c7d97c5SJed Brown /* Create new communicator for coarse problem splitting the old one */ 1552*0c7d97c5SJed Brown if( !(rank_prec_comm%procs_jumps_coarse_comm) && rank_prec_comm < procs_jumps_coarse_comm*n_parts ){ 1553*0c7d97c5SJed Brown coarse_color=0; //for communicator splitting 1554*0c7d97c5SJed Brown active_rank=rank_prec_comm; //for insertion of matrix values 1555*0c7d97c5SJed Brown } 1556*0c7d97c5SJed Brown // procs with coarse_color = MPI_UNDEFINED will have coarse_comm = MPI_COMM_NULL (from mpi standards) 1557*0c7d97c5SJed Brown // key = rank_prec_comm -> keep same ordering of ranks from the old to the new communicator 1558*0c7d97c5SJed Brown MPI_Comm_split(prec_comm,coarse_color,rank_prec_comm,&coarse_comm); 1559*0c7d97c5SJed Brown 1560*0c7d97c5SJed Brown if( coarse_color == 0 ) { 1561*0c7d97c5SJed Brown MPI_Comm_size(coarse_comm,&size_coarse_comm); 1562*0c7d97c5SJed Brown MPI_Comm_rank(coarse_comm,&rank_coarse_comm); 1563*0c7d97c5SJed Brown //printf("Details of coarse comm\n"); 1564*0c7d97c5SJed Brown //printf("size = %d, myrank = %d\n",size_coarse_comm,rank_coarse_comm); 1565*0c7d97c5SJed Brown //printf("jumps = %d, coarse_color = %d, n_parts = %d\n",procs_jumps_coarse_comm,coarse_color,n_parts); 1566*0c7d97c5SJed Brown } else { 1567*0c7d97c5SJed Brown rank_coarse_comm = MPI_PROC_NULL; 1568*0c7d97c5SJed Brown } 1569*0c7d97c5SJed Brown 1570*0c7d97c5SJed Brown /* master proc take care of arranging and distributing coarse informations */ 1571*0c7d97c5SJed Brown if(rank_coarse_comm == master_proc) { 1572*0c7d97c5SJed Brown ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&displacements_recv);CHKERRQ(ierr); 1573*0c7d97c5SJed Brown //ierr = PetscMalloc (size_coarse_comm*sizeof(PetscMPIInt),&total_count_recv);CHKERRQ(ierr); 1574*0c7d97c5SJed Brown //ierr = PetscMalloc (n_subdomains*sizeof(PetscMPIInt),&total_ranks_recv);CHKERRQ(ierr); 1575*0c7d97c5SJed Brown total_count_recv = (PetscMPIInt*)calloc(size_prec_comm,sizeof(PetscMPIInt)); 1576*0c7d97c5SJed Brown total_ranks_recv = (PetscMPIInt*)calloc(n_subdomains,sizeof(PetscMPIInt)); 1577*0c7d97c5SJed Brown /* some initializations */ 1578*0c7d97c5SJed Brown displacements_recv[0]=0; 1579*0c7d97c5SJed Brown //PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt)); not needed -> calloc initializes to zero 1580*0c7d97c5SJed Brown /* count from how many processes the j-th process of the coarse decomposition will receive data */ 1581*0c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) 1582*0c7d97c5SJed Brown for(i=0;i<n_subdomains;i++) 1583*0c7d97c5SJed Brown if(coarse_subdivision[i]==j) 1584*0c7d97c5SJed Brown total_count_recv[j]++; 1585*0c7d97c5SJed Brown /* displacements needed for scatterv of total_ranks_recv */ 1586*0c7d97c5SJed Brown for(i=1;i<size_coarse_comm;i++) displacements_recv[i]=displacements_recv[i-1]+total_count_recv[i-1]; 1587*0c7d97c5SJed Brown /* Now fill properly total_ranks_recv -> each coarse process will receive the ranks (in prec_comm communicator) of its friend (sending) processes */ 1588*0c7d97c5SJed Brown ierr = PetscMemzero(total_count_recv,size_coarse_comm*sizeof(PetscMPIInt));CHKERRQ(ierr); 1589*0c7d97c5SJed Brown for(j=0;j<size_coarse_comm;j++) { 1590*0c7d97c5SJed Brown for(i=0;i<n_subdomains;i++) { 1591*0c7d97c5SJed Brown if(coarse_subdivision[i]==j) { 1592*0c7d97c5SJed Brown total_ranks_recv[displacements_recv[j]+total_count_recv[j]]=i; 1593*0c7d97c5SJed Brown total_count_recv[j]=total_count_recv[j]+1; 1594*0c7d97c5SJed Brown } 1595*0c7d97c5SJed Brown } 1596*0c7d97c5SJed Brown } 1597*0c7d97c5SJed Brown //for(j=0;j<size_coarse_comm;j++) { 1598*0c7d97c5SJed Brown // printf("process %d in new rank will receive from %d processes (ranks follows)\n",j,total_count_recv[j]); 1599*0c7d97c5SJed Brown // for(i=0;i<total_count_recv[j];i++) { 1600*0c7d97c5SJed Brown // printf("%d ",total_ranks_recv[displacements_recv[j]+i]); 1601*0c7d97c5SJed Brown // } 1602*0c7d97c5SJed Brown // printf("\n"); 1603*0c7d97c5SJed Brown // } 1604*0c7d97c5SJed Brown 1605*0c7d97c5SJed Brown /* identify new decomposition in terms of ranks in the old communicator */ 1606*0c7d97c5SJed Brown k=size_prec_comm/pcbddc->active_procs; 1607*0c7d97c5SJed Brown for(i=0;i<n_subdomains;i++) coarse_subdivision[k*i]=coarse_subdivision[k*i]*procs_jumps_coarse_comm; 1608*0c7d97c5SJed Brown printf("coarse_subdivision in old end new ranks\n"); 1609*0c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) 1610*0c7d97c5SJed Brown printf("(%d %d) ",coarse_subdivision[i],coarse_subdivision[i]/procs_jumps_coarse_comm); 1611*0c7d97c5SJed Brown printf("\n"); 1612*0c7d97c5SJed Brown } 1613*0c7d97c5SJed Brown 1614*0c7d97c5SJed Brown /* Scatter new decomposition for send details */ 1615*0c7d97c5SJed Brown MPI_Scatter(&coarse_subdivision[0],1,MPIU_INT,&rank_coarse_proc_send_to,1,MPIU_INT,master_proc,prec_comm); 1616*0c7d97c5SJed Brown /* Scatter receiving details to members of coarse decomposition */ 1617*0c7d97c5SJed Brown if( coarse_color == 0) { 1618*0c7d97c5SJed Brown MPI_Scatter(&total_count_recv[0],1,MPIU_INT,&count_recv,1,MPIU_INT,master_proc,coarse_comm); 1619*0c7d97c5SJed Brown ierr = PetscMalloc (count_recv*sizeof(PetscMPIInt),&ranks_recv);CHKERRQ(ierr); 1620*0c7d97c5SJed Brown MPI_Scatterv(&total_ranks_recv[0],total_count_recv,displacements_recv,MPIU_INT,&ranks_recv[0],count_recv,MPIU_INT,master_proc,coarse_comm); 1621*0c7d97c5SJed Brown } 1622*0c7d97c5SJed Brown 1623*0c7d97c5SJed Brown //printf("I will send my matrix data to proc %d\n",rank_coarse_proc_send_to); 1624*0c7d97c5SJed Brown //if(coarse_color == 0) { 1625*0c7d97c5SJed Brown // printf("I will receive some matrix data from %d processes (ranks follows)\n",count_recv); 1626*0c7d97c5SJed Brown // for(i=0;i<count_recv;i++) 1627*0c7d97c5SJed Brown // printf("%d ",ranks_recv[i]); 1628*0c7d97c5SJed Brown // printf("\n"); 1629*0c7d97c5SJed Brown //} 1630*0c7d97c5SJed Brown 1631*0c7d97c5SJed Brown if(rank_prec_comm == master_proc) { 1632*0c7d97c5SJed Brown //ierr = PetscFree(coarse_subdivision);CHKERRQ(ierr); 1633*0c7d97c5SJed Brown //ierr = PetscFree(total_count_recv);CHKERRQ(ierr); 1634*0c7d97c5SJed Brown //ierr = PetscFree(total_ranks_recv);CHKERRQ(ierr); 1635*0c7d97c5SJed Brown free(coarse_subdivision); 1636*0c7d97c5SJed Brown free(total_count_recv); 1637*0c7d97c5SJed Brown free(total_ranks_recv); 1638*0c7d97c5SJed Brown ierr = PetscFree(displacements_recv);CHKERRQ(ierr); 1639*0c7d97c5SJed Brown } 1640*0c7d97c5SJed Brown break; 1641*0c7d97c5SJed Brown } 1642*0c7d97c5SJed Brown 1643*0c7d97c5SJed Brown case(REPLICATED_BDDC): 1644*0c7d97c5SJed Brown 1645*0c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 1646*0c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 1647*0c7d97c5SJed Brown coarse_pc_type = PCLU; 1648*0c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 1649*0c7d97c5SJed Brown active_rank = rank_prec_comm; 1650*0c7d97c5SJed Brown break; 1651*0c7d97c5SJed Brown 1652*0c7d97c5SJed Brown case(PARALLEL_BDDC): 1653*0c7d97c5SJed Brown 1654*0c7d97c5SJed Brown pcbddc->coarse_communications_type = SCATTERS_BDDC; 1655*0c7d97c5SJed Brown coarse_mat_type = MATMPIAIJ; 1656*0c7d97c5SJed Brown coarse_pc_type = PCREDUNDANT; 1657*0c7d97c5SJed Brown coarse_comm = prec_comm; 1658*0c7d97c5SJed Brown active_rank = rank_prec_comm; 1659*0c7d97c5SJed Brown break; 1660*0c7d97c5SJed Brown 1661*0c7d97c5SJed Brown case(SEQUENTIAL_BDDC): 1662*0c7d97c5SJed Brown pcbddc->coarse_communications_type = GATHERS_BDDC; 1663*0c7d97c5SJed Brown coarse_mat_type = MATSEQAIJ; 1664*0c7d97c5SJed Brown coarse_pc_type = PCLU; 1665*0c7d97c5SJed Brown coarse_comm = PETSC_COMM_SELF; 1666*0c7d97c5SJed Brown active_rank = master_proc; 1667*0c7d97c5SJed Brown break; 1668*0c7d97c5SJed Brown } 1669*0c7d97c5SJed Brown 1670*0c7d97c5SJed Brown switch(pcbddc->coarse_communications_type){ 1671*0c7d97c5SJed Brown 1672*0c7d97c5SJed Brown case(SCATTERS_BDDC): 1673*0c7d97c5SJed Brown { 1674*0c7d97c5SJed Brown if(pcbddc->coarse_problem_type==MULTILEVEL_BDDC) { 1675*0c7d97c5SJed Brown 1676*0c7d97c5SJed Brown PetscMPIInt send_size; 1677*0c7d97c5SJed Brown PetscInt *aux_ins_indices; 1678*0c7d97c5SJed Brown PetscInt ii,jj; 1679*0c7d97c5SJed Brown MPI_Request *requests; 1680*0c7d97c5SJed Brown 1681*0c7d97c5SJed Brown /* allocate auxiliary space */ 1682*0c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->coarse_size*sizeof(PetscInt),&aux_ins_indices);CHKERRQ(ierr); 1683*0c7d97c5SJed Brown ierr = PetscMemzero(aux_ins_indices,pcbddc->coarse_size*sizeof(PetscInt));CHKERRQ(ierr); 1684*0c7d97c5SJed Brown /* allocate stuffs for message massing */ 1685*0c7d97c5SJed Brown ierr = PetscMalloc ( (count_recv+1)*sizeof(MPI_Request),&requests);CHKERRQ(ierr); 1686*0c7d97c5SJed Brown for(i=0;i<count_recv+1;i++) requests[i]=MPI_REQUEST_NULL; 1687*0c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 1688*0c7d97c5SJed Brown ierr = PetscMalloc ( count_recv*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 1689*0c7d97c5SJed Brown /* fill up quantities */ 1690*0c7d97c5SJed Brown j=0; 1691*0c7d97c5SJed Brown for(i=0;i<count_recv;i++){ 1692*0c7d97c5SJed Brown ii = ranks_recv[i]; 1693*0c7d97c5SJed Brown localsizes2[i]=pcbddc->local_primal_sizes[ii]*pcbddc->local_primal_sizes[ii]; 1694*0c7d97c5SJed Brown localdispl2[i]=j; 1695*0c7d97c5SJed Brown j+=localsizes2[i]; 1696*0c7d97c5SJed Brown jj = pcbddc->local_primal_displacements[ii]; 1697*0c7d97c5SJed 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 1698*0c7d97c5SJed Brown } 1699*0c7d97c5SJed Brown //printf("aux_ins_indices 1\n"); 1700*0c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 1701*0c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 1702*0c7d97c5SJed Brown //printf("\n"); 1703*0c7d97c5SJed Brown /* temp_coarse_mat_vals used to store temporarly received matrix values */ 1704*0c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 1705*0c7d97c5SJed Brown /* evaluate how many values I will insert in coarse mat */ 1706*0c7d97c5SJed Brown ins_local_primal_size=0; 1707*0c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 1708*0c7d97c5SJed Brown if(aux_ins_indices[i]) 1709*0c7d97c5SJed Brown ins_local_primal_size++; 1710*0c7d97c5SJed Brown /* evaluate indices I will insert in coarse mat */ 1711*0c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscInt),&ins_local_primal_indices);CHKERRQ(ierr); 1712*0c7d97c5SJed Brown j=0; 1713*0c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++) 1714*0c7d97c5SJed Brown if(aux_ins_indices[i]) 1715*0c7d97c5SJed Brown ins_local_primal_indices[j++]=i; 1716*0c7d97c5SJed Brown /* use aux_ins_indices to realize a global to local mapping */ 1717*0c7d97c5SJed Brown j=0; 1718*0c7d97c5SJed Brown for(i=0;i<pcbddc->coarse_size;i++){ 1719*0c7d97c5SJed Brown if(aux_ins_indices[i]==0){ 1720*0c7d97c5SJed Brown aux_ins_indices[i]=-1; 1721*0c7d97c5SJed Brown } else { 1722*0c7d97c5SJed Brown aux_ins_indices[i]=j; 1723*0c7d97c5SJed Brown j++; 1724*0c7d97c5SJed Brown } 1725*0c7d97c5SJed Brown } 1726*0c7d97c5SJed Brown 1727*0c7d97c5SJed Brown //printf("New details localsizes2 localdispl2\n"); 1728*0c7d97c5SJed Brown //for(i=0;i<count_recv;i++) 1729*0c7d97c5SJed Brown // printf("(%d %d) ",localsizes2[i],localdispl2[i]); 1730*0c7d97c5SJed Brown //printf("\n"); 1731*0c7d97c5SJed Brown //printf("aux_ins_indices 2\n"); 1732*0c7d97c5SJed Brown //for(i=0;i<pcbddc->coarse_size;i++) 1733*0c7d97c5SJed Brown // printf("%d ",aux_ins_indices[i]); 1734*0c7d97c5SJed Brown //printf("\n"); 1735*0c7d97c5SJed Brown //printf("ins_local_primal_indices\n"); 1736*0c7d97c5SJed Brown //for(i=0;i<ins_local_primal_size;i++) 1737*0c7d97c5SJed Brown // printf("%d ",ins_local_primal_indices[i]); 1738*0c7d97c5SJed Brown //printf("\n"); 1739*0c7d97c5SJed Brown //printf("coarse_submat_vals\n"); 1740*0c7d97c5SJed Brown //for(i=0;i<pcbddc->local_primal_size;i++) 1741*0c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_size;j++) 1742*0c7d97c5SJed 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]); 1743*0c7d97c5SJed Brown //printf("\n"); 1744*0c7d97c5SJed Brown 1745*0c7d97c5SJed Brown /* processes partecipating in coarse problem receive matrix data from their friends */ 1746*0c7d97c5SJed Brown for(i=0;i<count_recv;i++) MPI_Irecv(&temp_coarse_mat_vals[localdispl2[i]],localsizes2[i],MPIU_SCALAR,ranks_recv[i],666,prec_comm,&requests[i]); 1747*0c7d97c5SJed Brown if(rank_coarse_proc_send_to != MPI_PROC_NULL ) { 1748*0c7d97c5SJed Brown send_size=pcbddc->local_primal_size*pcbddc->local_primal_size; 1749*0c7d97c5SJed Brown MPI_Isend(&coarse_submat_vals[0],send_size,MPIU_SCALAR,rank_coarse_proc_send_to,666,prec_comm,&requests[count_recv]); 1750*0c7d97c5SJed Brown } 1751*0c7d97c5SJed Brown MPI_Waitall(count_recv+1,requests,MPI_STATUSES_IGNORE); 1752*0c7d97c5SJed Brown 1753*0c7d97c5SJed Brown //if(coarse_color == 0) { 1754*0c7d97c5SJed Brown // printf("temp_coarse_mat_vals\n"); 1755*0c7d97c5SJed Brown // for(k=0;k<count_recv;k++){ 1756*0c7d97c5SJed Brown // printf("---- %d ----\n",ranks_recv[k]); 1757*0c7d97c5SJed Brown // for(i=0;i<pcbddc->local_primal_sizes[ranks_recv[k]];i++) 1758*0c7d97c5SJed Brown // for(j=0;j<pcbddc->local_primal_sizes[ranks_recv[k]];j++) 1759*0c7d97c5SJed 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]); 1760*0c7d97c5SJed Brown // printf("\n"); 1761*0c7d97c5SJed Brown // } 1762*0c7d97c5SJed Brown //} 1763*0c7d97c5SJed Brown /* calculate data to insert in coarse mat */ 1764*0c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 1765*0c7d97c5SJed Brown PetscMemzero(ins_coarse_mat_vals,ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar)); 1766*0c7d97c5SJed Brown 1767*0c7d97c5SJed Brown PetscMPIInt rr,kk,lps,lpd; 1768*0c7d97c5SJed Brown PetscInt row_ind,col_ind; 1769*0c7d97c5SJed Brown for(k=0;k<count_recv;k++){ 1770*0c7d97c5SJed Brown rr = ranks_recv[k]; 1771*0c7d97c5SJed Brown kk = localdispl2[k]; 1772*0c7d97c5SJed Brown lps = pcbddc->local_primal_sizes[rr]; 1773*0c7d97c5SJed Brown lpd = pcbddc->local_primal_displacements[rr]; 1774*0c7d97c5SJed Brown //printf("Inserting the following indices (received from %d)\n",rr); 1775*0c7d97c5SJed Brown for(j=0;j<lps;j++){ 1776*0c7d97c5SJed Brown col_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+j]]; 1777*0c7d97c5SJed Brown for(i=0;i<lps;i++){ 1778*0c7d97c5SJed Brown row_ind=aux_ins_indices[pcbddc->replicated_local_primal_indices[lpd+i]]; 1779*0c7d97c5SJed Brown //printf("%d %d\n",row_ind,col_ind); 1780*0c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*ins_local_primal_size+row_ind]+=temp_coarse_mat_vals[kk+j*lps+i]; 1781*0c7d97c5SJed Brown } 1782*0c7d97c5SJed Brown } 1783*0c7d97c5SJed Brown } 1784*0c7d97c5SJed Brown ierr = PetscFree(requests);CHKERRQ(ierr); 1785*0c7d97c5SJed Brown ierr = PetscFree(aux_ins_indices);CHKERRQ(ierr); 1786*0c7d97c5SJed Brown ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr); 1787*0c7d97c5SJed Brown if(coarse_color == 0) { ierr = PetscFree(ranks_recv);CHKERRQ(ierr); } 1788*0c7d97c5SJed Brown 1789*0c7d97c5SJed Brown /* create local to global mapping needed by coarse MATIS */ 1790*0c7d97c5SJed Brown { 1791*0c7d97c5SJed Brown IS coarse_IS; 1792*0c7d97c5SJed Brown if(coarse_comm != MPI_COMM_NULL ) MPI_Comm_free(&coarse_comm); 1793*0c7d97c5SJed Brown coarse_comm = prec_comm; 1794*0c7d97c5SJed Brown active_rank=rank_prec_comm; 1795*0c7d97c5SJed Brown ierr = ISCreateGeneral(coarse_comm,ins_local_primal_size,ins_local_primal_indices,PETSC_COPY_VALUES,&coarse_IS);CHKERRQ(ierr); 1796*0c7d97c5SJed Brown //ierr = ISSetBlockSize(coarse_IS,bs);CHKERRQ(ierr); 1797*0c7d97c5SJed Brown ierr = ISLocalToGlobalMappingCreateIS(coarse_IS,&coarse_ISLG);CHKERRQ(ierr); 1798*0c7d97c5SJed Brown ierr = ISDestroy(&coarse_IS);CHKERRQ(ierr); 1799*0c7d97c5SJed Brown } 1800*0c7d97c5SJed Brown } 1801*0c7d97c5SJed Brown if(pcbddc->coarse_problem_type==PARALLEL_BDDC) { 1802*0c7d97c5SJed Brown /* arrays for values insertion */ 1803*0c7d97c5SJed Brown ins_local_primal_size = pcbddc->local_primal_size; 1804*0c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 1805*0c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 1806*0c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 1807*0c7d97c5SJed Brown ins_local_primal_indices[j]=pcbddc->local_primal_indices[j]; 1808*0c7d97c5SJed 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]; 1809*0c7d97c5SJed Brown } 1810*0c7d97c5SJed Brown } 1811*0c7d97c5SJed Brown break; 1812*0c7d97c5SJed Brown 1813*0c7d97c5SJed Brown } 1814*0c7d97c5SJed Brown 1815*0c7d97c5SJed Brown case(GATHERS_BDDC): 1816*0c7d97c5SJed Brown { 1817*0c7d97c5SJed Brown 1818*0c7d97c5SJed Brown PetscMPIInt mysize,mysize2; 1819*0c7d97c5SJed Brown 1820*0c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 1821*0c7d97c5SJed Brown ierr = PetscMalloc ( pcbddc->replicated_primal_size*sizeof(PetscMPIInt),&pcbddc->replicated_local_primal_indices);CHKERRQ(ierr); 1822*0c7d97c5SJed Brown pcbddc->replicated_local_primal_values = (PetscScalar*)calloc(pcbddc->replicated_primal_size,sizeof(PetscScalar)); 1823*0c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localsizes2);CHKERRQ(ierr); 1824*0c7d97c5SJed Brown ierr = PetscMalloc ( size_prec_comm*sizeof(PetscMPIInt),&localdispl2);CHKERRQ(ierr); 1825*0c7d97c5SJed Brown /* arrays for values insertion */ 1826*0c7d97c5SJed Brown ins_local_primal_size = pcbddc->coarse_size; 1827*0c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*sizeof(PetscMPIInt),&ins_local_primal_indices);CHKERRQ(ierr); 1828*0c7d97c5SJed Brown ierr = PetscMalloc ( ins_local_primal_size*ins_local_primal_size*sizeof(PetscScalar),&ins_coarse_mat_vals);CHKERRQ(ierr); 1829*0c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) localsizes2[i]=pcbddc->local_primal_sizes[i]*pcbddc->local_primal_sizes[i]; 1830*0c7d97c5SJed Brown localdispl2[0]=0; 1831*0c7d97c5SJed Brown for(i=1;i<size_prec_comm;i++) localdispl2[i]=localsizes2[i-1]+localdispl2[i-1]; 1832*0c7d97c5SJed Brown j=0; 1833*0c7d97c5SJed Brown for(i=0;i<size_prec_comm;i++) j+=localsizes2[i]; 1834*0c7d97c5SJed Brown ierr = PetscMalloc ( j*sizeof(PetscScalar),&temp_coarse_mat_vals);CHKERRQ(ierr); 1835*0c7d97c5SJed Brown } 1836*0c7d97c5SJed Brown 1837*0c7d97c5SJed Brown mysize=pcbddc->local_primal_size; 1838*0c7d97c5SJed Brown mysize2=pcbddc->local_primal_size*pcbddc->local_primal_size; 1839*0c7d97c5SJed Brown if(pcbddc->coarse_problem_type == SEQUENTIAL_BDDC){ 1840*0c7d97c5SJed Brown 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); 1841*0c7d97c5SJed Brown MPI_Gatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,master_proc,prec_comm); 1842*0c7d97c5SJed Brown } else { 1843*0c7d97c5SJed Brown 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); 1844*0c7d97c5SJed Brown MPI_Allgatherv(&coarse_submat_vals[0],mysize2,MPIU_SCALAR,&temp_coarse_mat_vals[0],localsizes2,localdispl2,MPIU_SCALAR,prec_comm); 1845*0c7d97c5SJed Brown } 1846*0c7d97c5SJed Brown 1847*0c7d97c5SJed Brown /* free data structures no longer needed and allocate some space which will be needed in BDDC application */ 1848*0c7d97c5SJed Brown if(rank_prec_comm==active_rank) { 1849*0c7d97c5SJed Brown PetscInt offset,offset2,row_ind,col_ind; 1850*0c7d97c5SJed Brown for(j=0;j<ins_local_primal_size;j++){ 1851*0c7d97c5SJed Brown ins_local_primal_indices[j]=j; 1852*0c7d97c5SJed Brown for(i=0;i<ins_local_primal_size;i++) ins_coarse_mat_vals[j*ins_local_primal_size+i]=0.0; 1853*0c7d97c5SJed Brown } 1854*0c7d97c5SJed Brown for(k=0;k<size_prec_comm;k++){ 1855*0c7d97c5SJed Brown offset=pcbddc->local_primal_displacements[k]; 1856*0c7d97c5SJed Brown offset2=localdispl2[k]; 1857*0c7d97c5SJed Brown for(j=0;j<pcbddc->local_primal_sizes[k];j++){ 1858*0c7d97c5SJed Brown col_ind=pcbddc->replicated_local_primal_indices[offset+j]; 1859*0c7d97c5SJed Brown for(i=0;i<pcbddc->local_primal_sizes[k];i++){ 1860*0c7d97c5SJed Brown row_ind=pcbddc->replicated_local_primal_indices[offset+i]; 1861*0c7d97c5SJed Brown ins_coarse_mat_vals[col_ind*pcbddc->coarse_size+row_ind]+=temp_coarse_mat_vals[offset2+j*pcbddc->local_primal_sizes[k]+i]; 1862*0c7d97c5SJed Brown } 1863*0c7d97c5SJed Brown } 1864*0c7d97c5SJed Brown } 1865*0c7d97c5SJed Brown } 1866*0c7d97c5SJed Brown break; 1867*0c7d97c5SJed Brown }//switch on coarse problem and communications associated with finished 1868*0c7d97c5SJed Brown } 1869*0c7d97c5SJed Brown 1870*0c7d97c5SJed Brown /* Now create and fill up coarse matrix */ 1871*0c7d97c5SJed Brown if( rank_prec_comm == active_rank ) { 1872*0c7d97c5SJed Brown if(pcbddc->coarse_problem_type != MULTILEVEL_BDDC) { 1873*0c7d97c5SJed Brown ierr = MatCreate(coarse_comm,&pcbddc->coarse_mat);CHKERRQ(ierr); 1874*0c7d97c5SJed Brown ierr = MatSetSizes(pcbddc->coarse_mat,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size);CHKERRQ(ierr); 1875*0c7d97c5SJed Brown ierr = MatSetType(pcbddc->coarse_mat,coarse_mat_type);CHKERRQ(ierr); 1876*0c7d97c5SJed Brown ierr = MatSetOption(pcbddc->coarse_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 1877*0c7d97c5SJed Brown ierr = MatSetOption(pcbddc->coarse_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 1878*0c7d97c5SJed Brown } else { 1879*0c7d97c5SJed Brown Mat matis_coarse_local_mat; 1880*0c7d97c5SJed Brown ierr = MatCreateIS(coarse_comm,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_ISLG,&pcbddc->coarse_mat);CHKERRQ(ierr); 1881*0c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 1882*0c7d97c5SJed Brown ierr = MatSetOption(matis_coarse_local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); //local values stored in column major 1883*0c7d97c5SJed Brown ierr = MatSetOption(matis_coarse_local_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 1884*0c7d97c5SJed Brown ierr = MatSetOption(matis_coarse_local_mat,MAT_USE_INODES,PETSC_FALSE);CHKERRQ(ierr); 1885*0c7d97c5SJed Brown } 1886*0c7d97c5SJed 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); 1887*0c7d97c5SJed Brown ierr = MatAssemblyBegin(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1888*0c7d97c5SJed Brown ierr = MatAssemblyEnd(pcbddc->coarse_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1889*0c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 1890*0c7d97c5SJed Brown Mat matis_coarse_local_mat; 1891*0c7d97c5SJed Brown printf("Setting bs %d\n",bs); 1892*0c7d97c5SJed Brown ierr = MatISGetLocalMat(pcbddc->coarse_mat,&matis_coarse_local_mat);CHKERRQ(ierr); 1893*0c7d97c5SJed Brown ierr = MatSetBlockSize(matis_coarse_local_mat,bs);CHKERRQ(ierr); 1894*0c7d97c5SJed Brown } 1895*0c7d97c5SJed Brown 1896*0c7d97c5SJed Brown ierr = MatGetVecs(pcbddc->coarse_mat,&pcbddc->coarse_vec,&pcbddc->coarse_rhs);CHKERRQ(ierr); 1897*0c7d97c5SJed Brown /* Preconditioner for coarse problem */ 1898*0c7d97c5SJed Brown ierr = PCCreate(coarse_comm,&pcbddc->coarse_pc);CHKERRQ(ierr); 1899*0c7d97c5SJed Brown ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_pc,(PetscObject)pc,1);CHKERRQ(ierr); 1900*0c7d97c5SJed Brown ierr = PCSetOperators(pcbddc->coarse_pc,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER);CHKERRQ(ierr); 1901*0c7d97c5SJed Brown ierr = PCSetType(pcbddc->coarse_pc,coarse_pc_type);CHKERRQ(ierr); 1902*0c7d97c5SJed Brown ierr = PCSetOptionsPrefix(pcbddc->coarse_pc,"pc_bddc_coarse_");CHKERRQ(ierr); 1903*0c7d97c5SJed Brown /* Allow user's customization */ 1904*0c7d97c5SJed Brown ierr = PCSetFromOptions(pcbddc->coarse_pc);CHKERRQ(ierr); 1905*0c7d97c5SJed Brown /* Set Up PC for coarse problem BDDC */ 1906*0c7d97c5SJed Brown //if(pcbddc->check_flag && pcbddc->coarse_problem_type == MULTILEVEL_BDDC) { 1907*0c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) PetscPrintf(PETSC_COMM_WORLD,"----------------Setting up a new level---------------\n"); 1908*0c7d97c5SJed Brown if(pcbddc->coarse_problem_type == MULTILEVEL_BDDC) PCBDDCSetCoarseProblemType(pcbddc->coarse_pc,MULTILEVEL_BDDC); 1909*0c7d97c5SJed Brown ierr = PCSetUp(pcbddc->coarse_pc);CHKERRQ(ierr); 1910*0c7d97c5SJed Brown } 1911*0c7d97c5SJed Brown if(pcbddc->coarse_communications_type == SCATTERS_BDDC) { 1912*0c7d97c5SJed Brown IS local_IS,global_IS; 1913*0c7d97c5SJed Brown ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size,0,1,&local_IS);CHKERRQ(ierr); 1914*0c7d97c5SJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_indices,PETSC_COPY_VALUES,&global_IS);CHKERRQ(ierr); 1915*0c7d97c5SJed Brown ierr = VecScatterCreate(pcbddc->vec1_P,local_IS,pcbddc->coarse_vec,global_IS,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 1916*0c7d97c5SJed Brown ierr = ISDestroy(&local_IS);CHKERRQ(ierr); 1917*0c7d97c5SJed Brown ierr = ISDestroy(&global_IS);CHKERRQ(ierr); 1918*0c7d97c5SJed Brown } 1919*0c7d97c5SJed Brown 1920*0c7d97c5SJed Brown 1921*0c7d97c5SJed Brown /* Check condition number of coarse problem */ 1922*0c7d97c5SJed Brown /* How to destroy KSP without destroying PC associated with? */ 1923*0c7d97c5SJed Brown /* if( rank_prec_comm == active_rank ) { 1924*0c7d97c5SJed Brown KSP coarseksp; 1925*0c7d97c5SJed Brown PetscScalar m_one=-1.0; 1926*0c7d97c5SJed Brown PetscReal infty_error,lambda_min,lambda_max; 1927*0c7d97c5SJed Brown 1928*0c7d97c5SJed Brown KSPCreate(coarse_comm,&coarseksp); 1929*0c7d97c5SJed Brown KSPSetType(coarseksp,KSPCG); 1930*0c7d97c5SJed Brown KSPSetOperators(coarseksp,pcbddc->coarse_mat,pcbddc->coarse_mat,SAME_PRECONDITIONER); 1931*0c7d97c5SJed Brown KSPSetPC(coarseksp,pcbddc->coarse_pc); 1932*0c7d97c5SJed Brown KSPSetComputeSingularValues(coarseksp,PETSC_TRUE); 1933*0c7d97c5SJed Brown VecSetRandom(pcbddc->coarse_rhs,PETSC_NULL); 1934*0c7d97c5SJed Brown MatMult(pcbddc->coarse_mat,pcbddc->coarse_rhs,pcbddc->coarse_vec); 1935*0c7d97c5SJed Brown MatMult(pcbddc->coarse_mat,pcbddc->coarse_vec,pcbddc->coarse_rhs); 1936*0c7d97c5SJed Brown KSPSolve(coarseksp,pcbddc->coarse_rhs,pcbddc->coarse_rhs); 1937*0c7d97c5SJed Brown KSPComputeExtremeSingularValues(coarseksp,&lambda_max,&lambda_min); 1938*0c7d97c5SJed Brown VecAXPY(pcbddc->coarse_rhs,m_one,pcbddc->coarse_vec); 1939*0c7d97c5SJed Brown VecNorm(pcbddc->coarse_rhs,NORM_INFINITY,&infty_error); 1940*0c7d97c5SJed Brown printf("eigenvalues: % 1.14e %1.14e\n",lambda_min,lambda_max); 1941*0c7d97c5SJed Brown printf("Error on coarse ksp %1.14e\n",infty_error); 1942*0c7d97c5SJed Brown 1943*0c7d97c5SJed Brown }*/ 1944*0c7d97c5SJed Brown 1945*0c7d97c5SJed Brown /* free data structures no longer needed */ 1946*0c7d97c5SJed Brown if(coarse_ISLG) { ierr = ISLocalToGlobalMappingDestroy(&coarse_ISLG);CHKERRQ(ierr); } 1947*0c7d97c5SJed Brown if(ins_local_primal_indices) { ierr = PetscFree(ins_local_primal_indices);CHKERRQ(ierr); } 1948*0c7d97c5SJed Brown if(ins_coarse_mat_vals) { ierr = PetscFree(ins_coarse_mat_vals);CHKERRQ(ierr);} 1949*0c7d97c5SJed Brown if(localsizes2) { ierr = PetscFree(localsizes2);CHKERRQ(ierr);} 1950*0c7d97c5SJed Brown if(localdispl2) { ierr = PetscFree(localdispl2);CHKERRQ(ierr);} 1951*0c7d97c5SJed Brown if(temp_coarse_mat_vals) { ierr = PetscFree(temp_coarse_mat_vals);CHKERRQ(ierr);} 1952*0c7d97c5SJed Brown 1953*0c7d97c5SJed Brown PetscFunctionReturn(0); 1954*0c7d97c5SJed Brown 1955*0c7d97c5SJed Brown } 1956*0c7d97c5SJed Brown 1957*0c7d97c5SJed Brown #undef __FUNCT__ 1958*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCManageLocalBoundaries" 1959*0c7d97c5SJed Brown PetscErrorCode PCBDDCManageLocalBoundaries(PC pc) 1960*0c7d97c5SJed Brown { 1961*0c7d97c5SJed Brown 1962*0c7d97c5SJed Brown PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1963*0c7d97c5SJed Brown PC_IS *pcis = (PC_IS*)pc->data; 1964*0c7d97c5SJed Brown Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1965*0c7d97c5SJed Brown PetscInt *distinct_values; 1966*0c7d97c5SJed Brown PetscInt **array_int; 1967*0c7d97c5SJed Brown PetscInt bs,ierr,i,j,s,k; 1968*0c7d97c5SJed Brown PetscInt total_counts; 1969*0c7d97c5SJed Brown PetscBool flg_row; 1970*0c7d97c5SJed Brown PCBDDCGraph mat_graph; 1971*0c7d97c5SJed Brown PetscScalar *array; 1972*0c7d97c5SJed Brown Mat mat_adj; 1973*0c7d97c5SJed Brown 1974*0c7d97c5SJed Brown PetscFunctionBegin; 1975*0c7d97c5SJed Brown 1976*0c7d97c5SJed Brown ierr = MatGetBlockSize(matis->A,&bs);CHKERRQ(ierr); 1977*0c7d97c5SJed Brown // allocate and initialize needed graph structure 1978*0c7d97c5SJed Brown ierr = PetscMalloc(sizeof(*mat_graph),&mat_graph);CHKERRQ(ierr); 1979*0c7d97c5SJed Brown ierr = MatConvert(matis->A,MATMPIADJ,MAT_INITIAL_MATRIX,&mat_adj);CHKERRQ(ierr); 1980*0c7d97c5SJed Brown ierr = MatGetRowIJ(mat_adj,0,PETSC_FALSE,PETSC_FALSE,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 1981*0c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatGetRowIJ called from PCBDDCManageLocalBoundaries.\n"); 1982*0c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&mat_graph->where);CHKERRQ(ierr); 1983*0c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&mat_graph->count);CHKERRQ(ierr); 1984*0c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&mat_graph->which_dof);CHKERRQ(ierr); 1985*0c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt),&mat_graph->queue);CHKERRQ(ierr); 1986*0c7d97c5SJed Brown ierr = PetscMalloc((mat_graph->nvtxs+1)*sizeof(PetscInt),&mat_graph->cptr);CHKERRQ(ierr); 1987*0c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscBool),&mat_graph->touched);CHKERRQ(ierr); 1988*0c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++){ 1989*0c7d97c5SJed Brown mat_graph->count[i]=0; 1990*0c7d97c5SJed Brown mat_graph->touched[i]=PETSC_FALSE; 1991*0c7d97c5SJed Brown } 1992*0c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs/bs;i++) { 1993*0c7d97c5SJed Brown for(s=0;s<bs;s++) { 1994*0c7d97c5SJed Brown mat_graph->which_dof[i*bs+s]=s; 1995*0c7d97c5SJed Brown } 1996*0c7d97c5SJed Brown } 1997*0c7d97c5SJed Brown //printf("nvtxs = %d\n",mat_graph->nvtxs); 1998*0c7d97c5SJed Brown //printf("these are my IS data with n_neigh = %d\n",pcis->n_neigh); 1999*0c7d97c5SJed Brown //for(i=0;i<pcis->n_neigh;i++){ 2000*0c7d97c5SJed Brown // printf("number of shared nodes with rank %d is %d \n",pcis->neigh[i],pcis->n_shared[i]); 2001*0c7d97c5SJed Brown // } 2002*0c7d97c5SJed Brown 2003*0c7d97c5SJed Brown total_counts=0; 2004*0c7d97c5SJed Brown for(i=0;i<pcis->n_neigh;i++){ 2005*0c7d97c5SJed Brown s=pcis->n_shared[i]; 2006*0c7d97c5SJed Brown total_counts+=s; 2007*0c7d97c5SJed Brown //printf("computing neigh %d (rank = %d, n_shared = %d)\n",i,pcis->neigh[i],s); 2008*0c7d97c5SJed Brown for(j=0;j<s;j=j++){ 2009*0c7d97c5SJed Brown mat_graph->count[pcis->shared[i][j]] += 1; 2010*0c7d97c5SJed Brown } 2011*0c7d97c5SJed Brown } 2012*0c7d97c5SJed Brown /* Take into account Neumann data incrementing number of sharing subdomains for all but faces nodes lying on the interface */ 2013*0c7d97c5SJed Brown if(pcbddc->Vec_Neumann) { 2014*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->Vec_Neumann,&array);CHKERRQ(ierr); 2015*0c7d97c5SJed Brown for(i=0;i<pcis->n;i++){ 2016*0c7d97c5SJed Brown if(array[i] > 0.0 && mat_graph->count[i] > 2){ 2017*0c7d97c5SJed Brown mat_graph->count[i]=mat_graph->count[i]+1; 2018*0c7d97c5SJed Brown total_counts++; 2019*0c7d97c5SJed Brown } 2020*0c7d97c5SJed Brown } 2021*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->Vec_Neumann,&array);CHKERRQ(ierr); 2022*0c7d97c5SJed Brown } 2023*0c7d97c5SJed Brown 2024*0c7d97c5SJed Brown ierr = PetscMalloc(mat_graph->nvtxs*sizeof(PetscInt*),&array_int);CHKERRQ(ierr); 2025*0c7d97c5SJed Brown if(mat_graph->nvtxs) ierr = PetscMalloc(total_counts*sizeof(PetscInt),&array_int[0]);CHKERRQ(ierr); 2026*0c7d97c5SJed Brown for(i=1;i<mat_graph->nvtxs;i++) array_int[i]=array_int[i-1]+mat_graph->count[i-1]; 2027*0c7d97c5SJed Brown 2028*0c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++) mat_graph->count[i]=0; 2029*0c7d97c5SJed Brown for(i=0;i<pcis->n_neigh;i++){ 2030*0c7d97c5SJed Brown s=pcis->n_shared[i]; 2031*0c7d97c5SJed Brown for(j=0;j<s;j++) { 2032*0c7d97c5SJed Brown k=pcis->shared[i][j]; 2033*0c7d97c5SJed Brown array_int[k][mat_graph->count[k]] = pcis->neigh[i]; 2034*0c7d97c5SJed Brown mat_graph->count[k]+=1; 2035*0c7d97c5SJed Brown } 2036*0c7d97c5SJed Brown } 2037*0c7d97c5SJed Brown /* set -1 fake neighbour */ 2038*0c7d97c5SJed Brown if(pcbddc->Vec_Neumann) { 2039*0c7d97c5SJed Brown ierr = VecGetArray(pcbddc->Vec_Neumann,&array);CHKERRQ(ierr); 2040*0c7d97c5SJed Brown for(i=0;i<pcis->n;i++){ 2041*0c7d97c5SJed Brown if( array[i] > 0.0 && mat_graph->count[i] > 2){ 2042*0c7d97c5SJed Brown array_int[i][mat_graph->count[i]] = -1; //An additional fake neighbour (with rank -1) 2043*0c7d97c5SJed Brown mat_graph->count[i]+=1; 2044*0c7d97c5SJed Brown } 2045*0c7d97c5SJed Brown } 2046*0c7d97c5SJed Brown ierr = VecRestoreArray(pcbddc->Vec_Neumann,&array);CHKERRQ(ierr); 2047*0c7d97c5SJed Brown } 2048*0c7d97c5SJed Brown 2049*0c7d97c5SJed Brown /* sort sharing subdomains */ 2050*0c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++) { ierr = PetscSortInt(mat_graph->count[i],array_int[i]);CHKERRQ(ierr); } 2051*0c7d97c5SJed Brown 2052*0c7d97c5SJed Brown // Prepare for FindConnectedComponents 2053*0c7d97c5SJed Brown // Vertices will be eliminated later (if needed) 2054*0c7d97c5SJed Brown PetscInt nodes_touched=0; 2055*0c7d97c5SJed Brown for(i=0;i<mat_graph->nvtxs;i++){ 2056*0c7d97c5SJed Brown if(!mat_graph->count[i]){ //internal nodes 2057*0c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 2058*0c7d97c5SJed Brown mat_graph->where[i]=0; 2059*0c7d97c5SJed Brown nodes_touched++; 2060*0c7d97c5SJed Brown } 2061*0c7d97c5SJed Brown if(pcbddc->faces_flag){ 2062*0c7d97c5SJed Brown if(mat_graph->count[i]>2){ //all but faces 2063*0c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 2064*0c7d97c5SJed Brown mat_graph->where[i]=0; 2065*0c7d97c5SJed Brown nodes_touched++; 2066*0c7d97c5SJed Brown } 2067*0c7d97c5SJed Brown } 2068*0c7d97c5SJed Brown if(pcbddc->edges_flag){ 2069*0c7d97c5SJed Brown if(mat_graph->count[i]==2){ //faces 2070*0c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 2071*0c7d97c5SJed Brown mat_graph->where[i]=0; 2072*0c7d97c5SJed Brown nodes_touched++; 2073*0c7d97c5SJed Brown } 2074*0c7d97c5SJed Brown } 2075*0c7d97c5SJed Brown } 2076*0c7d97c5SJed Brown 2077*0c7d97c5SJed Brown PetscInt rvalue=1; 2078*0c7d97c5SJed Brown PetscBool same_set; 2079*0c7d97c5SJed Brown mat_graph->ncmps = 0; 2080*0c7d97c5SJed Brown while(nodes_touched<mat_graph->nvtxs) { 2081*0c7d97c5SJed Brown // find first untouched node in local ordering 2082*0c7d97c5SJed Brown i=0; 2083*0c7d97c5SJed Brown while(mat_graph->touched[i]) i++; 2084*0c7d97c5SJed Brown mat_graph->touched[i]=PETSC_TRUE; 2085*0c7d97c5SJed Brown mat_graph->where[i]=rvalue; 2086*0c7d97c5SJed Brown nodes_touched++; 2087*0c7d97c5SJed Brown // now find other connected nodes shared by the same set of subdomains 2088*0c7d97c5SJed Brown for(j=i+1;j<mat_graph->nvtxs;j++){ 2089*0c7d97c5SJed Brown // check for same number of sharing subdomains and dof number 2090*0c7d97c5SJed Brown if(mat_graph->count[i]==mat_graph->count[j] && mat_graph->which_dof[i] == mat_graph->which_dof[j] ){ 2091*0c7d97c5SJed Brown // check for same set of sharing subdomains 2092*0c7d97c5SJed Brown same_set=PETSC_TRUE; 2093*0c7d97c5SJed Brown for(k=0;k<mat_graph->count[j];k++){ 2094*0c7d97c5SJed Brown if(array_int[i][k]!=array_int[j][k]) { 2095*0c7d97c5SJed Brown same_set=PETSC_FALSE; 2096*0c7d97c5SJed Brown } 2097*0c7d97c5SJed Brown } 2098*0c7d97c5SJed Brown // OK, I found a friend of mine 2099*0c7d97c5SJed Brown if(same_set) { 2100*0c7d97c5SJed Brown mat_graph->where[j]=rvalue; 2101*0c7d97c5SJed Brown mat_graph->touched[j]=PETSC_TRUE; 2102*0c7d97c5SJed Brown nodes_touched++; 2103*0c7d97c5SJed Brown } 2104*0c7d97c5SJed Brown } 2105*0c7d97c5SJed Brown } 2106*0c7d97c5SJed Brown rvalue++; 2107*0c7d97c5SJed Brown } 2108*0c7d97c5SJed Brown // printf("where and count contains %d distinct values\n",rvalue); 2109*0c7d97c5SJed Brown // for(j=0;j<mat_graph->nvtxs;j++) 2110*0c7d97c5SJed Brown // printf("[%d %d %d]\n",j,mat_graph->where[j],mat_graph->count[j]); 2111*0c7d97c5SJed Brown 2112*0c7d97c5SJed Brown if(mat_graph->nvtxs) { 2113*0c7d97c5SJed Brown ierr = PetscFree(array_int[0]);CHKERRQ(ierr); 2114*0c7d97c5SJed Brown ierr = PetscFree(array_int);CHKERRQ(ierr); 2115*0c7d97c5SJed Brown } 2116*0c7d97c5SJed Brown 2117*0c7d97c5SJed Brown rvalue--; 2118*0c7d97c5SJed Brown ierr = PetscMalloc ( rvalue*sizeof(PetscInt),&distinct_values);CHKERRQ(ierr); 2119*0c7d97c5SJed Brown for(i=0;i<rvalue;i++) distinct_values[i]=i+1; //initializiation 2120*0c7d97c5SJed Brown if(rvalue) ierr = PCBDDCFindConnectedComponents(mat_graph, rvalue, distinct_values); 2121*0c7d97c5SJed Brown //printf("total number of connected components %d \n",mat_graph->ncmps); 2122*0c7d97c5SJed Brown //for (i=0; i<mat_graph->ncmps; i++) { 2123*0c7d97c5SJed 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]]); 2124*0c7d97c5SJed Brown //} 2125*0c7d97c5SJed Brown PetscInt nfc=0; 2126*0c7d97c5SJed Brown PetscInt nec=0; 2127*0c7d97c5SJed Brown PetscInt nvc=0; 2128*0c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 2129*0c7d97c5SJed Brown // sort each connected component (by local ordering) 2130*0c7d97c5SJed Brown ierr = PetscSortInt(mat_graph->cptr[i+1]-mat_graph->cptr[i],&mat_graph->queue[mat_graph->cptr[i]]);CHKERRQ(ierr); 2131*0c7d97c5SJed Brown // count edge and faces 2132*0c7d97c5SJed Brown if( !pcbddc->vertices_flag ) { 2133*0c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 2134*0c7d97c5SJed Brown if(mat_graph->count[mat_graph->queue[mat_graph->cptr[i]]]==2){ 2135*0c7d97c5SJed Brown nfc++; 2136*0c7d97c5SJed Brown } else { 2137*0c7d97c5SJed Brown nec++; 2138*0c7d97c5SJed Brown } 2139*0c7d97c5SJed Brown } 2140*0c7d97c5SJed Brown } 2141*0c7d97c5SJed Brown // count vertices 2142*0c7d97c5SJed Brown if( !pcbddc->constraints_flag ){ 2143*0c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] == 1 ){ 2144*0c7d97c5SJed Brown nvc++; 2145*0c7d97c5SJed Brown } 2146*0c7d97c5SJed Brown } 2147*0c7d97c5SJed Brown } 2148*0c7d97c5SJed Brown 2149*0c7d97c5SJed Brown pcbddc->n_constraints = nec+nfc; 2150*0c7d97c5SJed Brown pcbddc->n_vertices = nvc; 2151*0c7d97c5SJed Brown 2152*0c7d97c5SJed Brown if(pcbddc->n_constraints){ 2153*0c7d97c5SJed Brown /* allocate space for local constraints of BDDC */ 2154*0c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscInt*),&pcbddc->indices_to_constraint);CHKERRQ(ierr); 2155*0c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscScalar*),&pcbddc->quadrature_constraint);CHKERRQ(ierr); 2156*0c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_constraints*sizeof(PetscInt),&pcbddc->sizes_of_constraint);CHKERRQ(ierr); 2157*0c7d97c5SJed Brown k=0; 2158*0c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 2159*0c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 2160*0c7d97c5SJed Brown pcbddc->sizes_of_constraint[k] = mat_graph->cptr[i+1]-mat_graph->cptr[i]; 2161*0c7d97c5SJed Brown k++; 2162*0c7d97c5SJed Brown } 2163*0c7d97c5SJed Brown } 2164*0c7d97c5SJed Brown // printf("check constraints %d (should be %d)\n",k,pcbddc->n_constraints); 2165*0c7d97c5SJed Brown // for(i=0;i<k;i++) 2166*0c7d97c5SJed Brown // printf("%d ",pcbddc->sizes_of_constraint[i]); 2167*0c7d97c5SJed Brown // printf("\n"); 2168*0c7d97c5SJed Brown k=0; 2169*0c7d97c5SJed Brown for (i=0; i<pcbddc->n_constraints; i++) k+=pcbddc->sizes_of_constraint[i]; 2170*0c7d97c5SJed Brown ierr = PetscMalloc (k*sizeof(PetscInt),&pcbddc->indices_to_constraint[0]);CHKERRQ(ierr); 2171*0c7d97c5SJed Brown ierr = PetscMalloc (k*sizeof(PetscScalar),&pcbddc->quadrature_constraint[0]);CHKERRQ(ierr); 2172*0c7d97c5SJed Brown for (i=1; i<pcbddc->n_constraints; i++) { 2173*0c7d97c5SJed Brown pcbddc->indices_to_constraint[i] = pcbddc->indices_to_constraint[i-1] + pcbddc->sizes_of_constraint[i-1]; 2174*0c7d97c5SJed Brown pcbddc->quadrature_constraint[i] = pcbddc->quadrature_constraint[i-1] + pcbddc->sizes_of_constraint[i-1]; 2175*0c7d97c5SJed Brown } 2176*0c7d97c5SJed Brown k=0; 2177*0c7d97c5SJed Brown PetscScalar quad_value; 2178*0c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 2179*0c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] > 1 ){ 2180*0c7d97c5SJed Brown quad_value=1.0/( (PetscScalar) (mat_graph->cptr[i+1]-mat_graph->cptr[i]) ); 2181*0c7d97c5SJed Brown for(j=0;j<mat_graph->cptr[i+1]-mat_graph->cptr[i];j++) { 2182*0c7d97c5SJed Brown pcbddc->indices_to_constraint[k][j] = mat_graph->queue[mat_graph->cptr[i]+j]; 2183*0c7d97c5SJed Brown pcbddc->quadrature_constraint[k][j] = quad_value; 2184*0c7d97c5SJed Brown } 2185*0c7d97c5SJed Brown k++; 2186*0c7d97c5SJed Brown } 2187*0c7d97c5SJed Brown } 2188*0c7d97c5SJed Brown } 2189*0c7d97c5SJed Brown if(pcbddc->n_vertices){ 2190*0c7d97c5SJed Brown /* allocate space for local vertices of BDDC */ 2191*0c7d97c5SJed Brown ierr = PetscMalloc (pcbddc->n_vertices*sizeof(PetscInt),&pcbddc->vertices);CHKERRQ(ierr); 2192*0c7d97c5SJed Brown k=0; 2193*0c7d97c5SJed Brown for (i=0; i<mat_graph->ncmps; i++) { 2194*0c7d97c5SJed Brown if( mat_graph->cptr[i+1]-mat_graph->cptr[i] == 1 ){ 2195*0c7d97c5SJed Brown pcbddc->vertices[k] = mat_graph->queue[mat_graph->cptr[i]]; 2196*0c7d97c5SJed Brown k++; 2197*0c7d97c5SJed Brown } 2198*0c7d97c5SJed Brown } 2199*0c7d97c5SJed Brown // sort vertex set (by local ordering) 2200*0c7d97c5SJed Brown ierr = PetscSortInt(pcbddc->n_vertices,pcbddc->vertices);CHKERRQ(ierr); 2201*0c7d97c5SJed Brown } 2202*0c7d97c5SJed Brown 2203*0c7d97c5SJed Brown if(pcbddc->check_flag) { 2204*0c7d97c5SJed Brown PetscViewer viewer; 2205*0c7d97c5SJed Brown PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&viewer); 2206*0c7d97c5SJed Brown PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE); 2207*0c7d97c5SJed Brown PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n"); 2208*0c7d97c5SJed Brown PetscViewerASCIISynchronizedPrintf(viewer,"Details from PCBDDCManageLocalBoundaries for subdomain %04d\n",PetscGlobalRank); 2209*0c7d97c5SJed Brown PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n"); 2210*0c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"Graph (adjacency structure) of local Neumann mat\n"); 2211*0c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"--------------------------------------------------------------\n"); 2212*0c7d97c5SJed Brown // for(i=0;i<mat_graph->nvtxs;i++) { 2213*0c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"Nodes connected to node number %d are %d\n",i,mat_graph->xadj[i+1]-mat_graph->xadj[i]); 2214*0c7d97c5SJed Brown // for(j=mat_graph->xadj[i];j<mat_graph->xadj[i+1];j++){ 2215*0c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->adjncy[j]); 2216*0c7d97c5SJed Brown // } 2217*0c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n"); 2218*0c7d97c5SJed Brown // } 2219*0c7d97c5SJed Brown // TODO: APPLY Local to Global Mapping from IS object? 2220*0c7d97c5SJed Brown PetscViewerASCIISynchronizedPrintf(viewer,"Matrix graph has %d connected components", mat_graph->ncmps); 2221*0c7d97c5SJed Brown for(i=0;i<mat_graph->ncmps;i++) { 2222*0c7d97c5SJed Brown 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]]]); 2223*0c7d97c5SJed Brown for (j=mat_graph->cptr[i]; j<mat_graph->cptr[i+1]; j++){ 2224*0c7d97c5SJed Brown PetscViewerASCIISynchronizedPrintf(viewer,"%d ",mat_graph->queue[j]); 2225*0c7d97c5SJed Brown } 2226*0c7d97c5SJed Brown } 2227*0c7d97c5SJed Brown PetscViewerASCIISynchronizedPrintf(viewer,"\n--------------------------------------------------------------\n"); 2228*0c7d97c5SJed Brown if( pcbddc->n_vertices ) PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local vertices\n",PetscGlobalRank,pcbddc->n_vertices); 2229*0c7d97c5SJed Brown if( nfc ) PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local faces\n",PetscGlobalRank,nfc); 2230*0c7d97c5SJed Brown if( nec ) PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d detected %02d local edges\n",PetscGlobalRank,nec); 2231*0c7d97c5SJed Brown if( pcbddc->n_vertices ) PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain vertices follows\n",PetscGlobalRank,pcbddc->n_vertices); 2232*0c7d97c5SJed Brown for(i=0;i<pcbddc->n_vertices;i++){ 2233*0c7d97c5SJed Brown PetscViewerASCIISynchronizedPrintf(viewer,"%d ",pcbddc->vertices[i]); 2234*0c7d97c5SJed Brown } 2235*0c7d97c5SJed Brown if( pcbddc->n_vertices ) PetscViewerASCIISynchronizedPrintf(viewer,"\n"); 2236*0c7d97c5SJed Brown // if( pcbddc->n_constraints ) PetscViewerASCIISynchronizedPrintf(viewer,"Indices and quadrature constraints"); 2237*0c7d97c5SJed Brown // for(i=0;i<pcbddc->n_constraints;i++){ 2238*0c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"\nConstraint number %d\n",i); 2239*0c7d97c5SJed Brown // for(j=0;j<pcbddc->sizes_of_constraint[i];j++) { 2240*0c7d97c5SJed Brown // PetscViewerASCIISynchronizedPrintf(viewer,"(%d, %f) ",pcbddc->indices_to_constraint[i][j],pcbddc->quadrature_constraint[i][j]); 2241*0c7d97c5SJed Brown // } 2242*0c7d97c5SJed Brown // } 2243*0c7d97c5SJed Brown // if( pcbddc->n_constraints ) PetscViewerASCIISynchronizedPrintf(viewer,"\n"); 2244*0c7d97c5SJed Brown PetscViewerFlush(viewer); 2245*0c7d97c5SJed Brown } 2246*0c7d97c5SJed Brown 2247*0c7d97c5SJed Brown // Restore CSR structure into sequantial matrix and free memory space no longer needed 2248*0c7d97c5SJed Brown ierr = MatRestoreRowIJ(mat_adj,0,PETSC_FALSE,PETSC_TRUE,&mat_graph->nvtxs,&mat_graph->xadj,&mat_graph->adjncy,&flg_row);CHKERRQ(ierr); 2249*0c7d97c5SJed Brown ierr = MatDestroy(&mat_adj);CHKERRQ(ierr); 2250*0c7d97c5SJed Brown if(!flg_row) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in MatRestoreRowIJ called from PCBDDCManageLocalBoundaries.\n"); 2251*0c7d97c5SJed Brown ierr = PetscFree(distinct_values);CHKERRQ(ierr); 2252*0c7d97c5SJed Brown // Free graph structure 2253*0c7d97c5SJed Brown if(mat_graph->nvtxs){ 2254*0c7d97c5SJed Brown ierr = PetscFree(mat_graph->where);CHKERRQ(ierr); 2255*0c7d97c5SJed Brown ierr = PetscFree(mat_graph->touched);CHKERRQ(ierr); 2256*0c7d97c5SJed Brown ierr = PetscFree(mat_graph->which_dof);CHKERRQ(ierr); 2257*0c7d97c5SJed Brown ierr = PetscFree(mat_graph->queue);CHKERRQ(ierr); 2258*0c7d97c5SJed Brown ierr = PetscFree(mat_graph->cptr);CHKERRQ(ierr); 2259*0c7d97c5SJed Brown ierr = PetscFree(mat_graph->count);CHKERRQ(ierr); 2260*0c7d97c5SJed Brown } 2261*0c7d97c5SJed Brown ierr = PetscFree(mat_graph);CHKERRQ(ierr); 2262*0c7d97c5SJed Brown 2263*0c7d97c5SJed Brown PetscFunctionReturn(0); 2264*0c7d97c5SJed Brown 2265*0c7d97c5SJed Brown } 2266*0c7d97c5SJed Brown 2267*0c7d97c5SJed Brown /* -------------------------------------------------------------------------- */ 2268*0c7d97c5SJed Brown 2269*0c7d97c5SJed Brown /* The following code has been adapted from function IsConnectedSubdomain contained 2270*0c7d97c5SJed Brown in source file contig.c of METIS library (version 5.0.1) */ 2271*0c7d97c5SJed Brown 2272*0c7d97c5SJed Brown #undef __FUNCT__ 2273*0c7d97c5SJed Brown #define __FUNCT__ "PCBDDCFindConnectedComponents" 2274*0c7d97c5SJed Brown PetscErrorCode PCBDDCFindConnectedComponents(PCBDDCGraph graph, PetscInt n_dist, PetscInt *dist_vals) 2275*0c7d97c5SJed Brown { 2276*0c7d97c5SJed Brown PetscInt i, j, k, nvtxs, first, last, nleft, ncmps,pid,cum_queue,n,ncmps_pid; 2277*0c7d97c5SJed Brown PetscInt *xadj, *adjncy, *where, *queue; 2278*0c7d97c5SJed Brown PetscInt *cptr; 2279*0c7d97c5SJed Brown PetscBool *touched; 2280*0c7d97c5SJed Brown 2281*0c7d97c5SJed Brown PetscFunctionBegin; 2282*0c7d97c5SJed Brown 2283*0c7d97c5SJed Brown nvtxs = graph->nvtxs; 2284*0c7d97c5SJed Brown xadj = graph->xadj; 2285*0c7d97c5SJed Brown adjncy = graph->adjncy; 2286*0c7d97c5SJed Brown where = graph->where; 2287*0c7d97c5SJed Brown touched = graph->touched; 2288*0c7d97c5SJed Brown queue = graph->queue; 2289*0c7d97c5SJed Brown cptr = graph->cptr; 2290*0c7d97c5SJed Brown 2291*0c7d97c5SJed Brown for (i=0; i<nvtxs; i++) 2292*0c7d97c5SJed Brown touched[i] = PETSC_FALSE; 2293*0c7d97c5SJed Brown 2294*0c7d97c5SJed Brown cum_queue=0; 2295*0c7d97c5SJed Brown ncmps=0; 2296*0c7d97c5SJed Brown 2297*0c7d97c5SJed Brown for(n=0; n<n_dist; n++) { 2298*0c7d97c5SJed Brown 2299*0c7d97c5SJed Brown pid = dist_vals[n]; 2300*0c7d97c5SJed Brown nleft = 0; 2301*0c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 2302*0c7d97c5SJed Brown if (where[i] == pid) 2303*0c7d97c5SJed Brown nleft++; 2304*0c7d97c5SJed Brown } 2305*0c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 2306*0c7d97c5SJed Brown if (where[i] == pid) 2307*0c7d97c5SJed Brown break; 2308*0c7d97c5SJed Brown } 2309*0c7d97c5SJed Brown 2310*0c7d97c5SJed Brown touched[i] = PETSC_TRUE; 2311*0c7d97c5SJed Brown queue[cum_queue] = i; 2312*0c7d97c5SJed Brown first = 0; last = 1; 2313*0c7d97c5SJed Brown 2314*0c7d97c5SJed Brown cptr[ncmps] = cum_queue; /* This actually points to queue */ 2315*0c7d97c5SJed Brown ncmps_pid = 0; 2316*0c7d97c5SJed Brown while (first != nleft) { 2317*0c7d97c5SJed Brown if (first == last) { /* Find another starting vertex */ 2318*0c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 2319*0c7d97c5SJed Brown ncmps_pid++; 2320*0c7d97c5SJed Brown for (i=0; i<nvtxs; i++) { 2321*0c7d97c5SJed Brown if (where[i] == pid && !touched[i]) 2322*0c7d97c5SJed Brown break; 2323*0c7d97c5SJed Brown } 2324*0c7d97c5SJed Brown queue[cum_queue+last] = i; 2325*0c7d97c5SJed Brown last++; 2326*0c7d97c5SJed Brown touched[i] = PETSC_TRUE; 2327*0c7d97c5SJed Brown } 2328*0c7d97c5SJed Brown 2329*0c7d97c5SJed Brown i = queue[cum_queue+first]; 2330*0c7d97c5SJed Brown first++; 2331*0c7d97c5SJed Brown for (j=xadj[i]; j<xadj[i+1]; j++) { 2332*0c7d97c5SJed Brown k = adjncy[j]; 2333*0c7d97c5SJed Brown if (where[k] == pid && !touched[k]) { 2334*0c7d97c5SJed Brown queue[cum_queue+last] = k; 2335*0c7d97c5SJed Brown last++; 2336*0c7d97c5SJed Brown touched[k] = PETSC_TRUE; 2337*0c7d97c5SJed Brown } 2338*0c7d97c5SJed Brown } 2339*0c7d97c5SJed Brown } 2340*0c7d97c5SJed Brown cptr[++ncmps] = first+cum_queue; 2341*0c7d97c5SJed Brown ncmps_pid++; 2342*0c7d97c5SJed Brown cum_queue=cptr[ncmps]; 2343*0c7d97c5SJed Brown 2344*0c7d97c5SJed Brown //printf("The graph has %d connected components in partition %d\n", ncmps_pid, pid); 2345*0c7d97c5SJed Brown } 2346*0c7d97c5SJed Brown graph->ncmps = ncmps; 2347*0c7d97c5SJed Brown 2348*0c7d97c5SJed Brown PetscFunctionReturn(0); 2349*0c7d97c5SJed Brown } 2350*0c7d97c5SJed Brown 2351