123ce1328SBarry Smith 2ccd284c7SBarry Smith #include "../src/ksp/pc/impls/is/pcis.h" /*I "petscpc.h" I*/ 3831a100dSStefano Zampini 4831a100dSStefano Zampini EXTERN_C_BEGIN 5831a100dSStefano Zampini #undef __FUNCT__ 6*ba1573a8SStefano Zampini #define __FUNCT__ "PCISSetSubdomainDiagonalScaling_IS" 7*ba1573a8SStefano Zampini static PetscErrorCode PCISSetSubdomainDiagonalScaling_IS(PC pc, Vec scaling_factors) 8*ba1573a8SStefano Zampini { 9*ba1573a8SStefano Zampini PetscErrorCode ierr; 10*ba1573a8SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 11*ba1573a8SStefano Zampini 12*ba1573a8SStefano Zampini PetscFunctionBegin; 13*ba1573a8SStefano Zampini ierr = VecDestroy(&pcis->D);CHKERRQ(ierr); 14*ba1573a8SStefano Zampini ierr = PetscObjectReference((PetscObject)scaling_factors);CHKERRQ(ierr); 15*ba1573a8SStefano Zampini pcis->D = scaling_factors; 16*ba1573a8SStefano Zampini PetscFunctionReturn(0); 17*ba1573a8SStefano Zampini } 18*ba1573a8SStefano Zampini EXTERN_C_END 19*ba1573a8SStefano Zampini 20*ba1573a8SStefano Zampini #undef __FUNCT__ 21*ba1573a8SStefano Zampini #define __FUNCT__ "PCISSetSubdomainDiagonalScaling" 22*ba1573a8SStefano Zampini /*@ 23*ba1573a8SStefano Zampini PCISSetSubdomainDiagonalScaling - Set diagonal scaling for PCIS. 24*ba1573a8SStefano Zampini 25*ba1573a8SStefano Zampini Not collective 26*ba1573a8SStefano Zampini 27*ba1573a8SStefano Zampini Input Parameters: 28*ba1573a8SStefano Zampini + pc - the preconditioning context 29*ba1573a8SStefano Zampini - scaling_factors - scaling factors for the subdomain 30*ba1573a8SStefano Zampini 31*ba1573a8SStefano Zampini Level: intermediate 32*ba1573a8SStefano Zampini 33*ba1573a8SStefano Zampini Notes: 34*ba1573a8SStefano Zampini Intended to use with jumping coefficients cases. 35*ba1573a8SStefano Zampini 36*ba1573a8SStefano Zampini .seealso: PCBDDC 37*ba1573a8SStefano Zampini @*/ 38*ba1573a8SStefano Zampini PetscErrorCode PCISSetSubdomainDiagonalScaling(PC pc, Vec scaling_factors) 39*ba1573a8SStefano Zampini { 40*ba1573a8SStefano Zampini PetscErrorCode ierr; 41*ba1573a8SStefano Zampini 42*ba1573a8SStefano Zampini PetscFunctionBegin; 43*ba1573a8SStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 44*ba1573a8SStefano Zampini ierr = PetscTryMethod(pc,"PCISSetSubdomainDiagonalScaling_C",(PC,Vec),(pc,scaling_factors));CHKERRQ(ierr); 45*ba1573a8SStefano Zampini PetscFunctionReturn(0); 46*ba1573a8SStefano Zampini } 47*ba1573a8SStefano Zampini 48*ba1573a8SStefano Zampini EXTERN_C_BEGIN 49*ba1573a8SStefano Zampini #undef __FUNCT__ 50831a100dSStefano Zampini #define __FUNCT__ "PCISSetSubdomainScalingFactor_IS" 51831a100dSStefano Zampini static PetscErrorCode PCISSetSubdomainScalingFactor_IS(PC pc, PetscScalar scal) 52831a100dSStefano Zampini { 53831a100dSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 54831a100dSStefano Zampini 55831a100dSStefano Zampini PetscFunctionBegin; 56831a100dSStefano Zampini pcis->scaling_factor = scal; 57831a100dSStefano Zampini PetscFunctionReturn(0); 58831a100dSStefano Zampini } 59831a100dSStefano Zampini EXTERN_C_END 60831a100dSStefano Zampini 61831a100dSStefano Zampini #undef __FUNCT__ 62831a100dSStefano Zampini #define __FUNCT__ "PCISSetSubdomainScalingFactor" 63831a100dSStefano Zampini /*@ 64831a100dSStefano Zampini PCISSetSubdomainScalingFactor - Set scaling factor for PCIS. 65831a100dSStefano Zampini 66831a100dSStefano Zampini Not collective 67831a100dSStefano Zampini 68831a100dSStefano Zampini Input Parameters: 69831a100dSStefano Zampini + pc - the preconditioning context 70831a100dSStefano Zampini - scal - scaling factor for the subdomain 71831a100dSStefano Zampini 72831a100dSStefano Zampini Level: intermediate 73831a100dSStefano Zampini 74831a100dSStefano Zampini Notes: 75831a100dSStefano Zampini Intended to use with jumping coefficients cases. 76831a100dSStefano Zampini 77831a100dSStefano Zampini .seealso: PCBDDC 78831a100dSStefano Zampini @*/ 79831a100dSStefano Zampini PetscErrorCode PCISSetSubdomainScalingFactor(PC pc, PetscScalar scal) 80831a100dSStefano Zampini { 81831a100dSStefano Zampini PetscErrorCode ierr; 82831a100dSStefano Zampini 83831a100dSStefano Zampini PetscFunctionBegin; 84831a100dSStefano Zampini PetscValidHeaderSpecific(pc,PC_CLASSID,1); 85831a100dSStefano Zampini ierr = PetscTryMethod(pc,"PCISSetSubdomainScalingFactor_C",(PC,PetscScalar),(pc,scal));CHKERRQ(ierr); 86831a100dSStefano Zampini PetscFunctionReturn(0); 87831a100dSStefano Zampini } 88831a100dSStefano Zampini 89b4319ba4SBarry Smith 90b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */ 91b4319ba4SBarry Smith /* 92b4319ba4SBarry Smith PCISSetUp - 93b4319ba4SBarry Smith */ 94b4319ba4SBarry Smith #undef __FUNCT__ 95b4319ba4SBarry Smith #define __FUNCT__ "PCISSetUp" 967087cfbeSBarry Smith PetscErrorCode PCISSetUp(PC pc) 97b4319ba4SBarry Smith { 98b4319ba4SBarry Smith PC_IS *pcis = (PC_IS*)(pc->data); 99b4319ba4SBarry Smith Mat_IS *matis = (Mat_IS*)pc->mat->data; 10013f74950SBarry Smith PetscInt i; 1016849ba73SBarry Smith PetscErrorCode ierr; 102ace3abfcSBarry Smith PetscBool flg; 103831a100dSStefano Zampini Vec counter; 104b4319ba4SBarry Smith 105b4319ba4SBarry Smith PetscFunctionBegin; 106251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc->mat,MATIS,&flg);CHKERRQ(ierr); 107e7e72b3dSBarry Smith if (!flg) SETERRQ(((PetscObject)pc)->comm,PETSC_ERR_ARG_WRONG,"Preconditioner type of Neumann Neumman requires matrix of type MATIS"); 108b4319ba4SBarry Smith 109b4319ba4SBarry Smith pcis->pure_neumann = matis->pure_neumann; 110b4319ba4SBarry Smith 111b4319ba4SBarry Smith /* 112b4319ba4SBarry Smith Creating the local vector vec1_N, containing the inverse of the number 113b4319ba4SBarry Smith of subdomains to which each local node (either owned or ghost) 114b4319ba4SBarry Smith pertains. To accomplish that, we scatter local vectors of 1's to 115b4319ba4SBarry Smith a global vector (adding the values); scatter the result back to 116b4319ba4SBarry Smith local vectors and finally invert the result. 117b4319ba4SBarry Smith */ 118b4319ba4SBarry Smith ierr = VecDuplicate(matis->x,&pcis->vec1_N);CHKERRQ(ierr); 11923ce1328SBarry Smith ierr = MatGetVecs(pc->pmat,&counter,0);CHKERRQ(ierr); /* temporary auxiliar vector */ 120efb30889SBarry Smith ierr = VecSet(counter,0.0);CHKERRQ(ierr); 121efb30889SBarry Smith ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 122ca9f406cSSatish Balay ierr = VecScatterBegin(matis->ctx,pcis->vec1_N,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 123ca9f406cSSatish Balay ierr = VecScatterEnd (matis->ctx,pcis->vec1_N,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 124ca9f406cSSatish Balay ierr = VecScatterBegin(matis->ctx,counter,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 125ca9f406cSSatish Balay ierr = VecScatterEnd (matis->ctx,counter,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 126b4319ba4SBarry Smith /* 127b4319ba4SBarry Smith Creating local and global index sets for interior and 128b4319ba4SBarry Smith inteface nodes. Notice that interior nodes have D[i]==1.0. 129b4319ba4SBarry Smith */ 130b4319ba4SBarry Smith { 13113f74950SBarry Smith PetscInt n_I; 13213f74950SBarry Smith PetscInt *idx_I_local,*idx_B_local,*idx_I_global,*idx_B_global; 133b4319ba4SBarry Smith PetscScalar *array; 134b4319ba4SBarry Smith /* Identifying interior and interface nodes, in local numbering */ 135b4319ba4SBarry Smith ierr = VecGetSize(pcis->vec1_N,&pcis->n);CHKERRQ(ierr); 136b4319ba4SBarry Smith ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 13713f74950SBarry Smith ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&idx_I_local);CHKERRQ(ierr); 13813f74950SBarry Smith ierr = PetscMalloc(pcis->n*sizeof(PetscInt),&idx_B_local);CHKERRQ(ierr); 139b4319ba4SBarry Smith for (i=0, pcis->n_B=0, n_I=0; i<pcis->n; i++) { 140b4319ba4SBarry Smith if (array[i] == 1.0) { idx_I_local[n_I] = i; n_I++; } 141b4319ba4SBarry Smith else { idx_B_local[pcis->n_B] = i; pcis->n_B++; } 142b4319ba4SBarry Smith } 143b4319ba4SBarry Smith /* Getting the global numbering */ 144b4319ba4SBarry Smith idx_B_global = idx_I_local + n_I; /* Just avoiding allocating extra memory, since we have vacant space */ 145b4319ba4SBarry Smith idx_I_global = idx_B_local + pcis->n_B; 146b4319ba4SBarry Smith ierr = ISLocalToGlobalMappingApply(matis->mapping,pcis->n_B,idx_B_local,idx_B_global);CHKERRQ(ierr); 147b4319ba4SBarry Smith ierr = ISLocalToGlobalMappingApply(matis->mapping,n_I, idx_I_local,idx_I_global);CHKERRQ(ierr); 148b4319ba4SBarry Smith /* Creating the index sets. */ 14970b3c8c7SBarry Smith ierr = ISCreateGeneral(MPI_COMM_SELF,pcis->n_B,idx_B_local,PETSC_COPY_VALUES, &pcis->is_B_local);CHKERRQ(ierr); 15070b3c8c7SBarry Smith ierr = ISCreateGeneral(MPI_COMM_SELF,pcis->n_B,idx_B_global,PETSC_COPY_VALUES,&pcis->is_B_global);CHKERRQ(ierr); 15170b3c8c7SBarry Smith ierr = ISCreateGeneral(MPI_COMM_SELF,n_I ,idx_I_local,PETSC_COPY_VALUES, &pcis->is_I_local);CHKERRQ(ierr); 15270b3c8c7SBarry Smith ierr = ISCreateGeneral(MPI_COMM_SELF,n_I ,idx_I_global,PETSC_COPY_VALUES,&pcis->is_I_global);CHKERRQ(ierr); 153b4319ba4SBarry Smith /* Freeing memory and restoring arrays */ 154b4319ba4SBarry Smith ierr = PetscFree(idx_B_local);CHKERRQ(ierr); 155b4319ba4SBarry Smith ierr = PetscFree(idx_I_local);CHKERRQ(ierr); 156b4319ba4SBarry Smith ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 157b4319ba4SBarry Smith } 158b4319ba4SBarry Smith 159b4319ba4SBarry Smith /* 160b4319ba4SBarry Smith Extracting the blocks A_II, A_BI, A_IB and A_BB from A. If the numbering 161b4319ba4SBarry Smith is such that interior nodes come first than the interface ones, we have 162b4319ba4SBarry Smith 163b4319ba4SBarry Smith [ | ] 164b4319ba4SBarry Smith [ A_II | A_IB ] 165b4319ba4SBarry Smith A = [ | ] 166b4319ba4SBarry Smith [-----------+------] 167b4319ba4SBarry Smith [ A_BI | A_BB ] 168b4319ba4SBarry Smith */ 169b4319ba4SBarry Smith 1704aa3045dSJed Brown ierr = MatGetSubMatrix(matis->A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_II);CHKERRQ(ierr); 1714aa3045dSJed Brown ierr = MatGetSubMatrix(matis->A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_IB);CHKERRQ(ierr); 1724aa3045dSJed Brown ierr = MatGetSubMatrix(matis->A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&pcis->A_BI);CHKERRQ(ierr); 1734aa3045dSJed Brown ierr = MatGetSubMatrix(matis->A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&pcis->A_BB);CHKERRQ(ierr); 174b4319ba4SBarry Smith 175b4319ba4SBarry Smith /* 176b4319ba4SBarry Smith Creating work vectors and arrays 177b4319ba4SBarry Smith */ 178b4319ba4SBarry Smith /* pcis->vec1_N has already been created */ 179b4319ba4SBarry Smith ierr = VecDuplicate(pcis->vec1_N,&pcis->vec2_N);CHKERRQ(ierr); 180b4319ba4SBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,pcis->n-pcis->n_B,&pcis->vec1_D);CHKERRQ(ierr); 181b4319ba4SBarry Smith ierr = VecDuplicate(pcis->vec1_D,&pcis->vec2_D);CHKERRQ(ierr); 182b4319ba4SBarry Smith ierr = VecDuplicate(pcis->vec1_D,&pcis->vec3_D);CHKERRQ(ierr); 183b4319ba4SBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,pcis->n_B,&pcis->vec1_B);CHKERRQ(ierr); 184b4319ba4SBarry Smith ierr = VecDuplicate(pcis->vec1_B,&pcis->vec2_B);CHKERRQ(ierr); 185b4319ba4SBarry Smith ierr = VecDuplicate(pcis->vec1_B,&pcis->vec3_B);CHKERRQ(ierr); 18623ce1328SBarry Smith ierr = MatGetVecs(pc->pmat,&pcis->vec1_global,0);CHKERRQ(ierr); 187b4319ba4SBarry Smith ierr = PetscMalloc((pcis->n)*sizeof(PetscScalar),&pcis->work_N);CHKERRQ(ierr); 188b4319ba4SBarry Smith 189b4319ba4SBarry Smith /* Creating the scatter contexts */ 19023ce1328SBarry Smith ierr = VecScatterCreate(pcis->vec1_global,pcis->is_I_global,pcis->vec1_D,(IS)0,&pcis->global_to_D);CHKERRQ(ierr); 191b4319ba4SBarry Smith ierr = VecScatterCreate(pcis->vec1_N,pcis->is_B_local,pcis->vec1_B,(IS)0,&pcis->N_to_B);CHKERRQ(ierr); 19223ce1328SBarry Smith ierr = VecScatterCreate(pcis->vec1_global,pcis->is_B_global,pcis->vec1_B,(IS)0,&pcis->global_to_B);CHKERRQ(ierr); 193b4319ba4SBarry Smith 194831a100dSStefano Zampini /* Creating scaling "matrix" D */ 195831a100dSStefano Zampini if( !pcis->D ) { 196*ba1573a8SStefano Zampini ierr = VecSet(pcis->vec1_B,pcis->scaling_factor);CHKERRQ(ierr); 197*ba1573a8SStefano Zampini } else { 198*ba1573a8SStefano Zampini ierr = VecCopy(pcis->D,pcis->vec1_B);CHKERRQ(ierr); 199*ba1573a8SStefano Zampini } 200831a100dSStefano Zampini ierr = VecSet(counter,0.0);CHKERRQ(ierr); 201*ba1573a8SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 202*ba1573a8SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,pcis->vec1_B,counter,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 203*ba1573a8SStefano Zampini ierr = VecScatterBegin(pcis->global_to_B,counter,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 204*ba1573a8SStefano Zampini ierr = VecScatterEnd (pcis->global_to_B,counter,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 205*ba1573a8SStefano Zampini if( !pcis->D ) { 206b4319ba4SBarry Smith ierr = VecDuplicate(pcis->vec1_B,&pcis->D);CHKERRQ(ierr); 207*ba1573a8SStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->D);CHKERRQ(ierr); 208b4319ba4SBarry Smith ierr = VecReciprocal(pcis->D);CHKERRQ(ierr); 209831a100dSStefano Zampini ierr = VecScale(pcis->D,pcis->scaling_factor);CHKERRQ(ierr); 210*ba1573a8SStefano Zampini } else { 211*ba1573a8SStefano Zampini ierr = VecPointwiseDivide(pcis->D,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 212831a100dSStefano Zampini } 213b4319ba4SBarry Smith 214b4319ba4SBarry Smith /* See historical note 01, at the bottom of this file. */ 215b4319ba4SBarry Smith 216b4319ba4SBarry Smith /* 217b4319ba4SBarry Smith Creating the KSP contexts for the local Dirichlet and Neumann problems. 218b4319ba4SBarry Smith */ 219b4319ba4SBarry Smith { 220b4319ba4SBarry Smith PC pc_ctx; 221b4319ba4SBarry Smith /* Dirichlet */ 222b4319ba4SBarry Smith ierr = KSPCreate(PETSC_COMM_SELF,&pcis->ksp_D);CHKERRQ(ierr); 2231cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)pcis->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 224b4319ba4SBarry Smith ierr = KSPSetOperators(pcis->ksp_D,pcis->A_II,pcis->A_II,SAME_PRECONDITIONER);CHKERRQ(ierr); 225b4319ba4SBarry Smith ierr = KSPSetOptionsPrefix(pcis->ksp_D,"is_localD_");CHKERRQ(ierr); 226b4319ba4SBarry Smith ierr = KSPGetPC(pcis->ksp_D,&pc_ctx);CHKERRQ(ierr); 227b4319ba4SBarry Smith ierr = PCSetType(pc_ctx,PCLU);CHKERRQ(ierr); 228b4319ba4SBarry Smith ierr = KSPSetType(pcis->ksp_D,KSPPREONLY);CHKERRQ(ierr); 229b4319ba4SBarry Smith ierr = KSPSetFromOptions(pcis->ksp_D);CHKERRQ(ierr); 230b4319ba4SBarry Smith /* the vectors in the following line are dummy arguments, just telling the KSP the vector size. Values are not used */ 231b4319ba4SBarry Smith ierr = KSPSetUp(pcis->ksp_D);CHKERRQ(ierr); 232b4319ba4SBarry Smith /* Neumann */ 233b4319ba4SBarry Smith ierr = KSPCreate(PETSC_COMM_SELF,&pcis->ksp_N);CHKERRQ(ierr); 2341cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)pcis->ksp_N,(PetscObject)pc,1);CHKERRQ(ierr); 235b4319ba4SBarry Smith ierr = KSPSetOperators(pcis->ksp_N,matis->A,matis->A,SAME_PRECONDITIONER);CHKERRQ(ierr); 236b4319ba4SBarry Smith ierr = KSPSetOptionsPrefix(pcis->ksp_N,"is_localN_");CHKERRQ(ierr); 237b4319ba4SBarry Smith ierr = KSPGetPC(pcis->ksp_N,&pc_ctx);CHKERRQ(ierr); 238b4319ba4SBarry Smith ierr = PCSetType(pc_ctx,PCLU);CHKERRQ(ierr); 239b4319ba4SBarry Smith ierr = KSPSetType(pcis->ksp_N,KSPPREONLY);CHKERRQ(ierr); 240b4319ba4SBarry Smith ierr = KSPSetFromOptions(pcis->ksp_N);CHKERRQ(ierr); 241b4319ba4SBarry Smith { 242ace3abfcSBarry Smith PetscBool damp_fixed = PETSC_FALSE, 24390d69ab7SBarry Smith remove_nullspace_fixed = PETSC_FALSE, 24490d69ab7SBarry Smith set_damping_factor_floating = PETSC_FALSE, 24590d69ab7SBarry Smith not_damp_floating = PETSC_FALSE, 24690d69ab7SBarry Smith not_remove_nullspace_floating = PETSC_FALSE; 247b4319ba4SBarry Smith PetscReal fixed_factor, 248b4319ba4SBarry Smith floating_factor; 249b4319ba4SBarry Smith 2507adad957SLisandro Dalcin ierr = PetscOptionsGetReal(((PetscObject)pc_ctx)->prefix,"-pc_is_damp_fixed",&fixed_factor,&damp_fixed);CHKERRQ(ierr); 251b4319ba4SBarry Smith if (!damp_fixed) { fixed_factor = 0.0; } 252acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_damp_fixed",&damp_fixed,PETSC_NULL);CHKERRQ(ierr); 253b4319ba4SBarry Smith 254acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_remove_nullspace_fixed",&remove_nullspace_fixed,PETSC_NULL);CHKERRQ(ierr); 255b4319ba4SBarry Smith 2567adad957SLisandro Dalcin ierr = PetscOptionsGetReal(((PetscObject)pc_ctx)->prefix,"-pc_is_set_damping_factor_floating", 257b4319ba4SBarry Smith &floating_factor,&set_damping_factor_floating);CHKERRQ(ierr); 258b4319ba4SBarry Smith if (!set_damping_factor_floating) { floating_factor = 0.0; } 259acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_set_damping_factor_floating",&set_damping_factor_floating,PETSC_NULL);CHKERRQ(ierr); 260b4319ba4SBarry Smith if (!set_damping_factor_floating) { floating_factor = 1.e-12; } 261b4319ba4SBarry Smith 262acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_not_damp_floating",¬_damp_floating,PETSC_NULL);CHKERRQ(ierr); 263b4319ba4SBarry Smith 264acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)pc_ctx)->prefix,"-pc_is_not_remove_nullspace_floating",¬_remove_nullspace_floating,PETSC_NULL);CHKERRQ(ierr); 265b4319ba4SBarry Smith 266b4319ba4SBarry Smith if (pcis->pure_neumann) { /* floating subdomain */ 267b4319ba4SBarry Smith if (!(not_damp_floating)) { 268c88783f4SHong Zhang ierr = PCFactorSetShiftType(pc_ctx,MAT_SHIFT_NONZERO);CHKERRQ(ierr); 269c88783f4SHong Zhang ierr = PCFactorSetShiftAmount(pc_ctx,floating_factor);CHKERRQ(ierr); 270b4319ba4SBarry Smith } 271b4319ba4SBarry Smith if (!(not_remove_nullspace_floating)){ 272b4319ba4SBarry Smith MatNullSpace nullsp; 273ee512c37SSatish Balay ierr = MatNullSpaceCreate(PETSC_COMM_SELF,PETSC_TRUE,0,PETSC_NULL,&nullsp);CHKERRQ(ierr); 274d8fd42c4SBarry Smith ierr = KSPSetNullSpace(pcis->ksp_N,nullsp);CHKERRQ(ierr); 275d34fcf5fSBarry Smith ierr = MatNullSpaceDestroy(&nullsp);CHKERRQ(ierr); 276b4319ba4SBarry Smith } 277b4319ba4SBarry Smith } else { /* fixed subdomain */ 278b4319ba4SBarry Smith if (damp_fixed) { 279c88783f4SHong Zhang ierr = PCFactorSetShiftType(pc_ctx,MAT_SHIFT_NONZERO);CHKERRQ(ierr); 280c88783f4SHong Zhang ierr = PCFactorSetShiftAmount(pc_ctx,floating_factor);CHKERRQ(ierr); 281b4319ba4SBarry Smith } 282b4319ba4SBarry Smith if (remove_nullspace_fixed) { 283b4319ba4SBarry Smith MatNullSpace nullsp; 284ee512c37SSatish Balay ierr = MatNullSpaceCreate(PETSC_COMM_SELF,PETSC_TRUE,0,PETSC_NULL,&nullsp);CHKERRQ(ierr); 285d8fd42c4SBarry Smith ierr = KSPSetNullSpace(pcis->ksp_N,nullsp);CHKERRQ(ierr); 286d34fcf5fSBarry Smith ierr = MatNullSpaceDestroy(&nullsp);CHKERRQ(ierr); 287b4319ba4SBarry Smith } 288b4319ba4SBarry Smith } 289b4319ba4SBarry Smith } 290b4319ba4SBarry Smith /* the vectors in the following line are dummy arguments, just telling the KSP the vector size. Values are not used */ 291b4319ba4SBarry Smith ierr = KSPSetUp(pcis->ksp_N);CHKERRQ(ierr); 292b4319ba4SBarry Smith } 293b4319ba4SBarry Smith 2947c334f02SBarry Smith ierr = ISLocalToGlobalMappingGetInfo(((Mat_IS*)(pc->mat->data))->mapping,&(pcis->n_neigh),&(pcis->neigh),&(pcis->n_shared),&(pcis->shared));CHKERRQ(ierr); 295b4319ba4SBarry Smith pcis->ISLocalToGlobalMappingGetInfoWasCalled = PETSC_TRUE; 296831a100dSStefano Zampini ierr = VecDestroy(&counter);CHKERRQ(ierr); 297b4319ba4SBarry Smith PetscFunctionReturn(0); 298b4319ba4SBarry Smith } 299b4319ba4SBarry Smith 300b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */ 301b4319ba4SBarry Smith /* 302b4319ba4SBarry Smith PCISDestroy - 303b4319ba4SBarry Smith */ 304b4319ba4SBarry Smith #undef __FUNCT__ 305b4319ba4SBarry Smith #define __FUNCT__ "PCISDestroy" 3067087cfbeSBarry Smith PetscErrorCode PCISDestroy(PC pc) 307b4319ba4SBarry Smith { 308b4319ba4SBarry Smith PC_IS *pcis = (PC_IS*)(pc->data); 309dfbe8321SBarry Smith PetscErrorCode ierr; 310b4319ba4SBarry Smith 311b4319ba4SBarry Smith PetscFunctionBegin; 312fcfd50ebSBarry Smith ierr = ISDestroy(&pcis->is_B_local);CHKERRQ(ierr); 313fcfd50ebSBarry Smith ierr = ISDestroy(&pcis->is_I_local);CHKERRQ(ierr); 314fcfd50ebSBarry Smith ierr = ISDestroy(&pcis->is_B_global);CHKERRQ(ierr); 315fcfd50ebSBarry Smith ierr = ISDestroy(&pcis->is_I_global);CHKERRQ(ierr); 316fcfd50ebSBarry Smith ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 317fcfd50ebSBarry Smith ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 318fcfd50ebSBarry Smith ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 319fcfd50ebSBarry Smith ierr = MatDestroy(&pcis->A_BB);CHKERRQ(ierr); 320fcfd50ebSBarry Smith ierr = VecDestroy(&pcis->D);CHKERRQ(ierr); 321fcfd50ebSBarry Smith ierr = KSPDestroy(&pcis->ksp_N);CHKERRQ(ierr); 322fcfd50ebSBarry Smith ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 323fcfd50ebSBarry Smith ierr = VecDestroy(&pcis->vec1_N);CHKERRQ(ierr); 324fcfd50ebSBarry Smith ierr = VecDestroy(&pcis->vec2_N);CHKERRQ(ierr); 325fcfd50ebSBarry Smith ierr = VecDestroy(&pcis->vec1_D);CHKERRQ(ierr); 326fcfd50ebSBarry Smith ierr = VecDestroy(&pcis->vec2_D);CHKERRQ(ierr); 327fcfd50ebSBarry Smith ierr = VecDestroy(&pcis->vec3_D);CHKERRQ(ierr); 328fcfd50ebSBarry Smith ierr = VecDestroy(&pcis->vec1_B);CHKERRQ(ierr); 329fcfd50ebSBarry Smith ierr = VecDestroy(&pcis->vec2_B);CHKERRQ(ierr); 330fcfd50ebSBarry Smith ierr = VecDestroy(&pcis->vec3_B);CHKERRQ(ierr); 331fcfd50ebSBarry Smith ierr = VecDestroy(&pcis->vec1_global);CHKERRQ(ierr); 332fcfd50ebSBarry Smith ierr = VecScatterDestroy(&pcis->global_to_D);CHKERRQ(ierr); 333fcfd50ebSBarry Smith ierr = VecScatterDestroy(&pcis->N_to_B);CHKERRQ(ierr); 334fcfd50ebSBarry Smith ierr = VecScatterDestroy(&pcis->global_to_B);CHKERRQ(ierr); 33505b42c5fSBarry Smith ierr = PetscFree(pcis->work_N);CHKERRQ(ierr); 336b4319ba4SBarry Smith if (pcis->ISLocalToGlobalMappingGetInfoWasCalled) { 337b4319ba4SBarry Smith ierr = ISLocalToGlobalMappingRestoreInfo((ISLocalToGlobalMapping)0,&(pcis->n_neigh),&(pcis->neigh),&(pcis->n_shared),&(pcis->shared));CHKERRQ(ierr); 338b4319ba4SBarry Smith } 339b4319ba4SBarry Smith PetscFunctionReturn(0); 340b4319ba4SBarry Smith } 341b4319ba4SBarry Smith 342b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */ 343b4319ba4SBarry Smith /* 344b4319ba4SBarry Smith PCISCreate - 345b4319ba4SBarry Smith */ 346b4319ba4SBarry Smith #undef __FUNCT__ 347b4319ba4SBarry Smith #define __FUNCT__ "PCISCreate" 3487087cfbeSBarry Smith PetscErrorCode PCISCreate(PC pc) 349b4319ba4SBarry Smith { 350b4319ba4SBarry Smith PC_IS *pcis = (PC_IS*)(pc->data); 351831a100dSStefano Zampini PetscErrorCode ierr; 352b4319ba4SBarry Smith 353b4319ba4SBarry Smith PetscFunctionBegin; 354b4319ba4SBarry Smith pcis->is_B_local = 0; 355b4319ba4SBarry Smith pcis->is_I_local = 0; 356b4319ba4SBarry Smith pcis->is_B_global = 0; 357b4319ba4SBarry Smith pcis->is_I_global = 0; 358b4319ba4SBarry Smith pcis->A_II = 0; 359b4319ba4SBarry Smith pcis->A_IB = 0; 360b4319ba4SBarry Smith pcis->A_BI = 0; 361b4319ba4SBarry Smith pcis->A_BB = 0; 362b4319ba4SBarry Smith pcis->D = 0; 363b4319ba4SBarry Smith pcis->ksp_N = 0; 364b4319ba4SBarry Smith pcis->ksp_D = 0; 365b4319ba4SBarry Smith pcis->vec1_N = 0; 366b4319ba4SBarry Smith pcis->vec2_N = 0; 367b4319ba4SBarry Smith pcis->vec1_D = 0; 368b4319ba4SBarry Smith pcis->vec2_D = 0; 369b4319ba4SBarry Smith pcis->vec3_D = 0; 370b4319ba4SBarry Smith pcis->vec1_B = 0; 371b4319ba4SBarry Smith pcis->vec2_B = 0; 372b4319ba4SBarry Smith pcis->vec3_B = 0; 373b4319ba4SBarry Smith pcis->vec1_global = 0; 374b4319ba4SBarry Smith pcis->work_N = 0; 375b4319ba4SBarry Smith pcis->global_to_D = 0; 376b4319ba4SBarry Smith pcis->N_to_B = 0; 377b4319ba4SBarry Smith pcis->global_to_B = 0; 378b4319ba4SBarry Smith pcis->ISLocalToGlobalMappingGetInfoWasCalled = PETSC_FALSE; 379831a100dSStefano Zampini pcis->scaling_factor = 1.0; 380831a100dSStefano Zampini /* composing functions */ 381831a100dSStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCISSetSubdomainScalingFactor_C","PCISSetSubdomainScalingFactor_IS", 382831a100dSStefano Zampini PCISSetSubdomainScalingFactor_IS);CHKERRQ(ierr); 383*ba1573a8SStefano Zampini ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCISSetSubdomainDiagonalScaling_C","PCISSetSubdomainDiagonalScaling_IS", 384*ba1573a8SStefano Zampini PCISSetSubdomainDiagonalScaling_IS);CHKERRQ(ierr); 385b4319ba4SBarry Smith PetscFunctionReturn(0); 386b4319ba4SBarry Smith } 387b4319ba4SBarry Smith 388b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */ 389b4319ba4SBarry Smith /* 390b4319ba4SBarry Smith PCISApplySchur - 391b4319ba4SBarry Smith 392b4319ba4SBarry Smith Input parameters: 393b4319ba4SBarry Smith . pc - preconditioner context 394b4319ba4SBarry Smith . v - vector to which the Schur complement is to be applied (it is NOT modified inside this function, UNLESS vec2_B is null) 395b4319ba4SBarry Smith 396b4319ba4SBarry Smith Output parameters: 397b4319ba4SBarry Smith . vec1_B - result of Schur complement applied to chunk 398b4319ba4SBarry Smith . vec2_B - garbage (used as work space), or null (and v is used as workspace) 399b4319ba4SBarry Smith . vec1_D - garbage (used as work space) 400b4319ba4SBarry Smith . vec2_D - garbage (used as work space) 401b4319ba4SBarry Smith 402b4319ba4SBarry Smith */ 403b4319ba4SBarry Smith #undef __FUNCT__ 404831a100dSStefano Zampini #define __FUNCT__ "PCISApplySchur" 4057087cfbeSBarry Smith PetscErrorCode PCISApplySchur(PC pc, Vec v, Vec vec1_B, Vec vec2_B, Vec vec1_D, Vec vec2_D) 406b4319ba4SBarry Smith { 407dfbe8321SBarry Smith PetscErrorCode ierr; 408b4319ba4SBarry Smith PC_IS *pcis = (PC_IS*)(pc->data); 409b4319ba4SBarry Smith 410b4319ba4SBarry Smith PetscFunctionBegin; 41113f74950SBarry Smith if (!vec2_B) { vec2_B = v; } 412b4319ba4SBarry Smith 413b4319ba4SBarry Smith ierr = MatMult(pcis->A_BB,v,vec1_B);CHKERRQ(ierr); 414b4319ba4SBarry Smith ierr = MatMult(pcis->A_IB,v,vec1_D);CHKERRQ(ierr); 41523ce1328SBarry Smith ierr = KSPSolve(pcis->ksp_D,vec1_D,vec2_D);CHKERRQ(ierr); 416b4319ba4SBarry Smith ierr = MatMult(pcis->A_BI,vec2_D,vec2_B);CHKERRQ(ierr); 417efb30889SBarry Smith ierr = VecAXPY(vec1_B,-1.0,vec2_B);CHKERRQ(ierr); 418b4319ba4SBarry Smith PetscFunctionReturn(0); 419b4319ba4SBarry Smith } 420b4319ba4SBarry Smith 421b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */ 422b4319ba4SBarry Smith /* 423b4319ba4SBarry Smith PCISScatterArrayNToVecB - Scatters interface node values from a big array (of all local nodes, interior or interface, 424b4319ba4SBarry Smith including ghosts) into an interface vector, when in SCATTER_FORWARD mode, or vice-versa, when in SCATTER_REVERSE 425b4319ba4SBarry Smith mode. 426b4319ba4SBarry Smith 427b4319ba4SBarry Smith Input parameters: 428b4319ba4SBarry Smith . pc - preconditioner context 429b4319ba4SBarry Smith . array_N - [when in SCATTER_FORWARD mode] Array to be scattered into the vector 430b4319ba4SBarry Smith . v_B - [when in SCATTER_REVERSE mode] Vector to be scattered into the array 431b4319ba4SBarry Smith 432b4319ba4SBarry Smith Output parameter: 433b4319ba4SBarry Smith . array_N - [when in SCATTER_REVERSE mode] Array to receive the scattered vector 434b4319ba4SBarry Smith . v_B - [when in SCATTER_FORWARD mode] Vector to receive the scattered array 435b4319ba4SBarry Smith 436b4319ba4SBarry Smith Notes: 437b4319ba4SBarry Smith The entries in the array that do not correspond to interface nodes remain unaltered. 438b4319ba4SBarry Smith */ 439b4319ba4SBarry Smith #undef __FUNCT__ 440b4319ba4SBarry Smith #define __FUNCT__ "PCISScatterArrayNToVecB" 4417087cfbeSBarry Smith PetscErrorCode PCISScatterArrayNToVecB (PetscScalar *array_N, Vec v_B, InsertMode imode, ScatterMode smode, PC pc) 442b4319ba4SBarry Smith { 4435d0c19d7SBarry Smith PetscInt i; 4445d0c19d7SBarry Smith const PetscInt *idex; 4456849ba73SBarry Smith PetscErrorCode ierr; 446b4319ba4SBarry Smith PetscScalar *array_B; 447b4319ba4SBarry Smith PC_IS *pcis = (PC_IS*)(pc->data); 448b4319ba4SBarry Smith 449b4319ba4SBarry Smith PetscFunctionBegin; 450b4319ba4SBarry Smith ierr = VecGetArray(v_B,&array_B);CHKERRQ(ierr); 451b4319ba4SBarry Smith ierr = ISGetIndices(pcis->is_B_local,&idex);CHKERRQ(ierr); 452b4319ba4SBarry Smith 453b4319ba4SBarry Smith if (smode == SCATTER_FORWARD) { 454b4319ba4SBarry Smith if (imode == INSERT_VALUES) { 455b4319ba4SBarry Smith for (i=0; i<pcis->n_B; i++) { array_B[i] = array_N[idex[i]]; } 456b4319ba4SBarry Smith } else { /* ADD_VALUES */ 457b4319ba4SBarry Smith for (i=0; i<pcis->n_B; i++) { array_B[i] += array_N[idex[i]]; } 458b4319ba4SBarry Smith } 459b4319ba4SBarry Smith } else { /* SCATTER_REVERSE */ 460b4319ba4SBarry Smith if (imode == INSERT_VALUES) { 461b4319ba4SBarry Smith for (i=0; i<pcis->n_B; i++) { array_N[idex[i]] = array_B[i]; } 462b4319ba4SBarry Smith } else { /* ADD_VALUES */ 463b4319ba4SBarry Smith for (i=0; i<pcis->n_B; i++) { array_N[idex[i]] += array_B[i]; } 464b4319ba4SBarry Smith } 465b4319ba4SBarry Smith } 466b4319ba4SBarry Smith ierr = ISRestoreIndices(pcis->is_B_local,&idex);CHKERRQ(ierr); 467b4319ba4SBarry Smith ierr = VecRestoreArray(v_B,&array_B);CHKERRQ(ierr); 468b4319ba4SBarry Smith PetscFunctionReturn(0); 469b4319ba4SBarry Smith } 470b4319ba4SBarry Smith 471b4319ba4SBarry Smith /* -------------------------------------------------------------------------- */ 472b4319ba4SBarry Smith /* 473b4319ba4SBarry Smith PCISApplyInvSchur - Solves the Neumann problem related to applying the inverse of the Schur complement. 474b4319ba4SBarry Smith More precisely, solves the problem: 475b4319ba4SBarry Smith [ A_II A_IB ] [ . ] [ 0 ] 476b4319ba4SBarry Smith [ ] [ ] = [ ] 477b4319ba4SBarry Smith [ A_BI A_BB ] [ x ] [ b ] 478b4319ba4SBarry Smith 479b4319ba4SBarry Smith Input parameters: 480b4319ba4SBarry Smith . pc - preconditioner context 481b4319ba4SBarry Smith . b - vector of local interface nodes (including ghosts) 482b4319ba4SBarry Smith 483b4319ba4SBarry Smith Output parameters: 484b4319ba4SBarry Smith . x - vector of local interface nodes (including ghosts); returns the application of the inverse of the Schur 485b4319ba4SBarry Smith complement to b 486b4319ba4SBarry Smith . vec1_N - vector of local nodes (interior and interface, including ghosts); returns garbage (used as work space) 487b4319ba4SBarry Smith . vec2_N - vector of local nodes (interior and interface, including ghosts); returns garbage (used as work space) 488b4319ba4SBarry Smith 489b4319ba4SBarry Smith */ 490b4319ba4SBarry Smith #undef __FUNCT__ 491b4319ba4SBarry Smith #define __FUNCT__ "PCISApplyInvSchur" 4927087cfbeSBarry Smith PetscErrorCode PCISApplyInvSchur (PC pc, Vec b, Vec x, Vec vec1_N, Vec vec2_N) 493b4319ba4SBarry Smith { 494dfbe8321SBarry Smith PetscErrorCode ierr; 495b4319ba4SBarry Smith PC_IS *pcis = (PC_IS*)(pc->data); 496b4319ba4SBarry Smith 497b4319ba4SBarry Smith PetscFunctionBegin; 498b4319ba4SBarry Smith /* 499b4319ba4SBarry Smith Neumann solvers. 500b4319ba4SBarry Smith Applying the inverse of the local Schur complement, i.e, solving a Neumann 501b4319ba4SBarry Smith Problem with zero at the interior nodes of the RHS and extracting the interface 502b4319ba4SBarry Smith part of the solution. inverse Schur complement is applied to b and the result 503b4319ba4SBarry Smith is stored in x. 504b4319ba4SBarry Smith */ 505b4319ba4SBarry Smith /* Setting the RHS vec1_N */ 506efb30889SBarry Smith ierr = VecSet(vec1_N,0.0);CHKERRQ(ierr); 507ca9f406cSSatish Balay ierr = VecScatterBegin(pcis->N_to_B,b,vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 508ca9f406cSSatish Balay ierr = VecScatterEnd (pcis->N_to_B,b,vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 509b4319ba4SBarry Smith /* Checking for consistency of the RHS */ 510b4319ba4SBarry Smith { 511ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 512acfcf0e5SJed Brown ierr = PetscOptionsGetBool(PETSC_NULL,"-pc_is_check_consistency",&flg,PETSC_NULL);CHKERRQ(ierr); 513b4319ba4SBarry Smith if (flg) { 514b4319ba4SBarry Smith PetscScalar average; 5153050cee2SBarry Smith PetscViewer viewer; 5167adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)pc)->comm,&viewer);CHKERRQ(ierr); 5173050cee2SBarry Smith 518b4319ba4SBarry Smith ierr = VecSum(vec1_N,&average);CHKERRQ(ierr); 519b4319ba4SBarry Smith average = average / ((PetscReal)pcis->n); 5207b23a99aSBarry Smith ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 521b4319ba4SBarry Smith if (pcis->pure_neumann) { 5229f73f8ecSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d is floating. Average = % 1.14e\n",PetscGlobalRank,PetscAbsScalar(average));CHKERRQ(ierr); 523b4319ba4SBarry Smith } else { 5249f73f8ecSBarry Smith ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Subdomain %04d is fixed. Average = % 1.14e\n",PetscGlobalRank,PetscAbsScalar(average));CHKERRQ(ierr); 525b4319ba4SBarry Smith } 5263050cee2SBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 5277b23a99aSBarry Smith ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 528b4319ba4SBarry Smith } 529b4319ba4SBarry Smith } 530b4319ba4SBarry Smith /* Solving the system for vec2_N */ 53123ce1328SBarry Smith ierr = KSPSolve(pcis->ksp_N,vec1_N,vec2_N);CHKERRQ(ierr); 532b4319ba4SBarry Smith /* Extracting the local interface vector out of the solution */ 533ca9f406cSSatish Balay ierr = VecScatterBegin(pcis->N_to_B,vec2_N,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 534ca9f406cSSatish Balay ierr = VecScatterEnd (pcis->N_to_B,vec2_N,x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 535b4319ba4SBarry Smith PetscFunctionReturn(0); 536b4319ba4SBarry Smith } 537b4319ba4SBarry Smith 538b4319ba4SBarry Smith 539b4319ba4SBarry Smith 540b4319ba4SBarry Smith 541b4319ba4SBarry Smith 542b4319ba4SBarry Smith 543b4319ba4SBarry Smith 544b4319ba4SBarry Smith 545b4319ba4SBarry Smith 546