1 2 /* 3 Provides the functions for index sets (IS) defined by a list of integers. 4 These are for blocks of data, each block is indicated with a single integer. 5 */ 6 #include <petsc/private/isimpl.h> /*I "petscis.h" I*/ 7 #include <petscvec.h> 8 #include <petscviewer.h> 9 10 typedef struct { 11 PetscBool sorted; /* are the blocks sorted? */ 12 PetscBool borrowed_indices; /* do not free indices when IS is destroyed */ 13 PetscInt *idx; 14 } IS_Block; 15 16 static PetscErrorCode ISDestroy_Block(IS is) 17 { 18 IS_Block *is_block = (IS_Block*)is->data; 19 PetscErrorCode ierr; 20 21 PetscFunctionBegin; 22 if (!is_block->borrowed_indices) { 23 ierr = PetscFree(is_block->idx);CHKERRQ(ierr); 24 } 25 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockSetIndices_C",0);CHKERRQ(ierr); 26 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetIndices_C",0);CHKERRQ(ierr); 27 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockRestoreIndices_C",0);CHKERRQ(ierr); 28 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetSize_C",0);CHKERRQ(ierr); 29 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetLocalSize_C",0);CHKERRQ(ierr); 30 ierr = PetscFree(is->data);CHKERRQ(ierr); 31 PetscFunctionReturn(0); 32 } 33 34 static PetscErrorCode ISLocate_Block(IS is,PetscInt key,PetscInt *location) 35 { 36 IS_Block *sub = (IS_Block*)is->data; 37 PetscInt numIdx, i, bs, bkey, mkey; 38 PetscErrorCode ierr; 39 40 PetscFunctionBegin; 41 ierr = PetscLayoutGetBlockSize(is->map,&bs);CHKERRQ(ierr); 42 ierr = PetscLayoutGetSize(is->map,&numIdx);CHKERRQ(ierr); 43 numIdx /= bs; 44 bkey = key / bs; 45 mkey = key % bs; 46 if (mkey < 0) { 47 bkey--; 48 mkey += bs; 49 } 50 if (sub->sorted) { 51 ierr = PetscFindInt(bkey,numIdx,sub->idx,location);CHKERRQ(ierr); 52 } else { 53 const PetscInt *idx = sub->idx; 54 55 *location = -1; 56 for (i = 0; i < numIdx; i++) { 57 if (idx[i] == bkey) { 58 *location = i; 59 break; 60 } 61 } 62 } 63 if (*location >= 0) { 64 *location = *location * bs + mkey; 65 } 66 PetscFunctionReturn(0); 67 } 68 69 static PetscErrorCode ISGetIndices_Block(IS in,const PetscInt *idx[]) 70 { 71 IS_Block *sub = (IS_Block*)in->data; 72 PetscErrorCode ierr; 73 PetscInt i,j,k,bs,n,*ii,*jj; 74 75 PetscFunctionBegin; 76 ierr = PetscLayoutGetBlockSize(in->map, &bs);CHKERRQ(ierr); 77 ierr = PetscLayoutGetLocalSize(in->map, &n);CHKERRQ(ierr); 78 n /= bs; 79 if (bs == 1) *idx = sub->idx; 80 else { 81 ierr = PetscMalloc1(bs*n,&jj);CHKERRQ(ierr); 82 *idx = jj; 83 k = 0; 84 ii = sub->idx; 85 for (i=0; i<n; i++) 86 for (j=0; j<bs; j++) 87 jj[k++] = bs*ii[i] + j; 88 } 89 PetscFunctionReturn(0); 90 } 91 92 static PetscErrorCode ISRestoreIndices_Block(IS is,const PetscInt *idx[]) 93 { 94 IS_Block *sub = (IS_Block*)is->data; 95 PetscInt bs; 96 PetscErrorCode ierr; 97 98 PetscFunctionBegin; 99 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 100 if (bs != 1) { 101 ierr = PetscFree(*(void**)idx);CHKERRQ(ierr); 102 } else { 103 if (*idx != sub->idx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Must restore with value from ISGetIndices()"); 104 } 105 PetscFunctionReturn(0); 106 } 107 108 static PetscErrorCode ISGetSize_Block(IS is,PetscInt *size) 109 { 110 PetscErrorCode ierr; 111 112 PetscFunctionBegin; 113 ierr = PetscLayoutGetSize(is->map, size);CHKERRQ(ierr); 114 PetscFunctionReturn(0); 115 } 116 117 static PetscErrorCode ISGetLocalSize_Block(IS is,PetscInt *size) 118 { 119 PetscErrorCode ierr; 120 121 PetscFunctionBegin; 122 ierr = PetscLayoutGetLocalSize(is->map, size);CHKERRQ(ierr); 123 PetscFunctionReturn(0); 124 } 125 126 static PetscErrorCode ISInvertPermutation_Block(IS is,PetscInt nlocal,IS *isout) 127 { 128 IS_Block *sub = (IS_Block*)is->data; 129 PetscInt i,*ii,bs,n,*idx = sub->idx; 130 PetscMPIInt size; 131 PetscErrorCode ierr; 132 133 PetscFunctionBegin; 134 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)is),&size);CHKERRQ(ierr); 135 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 136 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 137 n /= bs; 138 if (size == 1) { 139 ierr = PetscMalloc1(n,&ii);CHKERRQ(ierr); 140 for (i=0; i<n; i++) ii[idx[i]] = i; 141 ierr = ISCreateBlock(PETSC_COMM_SELF,bs,n,ii,PETSC_OWN_POINTER,isout);CHKERRQ(ierr); 142 ierr = ISSetPermutation(*isout);CHKERRQ(ierr); 143 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No inversion written yet for block IS"); 144 PetscFunctionReturn(0); 145 } 146 147 static PetscErrorCode ISView_Block(IS is, PetscViewer viewer) 148 { 149 IS_Block *sub = (IS_Block*)is->data; 150 PetscErrorCode ierr; 151 PetscInt i,bs,n,*idx = sub->idx; 152 PetscBool iascii; 153 154 PetscFunctionBegin; 155 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 156 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 157 n /= bs; 158 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 159 if (iascii) { 160 ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 161 if (is->isperm) { 162 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Block Index set is permutation\n");CHKERRQ(ierr); 163 } 164 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Block size %D\n",bs);CHKERRQ(ierr); 165 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Number of block indices in set %D\n",n);CHKERRQ(ierr); 166 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"The first indices of each block are\n");CHKERRQ(ierr); 167 for (i=0; i<n; i++) { 168 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"Block %D Index %D\n",i,idx[i]);CHKERRQ(ierr); 169 } 170 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 171 ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 172 } 173 PetscFunctionReturn(0); 174 } 175 176 static PetscErrorCode ISSort_Block(IS is) 177 { 178 IS_Block *sub = (IS_Block*)is->data; 179 PetscInt bs, n; 180 PetscErrorCode ierr; 181 182 PetscFunctionBegin; 183 if (sub->sorted) PetscFunctionReturn(0); 184 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 185 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 186 ierr = PetscSortInt(n/bs,sub->idx);CHKERRQ(ierr); 187 sub->sorted = PETSC_TRUE; 188 PetscFunctionReturn(0); 189 } 190 191 static PetscErrorCode ISSortRemoveDups_Block(IS is) 192 { 193 IS_Block *sub = (IS_Block*)is->data; 194 PetscInt bs, n, nb; 195 PetscErrorCode ierr; 196 197 PetscFunctionBegin; 198 if (sub->sorted) PetscFunctionReturn(0); 199 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 200 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 201 nb = n/bs; 202 ierr = PetscSortRemoveDupsInt(&nb,sub->idx);CHKERRQ(ierr); 203 ierr = PetscLayoutSetLocalSize(is->map, nb*bs);CHKERRQ(ierr); 204 sub->sorted = PETSC_TRUE; 205 PetscFunctionReturn(0); 206 } 207 208 static PetscErrorCode ISSorted_Block(IS is,PetscBool *flg) 209 { 210 IS_Block *sub = (IS_Block*)is->data; 211 212 PetscFunctionBegin; 213 *flg = sub->sorted; 214 PetscFunctionReturn(0); 215 } 216 217 static PetscErrorCode ISDuplicate_Block(IS is,IS *newIS) 218 { 219 PetscErrorCode ierr; 220 IS_Block *sub = (IS_Block*)is->data; 221 PetscInt bs, n; 222 223 PetscFunctionBegin; 224 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 225 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 226 n /= bs; 227 ierr = ISCreateBlock(PetscObjectComm((PetscObject)is),bs,n,sub->idx,PETSC_COPY_VALUES,newIS);CHKERRQ(ierr); 228 PetscFunctionReturn(0); 229 } 230 231 static PetscErrorCode ISIdentity_Block(IS is,PetscBool *ident) 232 { 233 IS_Block *is_block = (IS_Block*)is->data; 234 PetscInt i,bs,n,*idx = is_block->idx; 235 PetscErrorCode ierr; 236 237 PetscFunctionBegin; 238 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 239 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 240 n /= bs; 241 is->isidentity = PETSC_TRUE; 242 *ident = PETSC_TRUE; 243 for (i=0; i<n; i++) { 244 if (idx[i] != i) { 245 is->isidentity = PETSC_FALSE; 246 *ident = PETSC_FALSE; 247 PetscFunctionReturn(0); 248 } 249 } 250 PetscFunctionReturn(0); 251 } 252 253 static PetscErrorCode ISCopy_Block(IS is,IS isy) 254 { 255 IS_Block *is_block = (IS_Block*)is->data,*isy_block = (IS_Block*)isy->data; 256 PetscInt bs, n, N, bsy, ny, Ny; 257 PetscErrorCode ierr; 258 259 PetscFunctionBegin; 260 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 261 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 262 ierr = PetscLayoutGetSize(is->map, &N);CHKERRQ(ierr); 263 ierr = PetscLayoutGetBlockSize(isy->map, &bsy);CHKERRQ(ierr); 264 ierr = PetscLayoutGetLocalSize(isy->map, &ny);CHKERRQ(ierr); 265 ierr = PetscLayoutGetSize(isy->map, &Ny);CHKERRQ(ierr); 266 if (n != ny || N != Ny || bs != bsy) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Index sets incompatible"); 267 isy_block->sorted = is_block->sorted; 268 ierr = PetscMemcpy(isy_block->idx,is_block->idx,(n/bs)*sizeof(PetscInt));CHKERRQ(ierr); 269 PetscFunctionReturn(0); 270 } 271 272 static PetscErrorCode ISOnComm_Block(IS is,MPI_Comm comm,PetscCopyMode mode,IS *newis) 273 { 274 PetscErrorCode ierr; 275 IS_Block *sub = (IS_Block*)is->data; 276 PetscInt bs, n; 277 278 PetscFunctionBegin; 279 if (mode == PETSC_OWN_POINTER) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Cannot use PETSC_OWN_POINTER"); 280 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 281 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 282 ierr = ISCreateBlock(comm,bs,n/bs,sub->idx,mode,newis);CHKERRQ(ierr); 283 PetscFunctionReturn(0); 284 } 285 286 static PetscErrorCode ISSetBlockSize_Block(IS is,PetscInt bs) 287 { 288 PetscErrorCode ierr; 289 290 PetscFunctionBegin; 291 ierr = PetscLayoutSetBlockSize(is->map, bs);CHKERRQ(ierr); 292 PetscFunctionReturn(0); 293 } 294 295 static PetscErrorCode ISToGeneral_Block(IS inis) 296 { 297 IS_Block *sub = (IS_Block*)inis->data; 298 PetscInt bs,n; 299 const PetscInt *idx; 300 PetscErrorCode ierr; 301 302 PetscFunctionBegin; 303 ierr = ISGetBlockSize(inis,&bs);CHKERRQ(ierr); 304 ierr = ISGetLocalSize(inis,&n);CHKERRQ(ierr); 305 ierr = ISGetIndices(inis,&idx);CHKERRQ(ierr); 306 if (bs == 1) { 307 PetscCopyMode mode = sub->borrowed_indices ? PETSC_USE_POINTER : PETSC_OWN_POINTER; 308 sub->borrowed_indices = PETSC_TRUE; /* prevent deallocation when changing the subtype*/ 309 ierr = ISSetType(inis,ISGENERAL);CHKERRQ(ierr); 310 ierr = ISGeneralSetIndices(inis,n,idx,mode);CHKERRQ(ierr); 311 } else { 312 ierr = ISSetType(inis,ISGENERAL);CHKERRQ(ierr); 313 ierr = ISGeneralSetIndices(inis,n,idx,PETSC_OWN_POINTER);CHKERRQ(ierr); 314 } 315 PetscFunctionReturn(0); 316 } 317 318 319 static struct _ISOps myops = { ISGetSize_Block, 320 ISGetLocalSize_Block, 321 ISGetIndices_Block, 322 ISRestoreIndices_Block, 323 ISInvertPermutation_Block, 324 ISSort_Block, 325 ISSortRemoveDups_Block, 326 ISSorted_Block, 327 ISDuplicate_Block, 328 ISDestroy_Block, 329 ISView_Block, 330 ISLoad_Default, 331 ISIdentity_Block, 332 ISCopy_Block, 333 ISToGeneral_Block, 334 ISOnComm_Block, 335 ISSetBlockSize_Block, 336 0, 337 ISLocate_Block}; 338 339 /*@ 340 ISBlockSetIndices - The indices are relative to entries, not blocks. 341 342 Collective on IS 343 344 Input Parameters: 345 + is - the index set 346 . bs - number of elements in each block, one for each block and count of block not indices 347 . n - the length of the index set (the number of blocks) 348 . idx - the list of integers, these are by block, not by location 349 + mode - see PetscCopyMode, only PETSC_COPY_VALUES and PETSC_OWN_POINTER are supported 350 351 352 Notes: 353 When the communicator is not MPI_COMM_SELF, the operations on the 354 index sets, IS, are NOT conceptually the same as MPI_Group operations. 355 The index sets are then distributed sets of indices and thus certain operations 356 on them are collective. 357 358 Example: 359 If you wish to index the values {0,1,4,5}, then use 360 a block size of 2 and idx of {0,2}. 361 362 Level: beginner 363 364 Concepts: IS^block 365 Concepts: index sets^block 366 Concepts: block^index set 367 368 .seealso: ISCreateStride(), ISCreateGeneral(), ISAllGather() 369 @*/ 370 PetscErrorCode ISBlockSetIndices(IS is,PetscInt bs,PetscInt n,const PetscInt idx[],PetscCopyMode mode) 371 { 372 PetscErrorCode ierr; 373 374 PetscFunctionBegin; 375 ierr = PetscUseMethod(is,"ISBlockSetIndices_C",(IS,PetscInt,PetscInt,const PetscInt[],PetscCopyMode),(is,bs,n,idx,mode));CHKERRQ(ierr); 376 PetscFunctionReturn(0); 377 } 378 379 static PetscErrorCode ISBlockSetIndices_Block(IS is,PetscInt bs,PetscInt n,const PetscInt idx[],PetscCopyMode mode) 380 { 381 PetscErrorCode ierr; 382 PetscInt i,min,max; 383 IS_Block *sub = (IS_Block*)is->data; 384 PetscBool sorted = PETSC_TRUE; 385 386 PetscFunctionBegin; 387 if (!sub->borrowed_indices) { 388 ierr = PetscFree(sub->idx);CHKERRQ(ierr); 389 } else { 390 sub->borrowed_indices = PETSC_FALSE; 391 } 392 ierr = PetscLayoutSetLocalSize(is->map, n*bs);CHKERRQ(ierr); 393 ierr = PetscLayoutSetBlockSize(is->map, bs);CHKERRQ(ierr); 394 ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); 395 for (i=1; i<n; i++) { 396 if (idx[i] < idx[i-1]) {sorted = PETSC_FALSE; break;} 397 } 398 if (n) { 399 min = max = idx[0]; 400 } else { 401 min = -1; 402 max = -2; 403 } 404 for (i=1; i<n; i++) { 405 if (idx[i] < min) min = idx[i]; 406 if (idx[i] > max) max = idx[i]; 407 } 408 if (mode == PETSC_COPY_VALUES) { 409 ierr = PetscMalloc1(n,&sub->idx);CHKERRQ(ierr); 410 ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); 411 ierr = PetscMemcpy(sub->idx,idx,n*sizeof(PetscInt));CHKERRQ(ierr); 412 } else if (mode == PETSC_OWN_POINTER) { 413 sub->idx = (PetscInt*) idx; 414 ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); 415 } else if (mode == PETSC_USE_POINTER) { 416 sub->idx = (PetscInt*) idx; 417 sub->borrowed_indices = PETSC_TRUE; 418 } 419 420 sub->sorted = sorted; 421 is->min = bs*min; 422 is->max = bs*max+bs-1; 423 is->data = (void*)sub; 424 ierr = PetscMemcpy(is->ops,&myops,sizeof(myops));CHKERRQ(ierr); 425 is->isperm = PETSC_FALSE; 426 PetscFunctionReturn(0); 427 } 428 429 /*@ 430 ISCreateBlock - Creates a data structure for an index set containing 431 a list of integers. The indices are relative to entries, not blocks. 432 433 Collective on MPI_Comm 434 435 Input Parameters: 436 + comm - the MPI communicator 437 . bs - number of elements in each block 438 . n - the length of the index set (the number of blocks) 439 . idx - the list of integers, one for each block and count of block not indices 440 - mode - see PetscCopyMode, only PETSC_COPY_VALUES and PETSC_OWN_POINTER are supported in this routine 441 442 Output Parameter: 443 . is - the new index set 444 445 Notes: 446 When the communicator is not MPI_COMM_SELF, the operations on the 447 index sets, IS, are NOT conceptually the same as MPI_Group operations. 448 The index sets are then distributed sets of indices and thus certain operations 449 on them are collective. 450 451 Example: 452 If you wish to index the values {0,1,6,7}, then use 453 a block size of 2 and idx of {0,3}. 454 455 Level: beginner 456 457 Concepts: IS^block 458 Concepts: index sets^block 459 Concepts: block^index set 460 461 .seealso: ISCreateStride(), ISCreateGeneral(), ISAllGather() 462 @*/ 463 PetscErrorCode ISCreateBlock(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt idx[],PetscCopyMode mode,IS *is) 464 { 465 PetscErrorCode ierr; 466 467 PetscFunctionBegin; 468 PetscValidPointer(is,5); 469 if (n < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"length < 0"); 470 if (n) PetscValidIntPointer(idx,4); 471 472 ierr = ISCreate(comm,is);CHKERRQ(ierr); 473 ierr = ISSetType(*is,ISBLOCK);CHKERRQ(ierr); 474 ierr = ISBlockSetIndices(*is,bs,n,idx,mode);CHKERRQ(ierr); 475 PetscFunctionReturn(0); 476 } 477 478 static PetscErrorCode ISBlockGetIndices_Block(IS is,const PetscInt *idx[]) 479 { 480 IS_Block *sub = (IS_Block*)is->data; 481 482 PetscFunctionBegin; 483 *idx = sub->idx; 484 PetscFunctionReturn(0); 485 } 486 487 static PetscErrorCode ISBlockRestoreIndices_Block(IS is,const PetscInt *idx[]) 488 { 489 PetscFunctionBegin; 490 PetscFunctionReturn(0); 491 } 492 493 /*@C 494 ISBlockGetIndices - Gets the indices associated with each block. 495 496 Not Collective 497 498 Input Parameter: 499 . is - the index set 500 501 Output Parameter: 502 . idx - the integer indices, one for each block and count of block not indices 503 504 Level: intermediate 505 506 Concepts: IS^block 507 Concepts: index sets^getting indices 508 Concepts: index sets^block 509 510 .seealso: ISGetIndices(), ISBlockRestoreIndices() 511 @*/ 512 PetscErrorCode ISBlockGetIndices(IS is,const PetscInt *idx[]) 513 { 514 PetscErrorCode ierr; 515 516 PetscFunctionBegin; 517 ierr = PetscUseMethod(is,"ISBlockGetIndices_C",(IS,const PetscInt*[]),(is,idx));CHKERRQ(ierr); 518 PetscFunctionReturn(0); 519 } 520 521 /*@C 522 ISBlockRestoreIndices - Restores the indices associated with each block. 523 524 Not Collective 525 526 Input Parameter: 527 . is - the index set 528 529 Output Parameter: 530 . idx - the integer indices 531 532 Level: intermediate 533 534 Concepts: IS^block 535 Concepts: index sets^getting indices 536 Concepts: index sets^block 537 538 .seealso: ISRestoreIndices(), ISBlockGetIndices() 539 @*/ 540 PetscErrorCode ISBlockRestoreIndices(IS is,const PetscInt *idx[]) 541 { 542 PetscErrorCode ierr; 543 544 PetscFunctionBegin; 545 ierr = PetscUseMethod(is,"ISBlockRestoreIndices_C",(IS,const PetscInt*[]),(is,idx));CHKERRQ(ierr); 546 PetscFunctionReturn(0); 547 } 548 549 /*@ 550 ISBlockGetLocalSize - Returns the local number of blocks in the index set. 551 552 Not Collective 553 554 Input Parameter: 555 . is - the index set 556 557 Output Parameter: 558 . size - the local number of blocks 559 560 Level: intermediate 561 562 Concepts: IS^block sizes 563 Concepts: index sets^block sizes 564 565 .seealso: ISGetBlockSize(), ISBlockGetSize(), ISGetSize(), ISCreateBlock() 566 @*/ 567 PetscErrorCode ISBlockGetLocalSize(IS is,PetscInt *size) 568 { 569 PetscErrorCode ierr; 570 571 PetscFunctionBegin; 572 ierr = PetscUseMethod(is,"ISBlockGetLocalSize_C",(IS,PetscInt*),(is,size));CHKERRQ(ierr); 573 PetscFunctionReturn(0); 574 } 575 576 static PetscErrorCode ISBlockGetLocalSize_Block(IS is,PetscInt *size) 577 { 578 PetscInt bs, n; 579 PetscErrorCode ierr; 580 581 PetscFunctionBegin; 582 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 583 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 584 *size = n/bs; 585 PetscFunctionReturn(0); 586 } 587 588 /*@ 589 ISBlockGetSize - Returns the global number of blocks in the index set. 590 591 Not Collective 592 593 Input Parameter: 594 . is - the index set 595 596 Output Parameter: 597 . size - the global number of blocks 598 599 Level: intermediate 600 601 Concepts: IS^block sizes 602 Concepts: index sets^block sizes 603 604 .seealso: ISGetBlockSize(), ISBlockGetLocalSize(), ISGetSize(), ISCreateBlock() 605 @*/ 606 PetscErrorCode ISBlockGetSize(IS is,PetscInt *size) 607 { 608 PetscErrorCode ierr; 609 610 PetscFunctionBegin; 611 ierr = PetscUseMethod(is,"ISBlockGetSize_C",(IS,PetscInt*),(is,size));CHKERRQ(ierr); 612 PetscFunctionReturn(0); 613 } 614 615 static PetscErrorCode ISBlockGetSize_Block(IS is,PetscInt *size) 616 { 617 PetscInt bs, N; 618 PetscErrorCode ierr; 619 620 PetscFunctionBegin; 621 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 622 ierr = PetscLayoutGetSize(is->map, &N);CHKERRQ(ierr); 623 *size = N/bs; 624 PetscFunctionReturn(0); 625 } 626 627 PETSC_EXTERN PetscErrorCode ISCreate_Block(IS is) 628 { 629 PetscErrorCode ierr; 630 IS_Block *sub; 631 632 PetscFunctionBegin; 633 ierr = PetscNewLog(is,&sub);CHKERRQ(ierr); 634 is->data = sub; 635 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockSetIndices_C",ISBlockSetIndices_Block);CHKERRQ(ierr); 636 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetIndices_C",ISBlockGetIndices_Block);CHKERRQ(ierr); 637 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockRestoreIndices_C",ISBlockRestoreIndices_Block);CHKERRQ(ierr); 638 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetSize_C",ISBlockGetSize_Block);CHKERRQ(ierr); 639 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetLocalSize_C",ISBlockGetLocalSize_Block);CHKERRQ(ierr); 640 PetscFunctionReturn(0); 641 } 642