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