1 #include <../src/ksp/pc/impls/bddc/bddc.h> 2 #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 3 4 /* prototypes for deluxe functions */ 5 static PetscErrorCode PCBDDCScalingCreate_Deluxe(PC); 6 static PetscErrorCode PCBDDCScalingDestroy_Deluxe(PC); 7 static PetscErrorCode PCBDDCScalingSetUp_Deluxe(PC); 8 static PetscErrorCode PCBDDCScalingSetUp_Deluxe_Private(PC); 9 static PetscErrorCode PCBDDCScalingReset_Deluxe_Solvers(PCBDDCDeluxeScaling); 10 11 #undef __FUNCT__ 12 #define __FUNCT__ "PCBDDCScalingExtension_Basic" 13 static PetscErrorCode PCBDDCScalingExtension_Basic(PC pc, Vec local_interface_vector, Vec global_vector) 14 { 15 PC_IS* pcis = (PC_IS*)pc->data; 16 PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 17 PetscErrorCode ierr; 18 19 PetscFunctionBegin; 20 /* Apply partition of unity */ 21 ierr = VecPointwiseMult(pcbddc->work_scaling,pcis->D,local_interface_vector);CHKERRQ(ierr); 22 ierr = VecSet(global_vector,0.0);CHKERRQ(ierr); 23 ierr = VecScatterBegin(pcis->global_to_B,pcbddc->work_scaling,global_vector,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 24 ierr = VecScatterEnd(pcis->global_to_B,pcbddc->work_scaling,global_vector,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 25 PetscFunctionReturn(0); 26 } 27 28 #undef __FUNCT__ 29 #define __FUNCT__ "PCBDDCScalingExtension_Deluxe" 30 static PetscErrorCode PCBDDCScalingExtension_Deluxe(PC pc, Vec x, Vec y) 31 { 32 PC_IS* pcis=(PC_IS*)pc->data; 33 PC_BDDC* pcbddc=(PC_BDDC*)pc->data; 34 PCBDDCDeluxeScaling deluxe_ctx = pcbddc->deluxe_ctx; 35 PetscErrorCode ierr; 36 37 PetscFunctionBegin; 38 ierr = VecSet(pcbddc->work_scaling,0.0);CHKERRQ(ierr); 39 ierr = VecSet(y,0.0);CHKERRQ(ierr); 40 if (deluxe_ctx->n_simple) { /* scale deluxe vertices using diagonal scaling */ 41 PetscInt i; 42 const PetscScalar *array_x,*array_D; 43 PetscScalar *array; 44 ierr = VecGetArrayRead(x,&array_x);CHKERRQ(ierr); 45 ierr = VecGetArrayRead(pcis->D,&array_D);CHKERRQ(ierr); 46 ierr = VecGetArray(pcbddc->work_scaling,&array);CHKERRQ(ierr); 47 for (i=0;i<deluxe_ctx->n_simple;i++) { 48 array[deluxe_ctx->idx_simple_B[i]] = array_x[deluxe_ctx->idx_simple_B[i]]*array_D[deluxe_ctx->idx_simple_B[i]]; 49 } 50 ierr = VecRestoreArray(pcbddc->work_scaling,&array);CHKERRQ(ierr); 51 ierr = VecRestoreArrayRead(pcis->D,&array_D);CHKERRQ(ierr); 52 ierr = VecRestoreArrayRead(x,&array_x);CHKERRQ(ierr); 53 } 54 /* sequential part : all problems and Schur applications collapsed into a single matrix vector multiplication or a matvec and a solve */ 55 if (deluxe_ctx->seq_mat) { 56 ierr = VecScatterBegin(deluxe_ctx->seq_scctx,x,deluxe_ctx->seq_work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 57 ierr = VecScatterEnd(deluxe_ctx->seq_scctx,x,deluxe_ctx->seq_work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 58 ierr = MatMultTranspose(deluxe_ctx->seq_mat,deluxe_ctx->seq_work1,deluxe_ctx->seq_work2);CHKERRQ(ierr); 59 if (deluxe_ctx->seq_ksp) { 60 ierr = KSPSolveTranspose(deluxe_ctx->seq_ksp,deluxe_ctx->seq_work2,deluxe_ctx->seq_work2);CHKERRQ(ierr); 61 } 62 ierr = VecScatterBegin(deluxe_ctx->seq_scctx,deluxe_ctx->seq_work2,pcbddc->work_scaling,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 63 ierr = VecScatterEnd(deluxe_ctx->seq_scctx,deluxe_ctx->seq_work2,pcbddc->work_scaling,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 64 } 65 /* put local boundary part in global vector */ 66 ierr = VecScatterBegin(pcis->global_to_B,pcbddc->work_scaling,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 67 ierr = VecScatterEnd(pcis->global_to_B,pcbddc->work_scaling,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 68 PetscFunctionReturn(0); 69 } 70 71 #undef __FUNCT__ 72 #define __FUNCT__ "PCBDDCScalingExtension" 73 PetscErrorCode PCBDDCScalingExtension(PC pc, Vec local_interface_vector, Vec global_vector) 74 { 75 PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 76 PetscErrorCode ierr; 77 78 PetscFunctionBegin; 79 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 80 PetscValidHeaderSpecific(local_interface_vector,VEC_CLASSID,2); 81 PetscValidHeaderSpecific(global_vector,VEC_CLASSID,3); 82 if (local_interface_vector == pcbddc->work_scaling) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local vector cannot be pcbddc->work_scaling!\n"); 83 ierr = PetscUseMethod(pc,"PCBDDCScalingExtension_C",(PC,Vec,Vec),(pc,local_interface_vector,global_vector));CHKERRQ(ierr); 84 PetscFunctionReturn(0); 85 } 86 87 #undef __FUNCT__ 88 #define __FUNCT__ "PCBDDCScalingRestriction_Basic" 89 static PetscErrorCode PCBDDCScalingRestriction_Basic(PC pc, Vec global_vector, Vec local_interface_vector) 90 { 91 PetscErrorCode ierr; 92 PC_IS *pcis = (PC_IS*)pc->data; 93 94 PetscFunctionBegin; 95 ierr = VecScatterBegin(pcis->global_to_B,global_vector,local_interface_vector,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 96 ierr = VecScatterEnd(pcis->global_to_B,global_vector,local_interface_vector,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 97 /* Apply partition of unity */ 98 ierr = VecPointwiseMult(local_interface_vector,pcis->D,local_interface_vector);CHKERRQ(ierr); 99 PetscFunctionReturn(0); 100 } 101 102 #undef __FUNCT__ 103 #define __FUNCT__ "PCBDDCScalingRestriction_Deluxe" 104 static PetscErrorCode PCBDDCScalingRestriction_Deluxe(PC pc, Vec x, Vec y) 105 { 106 PC_IS* pcis=(PC_IS*)pc->data; 107 PC_BDDC* pcbddc=(PC_BDDC*)pc->data; 108 PCBDDCDeluxeScaling deluxe_ctx = pcbddc->deluxe_ctx; 109 PetscErrorCode ierr; 110 111 PetscFunctionBegin; 112 /* get local boundary part of global vector */ 113 ierr = VecScatterBegin(pcis->global_to_B,x,y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 114 ierr = VecScatterEnd(pcis->global_to_B,x,y,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 115 if (deluxe_ctx->n_simple) { /* scale deluxe vertices using diagonal scaling */ 116 PetscInt i; 117 PetscScalar *array_y; 118 const PetscScalar *array_D; 119 ierr = VecGetArray(y,&array_y);CHKERRQ(ierr); 120 ierr = VecGetArrayRead(pcis->D,&array_D);CHKERRQ(ierr); 121 for (i=0;i<deluxe_ctx->n_simple;i++) { 122 array_y[deluxe_ctx->idx_simple_B[i]] *= array_D[deluxe_ctx->idx_simple_B[i]]; 123 } 124 ierr = VecRestoreArrayRead(pcis->D,&array_D);CHKERRQ(ierr); 125 ierr = VecRestoreArray(y,&array_y);CHKERRQ(ierr); 126 } 127 /* sequential part : all problems and Schur applications collapsed into a single matrix vector multiplication and ksp solution */ 128 if (deluxe_ctx->seq_mat) { 129 ierr = VecScatterBegin(deluxe_ctx->seq_scctx,y,deluxe_ctx->seq_work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 130 ierr = VecScatterEnd(deluxe_ctx->seq_scctx,y,deluxe_ctx->seq_work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 131 if (deluxe_ctx->seq_ksp) { 132 ierr = KSPSolve(deluxe_ctx->seq_ksp,deluxe_ctx->seq_work1,deluxe_ctx->seq_work1);CHKERRQ(ierr); 133 } 134 ierr = MatMult(deluxe_ctx->seq_mat,deluxe_ctx->seq_work1,deluxe_ctx->seq_work2);CHKERRQ(ierr); 135 ierr = VecScatterBegin(deluxe_ctx->seq_scctx,deluxe_ctx->seq_work2,y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 136 ierr = VecScatterEnd(deluxe_ctx->seq_scctx,deluxe_ctx->seq_work2,y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 137 } 138 PetscFunctionReturn(0); 139 } 140 141 #undef __FUNCT__ 142 #define __FUNCT__ "PCBDDCScalingRestriction" 143 PetscErrorCode PCBDDCScalingRestriction(PC pc, Vec global_vector, Vec local_interface_vector) 144 { 145 PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 146 PetscErrorCode ierr; 147 148 PetscFunctionBegin; 149 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 150 PetscValidHeaderSpecific(global_vector,VEC_CLASSID,2); 151 PetscValidHeaderSpecific(local_interface_vector,VEC_CLASSID,3); 152 if (local_interface_vector == pcbddc->work_scaling) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Local vector cannot be pcbddc->work_scaling!\n"); 153 ierr = PetscUseMethod(pc,"PCBDDCScalingRestriction_C",(PC,Vec,Vec),(pc,global_vector,local_interface_vector));CHKERRQ(ierr); 154 PetscFunctionReturn(0); 155 } 156 157 #undef __FUNCT__ 158 #define __FUNCT__ "PCBDDCScalingSetUp" 159 PetscErrorCode PCBDDCScalingSetUp(PC pc) 160 { 161 PC_IS* pcis=(PC_IS*)pc->data; 162 PC_BDDC* pcbddc=(PC_BDDC*)pc->data; 163 PetscErrorCode ierr; 164 165 PetscFunctionBegin; 166 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 167 /* create work vector for the operator */ 168 ierr = VecDestroy(&pcbddc->work_scaling);CHKERRQ(ierr); 169 ierr = VecDuplicate(pcis->vec1_B,&pcbddc->work_scaling);CHKERRQ(ierr); 170 /* always rebuild pcis->D */ 171 if (pcis->use_stiffness_scaling) { 172 ierr = MatGetDiagonal(pcbddc->local_mat,pcis->vec1_N);CHKERRQ(ierr); 173 ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 174 ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 175 } 176 ierr = VecCopy(pcis->D,pcis->vec1_B);CHKERRQ(ierr); 177 ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 178 ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 179 ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 180 ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 181 ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 182 ierr = VecPointwiseDivide(pcis->D,pcis->D,pcis->vec1_B);CHKERRQ(ierr); 183 /* now setup */ 184 if (pcbddc->use_deluxe_scaling) { 185 if (!pcbddc->deluxe_ctx) { 186 ierr = PCBDDCScalingCreate_Deluxe(pc);CHKERRQ(ierr); 187 } 188 ierr = PCBDDCScalingSetUp_Deluxe(pc);CHKERRQ(ierr); 189 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingRestriction_C",PCBDDCScalingRestriction_Deluxe);CHKERRQ(ierr); 190 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingExtension_C",PCBDDCScalingExtension_Deluxe);CHKERRQ(ierr); 191 } else { 192 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingRestriction_C",PCBDDCScalingRestriction_Basic);CHKERRQ(ierr); 193 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingExtension_C",PCBDDCScalingExtension_Basic);CHKERRQ(ierr); 194 } 195 196 /* test */ 197 if (pcbddc->dbg_flag) { 198 Vec vec2_global; 199 PetscViewer viewer=pcbddc->dbg_viewer; 200 PetscReal error; 201 202 /* extension -> from local to parallel */ 203 ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 204 ierr = VecSetRandom(pcis->vec1_B,NULL);CHKERRQ(ierr); 205 ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 206 ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 207 ierr = VecDuplicate(pcis->vec1_global,&vec2_global);CHKERRQ(ierr); 208 ierr = VecCopy(pcis->vec1_global,vec2_global);CHKERRQ(ierr); 209 210 ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 211 ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_global,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 212 ierr = PCBDDCScalingExtension(pc,pcis->vec1_B,pcis->vec1_global);CHKERRQ(ierr); 213 ierr = VecAXPY(pcis->vec1_global,-1.0,vec2_global);CHKERRQ(ierr); 214 ierr = VecNorm(pcis->vec1_global,NORM_INFINITY,&error);CHKERRQ(ierr); 215 ierr = PetscViewerASCIIPrintf(viewer,"Error scaling extension %1.14e\n",error);CHKERRQ(ierr); 216 if (error>1.e-8 && pcbddc->dbg_flag>1) { 217 ierr = VecView(pcis->vec1_global,viewer);CHKERRQ(ierr); 218 } 219 ierr = VecDestroy(&vec2_global);CHKERRQ(ierr); 220 221 /* restriction -> from parallel to local */ 222 ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 223 ierr = VecSetRandom(pcis->vec1_B,NULL);CHKERRQ(ierr); 224 ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 225 ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 226 227 ierr = PCBDDCScalingRestriction(pc,pcis->vec1_global,pcis->vec1_B);CHKERRQ(ierr); 228 ierr = VecScale(pcis->vec1_B,-1.0);CHKERRQ(ierr); 229 ierr = VecScatterBegin(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 230 ierr = VecScatterEnd(pcis->global_to_B,pcis->vec1_B,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 231 ierr = VecNorm(pcis->vec1_global,NORM_INFINITY,&error);CHKERRQ(ierr); 232 ierr = PetscViewerASCIIPrintf(viewer,"Error scaling restriction %1.14e\n",error);CHKERRQ(ierr); 233 if (error>1.e-8 && pcbddc->dbg_flag>1) { 234 ierr = VecView(pcis->vec1_global,viewer);CHKERRQ(ierr); 235 } 236 } 237 PetscFunctionReturn(0); 238 } 239 240 #undef __FUNCT__ 241 #define __FUNCT__ "PCBDDCScalingDestroy" 242 PetscErrorCode PCBDDCScalingDestroy(PC pc) 243 { 244 PC_BDDC* pcbddc=(PC_BDDC*)pc->data; 245 PetscErrorCode ierr; 246 247 PetscFunctionBegin; 248 if (pcbddc->deluxe_ctx) { 249 ierr = PCBDDCScalingDestroy_Deluxe(pc);CHKERRQ(ierr); 250 } 251 ierr = VecDestroy(&pcbddc->work_scaling);CHKERRQ(ierr); 252 /* remove functions */ 253 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingRestriction_C",NULL);CHKERRQ(ierr); 254 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCBDDCScalingExtension_C",NULL);CHKERRQ(ierr); 255 PetscFunctionReturn(0); 256 } 257 258 #undef __FUNCT__ 259 #define __FUNCT__ "PCBDDCScalingCreate_Deluxe" 260 static PetscErrorCode PCBDDCScalingCreate_Deluxe(PC pc) 261 { 262 PC_BDDC* pcbddc=(PC_BDDC*)pc->data; 263 PCBDDCDeluxeScaling deluxe_ctx; 264 PetscErrorCode ierr; 265 266 PetscFunctionBegin; 267 ierr = PetscNew(&deluxe_ctx);CHKERRQ(ierr); 268 pcbddc->deluxe_ctx = deluxe_ctx; 269 PetscFunctionReturn(0); 270 } 271 272 #undef __FUNCT__ 273 #define __FUNCT__ "PCBDDCScalingDestroy_Deluxe" 274 static PetscErrorCode PCBDDCScalingDestroy_Deluxe(PC pc) 275 { 276 PC_BDDC* pcbddc=(PC_BDDC*)pc->data; 277 PetscErrorCode ierr; 278 279 PetscFunctionBegin; 280 ierr = PCBDDCScalingReset_Deluxe_Solvers(pcbddc->deluxe_ctx);CHKERRQ(ierr); 281 ierr = PetscFree(pcbddc->deluxe_ctx);CHKERRQ(ierr); 282 PetscFunctionReturn(0); 283 } 284 285 #undef __FUNCT__ 286 #define __FUNCT__ "PCBDDCScalingReset_Deluxe_Solvers" 287 static PetscErrorCode PCBDDCScalingReset_Deluxe_Solvers(PCBDDCDeluxeScaling deluxe_ctx) 288 { 289 PetscErrorCode ierr; 290 291 PetscFunctionBegin; 292 ierr = PetscFree(deluxe_ctx->idx_simple_B);CHKERRQ(ierr); 293 deluxe_ctx->n_simple = 0; 294 ierr = VecScatterDestroy(&deluxe_ctx->seq_scctx);CHKERRQ(ierr); 295 ierr = VecDestroy(&deluxe_ctx->seq_work1);CHKERRQ(ierr); 296 ierr = VecDestroy(&deluxe_ctx->seq_work2);CHKERRQ(ierr); 297 ierr = MatDestroy(&deluxe_ctx->seq_mat);CHKERRQ(ierr); 298 ierr = KSPDestroy(&deluxe_ctx->seq_ksp);CHKERRQ(ierr); 299 PetscFunctionReturn(0); 300 } 301 302 #undef __FUNCT__ 303 #define __FUNCT__ "PCBDDCScalingSetUp_Deluxe" 304 static PetscErrorCode PCBDDCScalingSetUp_Deluxe(PC pc) 305 { 306 PC_IS *pcis=(PC_IS*)pc->data; 307 PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 308 PCBDDCDeluxeScaling deluxe_ctx=pcbddc->deluxe_ctx; 309 PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 310 PetscErrorCode ierr; 311 312 PetscFunctionBegin; 313 /* (TODO: reuse) throw away the solvers */ 314 ierr = PCBDDCScalingReset_Deluxe_Solvers(deluxe_ctx);CHKERRQ(ierr); 315 316 /* Compute data structures to solve sequential problems */ 317 ierr = PCBDDCScalingSetUp_Deluxe_Private(pc);CHKERRQ(ierr); 318 319 /* diagonal scaling on interface dofs not contained in cc */ 320 if (sub_schurs->is_vertices || sub_schurs->is_dir) { 321 PetscInt n_com,n_dir; 322 n_com = 0; 323 if (sub_schurs->is_vertices) { 324 ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_com);CHKERRQ(ierr); 325 } 326 n_dir = 0; 327 if (sub_schurs->is_dir) { 328 ierr = ISGetLocalSize(sub_schurs->is_dir,&n_dir);CHKERRQ(ierr); 329 } 330 deluxe_ctx->n_simple = n_dir + n_com; 331 ierr = PetscMalloc1(deluxe_ctx->n_simple,&deluxe_ctx->idx_simple_B);CHKERRQ(ierr); 332 if (sub_schurs->is_vertices) { 333 PetscInt nmap; 334 const PetscInt *idxs; 335 336 ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 337 ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_com,idxs,&nmap,deluxe_ctx->idx_simple_B);CHKERRQ(ierr); 338 if (nmap != n_com) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error when mapping simply scaled dofs (is_vertices)! %D != %D",nmap,n_com); 339 ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 340 } 341 if (sub_schurs->is_dir) { 342 PetscInt nmap; 343 const PetscInt *idxs; 344 345 ierr = ISGetIndices(sub_schurs->is_dir,&idxs);CHKERRQ(ierr); 346 ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_dir,idxs,&nmap,deluxe_ctx->idx_simple_B+n_com);CHKERRQ(ierr); 347 if (nmap != n_dir) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error when mapping simply scaled dofs (sub_schurs->is_dir)! %D != %D",nmap,n_dir); 348 ierr = ISRestoreIndices(sub_schurs->is_dir,&idxs);CHKERRQ(ierr); 349 } 350 ierr = PetscSortInt(deluxe_ctx->n_simple,deluxe_ctx->idx_simple_B);CHKERRQ(ierr); 351 } else { 352 deluxe_ctx->n_simple = 0; 353 deluxe_ctx->idx_simple_B = 0; 354 } 355 PetscFunctionReturn(0); 356 } 357 358 #undef __FUNCT__ 359 #define __FUNCT__ "PCBDDCScalingSetUp_Deluxe_Private" 360 static PetscErrorCode PCBDDCScalingSetUp_Deluxe_Private(PC pc) 361 { 362 PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 363 PCBDDCDeluxeScaling deluxe_ctx=pcbddc->deluxe_ctx; 364 PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 365 PetscErrorCode ierr; 366 367 PetscFunctionBegin; 368 if (!sub_schurs->n_subs) { 369 PetscFunctionReturn(0); 370 } 371 372 /* Create work vectors for sequential part of deluxe */ 373 ierr = MatCreateVecs(sub_schurs->S_Ej_all,&deluxe_ctx->seq_work1,&deluxe_ctx->seq_work2);CHKERRQ(ierr); 374 375 /* Compute deluxe sequential scatter */ 376 if (sub_schurs->reuse_mumps && !sub_schurs->is_dir) { 377 PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps; 378 ierr = PetscObjectReference((PetscObject)reuse_mumps->correction_scatter_B);CHKERRQ(ierr); 379 deluxe_ctx->seq_scctx = reuse_mumps->correction_scatter_B; 380 } else { 381 ierr = VecScatterCreate(pcbddc->work_scaling,sub_schurs->is_Ej_all,deluxe_ctx->seq_work1,NULL,&deluxe_ctx->seq_scctx);CHKERRQ(ierr); 382 } 383 384 /* Create Mat object for deluxe scaling */ 385 ierr = PetscObjectReference((PetscObject)sub_schurs->S_Ej_all);CHKERRQ(ierr); 386 deluxe_ctx->seq_mat = sub_schurs->S_Ej_all; 387 if (sub_schurs->sum_S_Ej_all) { /* if this matrix is present, then we need to create the KSP object to invert it */ 388 PC pc_temp; 389 MatSolverPackage solver=NULL; 390 char ksp_prefix[256]; 391 size_t len; 392 393 ierr = KSPCreate(PETSC_COMM_SELF,&deluxe_ctx->seq_ksp);CHKERRQ(ierr); 394 ierr = KSPSetOperators(deluxe_ctx->seq_ksp,sub_schurs->sum_S_Ej_all,sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 395 ierr = KSPSetType(deluxe_ctx->seq_ksp,KSPPREONLY);CHKERRQ(ierr); 396 ierr = KSPGetPC(deluxe_ctx->seq_ksp,&pc_temp);CHKERRQ(ierr); 397 ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 398 ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 399 ierr = PCFactorGetMatSolverPackage(pc_temp,(const MatSolverPackage*)&solver);CHKERRQ(ierr); 400 if (solver) { 401 PC new_pc; 402 PCType type; 403 404 ierr = PCGetType(pc_temp,&type);CHKERRQ(ierr); 405 ierr = KSPGetPC(deluxe_ctx->seq_ksp,&new_pc);CHKERRQ(ierr); 406 ierr = PCSetType(new_pc,type);CHKERRQ(ierr); 407 ierr = PCFactorSetMatSolverPackage(new_pc,solver);CHKERRQ(ierr); 408 } 409 ierr = PetscStrlen(((PetscObject)(pcbddc->ksp_D))->prefix,&len);CHKERRQ(ierr); 410 len -= 10; /* remove "dirichlet_" */ 411 ierr = PetscStrncpy(ksp_prefix,((PetscObject)(pcbddc->ksp_D))->prefix,len+1);CHKERRQ(ierr); 412 ierr = PetscStrcat(ksp_prefix,"deluxe_");CHKERRQ(ierr); 413 ierr = KSPSetOptionsPrefix(deluxe_ctx->seq_ksp,ksp_prefix);CHKERRQ(ierr); 414 ierr = KSPSetFromOptions(deluxe_ctx->seq_ksp);CHKERRQ(ierr); 415 ierr = KSPSetUp(deluxe_ctx->seq_ksp);CHKERRQ(ierr); 416 } 417 PetscFunctionReturn(0); 418 } 419