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