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