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