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) min = max = idx[0]; 437 else min = max = 0; 438 for (i=1; i<n; i++) { 439 if (idx[i] < min) min = idx[i]; 440 if (idx[i] > max) max = idx[i]; 441 } 442 if (mode == PETSC_COPY_VALUES) { 443 ierr = PetscMalloc1(n,&sub->idx);CHKERRQ(ierr); 444 ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); 445 ierr = PetscMemcpy(sub->idx,idx,n*sizeof(PetscInt));CHKERRQ(ierr); 446 } else if (mode == PETSC_OWN_POINTER) { 447 sub->idx = (PetscInt*) idx; 448 ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); 449 } else if (mode == PETSC_USE_POINTER) { 450 sub->idx = (PetscInt*) idx; 451 sub->borrowed_indices = PETSC_TRUE; 452 } 453 454 sub->sorted = sorted; 455 is->min = bs*min; 456 is->max = bs*max+bs-1; 457 is->data = (void*)sub; 458 ierr = PetscMemcpy(is->ops,&myops,sizeof(myops));CHKERRQ(ierr); 459 is->isperm = PETSC_FALSE; 460 PetscFunctionReturn(0); 461 } 462 463 #undef __FUNCT__ 464 #define __FUNCT__ "ISCreateBlock" 465 /*@ 466 ISCreateBlock - Creates a data structure for an index set containing 467 a list of integers. The indices are relative to entries, not blocks. 468 469 Collective on MPI_Comm 470 471 Input Parameters: 472 + comm - the MPI communicator 473 . bs - number of elements in each block 474 . n - the length of the index set (the number of blocks) 475 . idx - the list of integers, one for each block and count of block not indices 476 - mode - see PetscCopyMode, only PETSC_COPY_VALUES and PETSC_OWN_POINTER are supported in this routine 477 478 Output Parameter: 479 . is - the new index set 480 481 Notes: 482 When the communicator is not MPI_COMM_SELF, the operations on the 483 index sets, IS, are NOT conceptually the same as MPI_Group operations. 484 The index sets are then distributed sets of indices and thus certain operations 485 on them are collective. 486 487 Example: 488 If you wish to index the values {0,1,6,7}, then use 489 a block size of 2 and idx of {0,3}. 490 491 Level: beginner 492 493 Concepts: IS^block 494 Concepts: index sets^block 495 Concepts: block^index set 496 497 .seealso: ISCreateStride(), ISCreateGeneral(), ISAllGather() 498 @*/ 499 PetscErrorCode ISCreateBlock(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt idx[],PetscCopyMode mode,IS *is) 500 { 501 PetscErrorCode ierr; 502 503 PetscFunctionBegin; 504 PetscValidPointer(is,5); 505 if (n < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"length < 0"); 506 if (n) PetscValidIntPointer(idx,4); 507 508 ierr = ISCreate(comm,is);CHKERRQ(ierr); 509 ierr = ISSetType(*is,ISBLOCK);CHKERRQ(ierr); 510 ierr = ISBlockSetIndices(*is,bs,n,idx,mode);CHKERRQ(ierr); 511 PetscFunctionReturn(0); 512 } 513 514 #undef __FUNCT__ 515 #define __FUNCT__ "ISBlockGetIndices_Block" 516 static PetscErrorCode ISBlockGetIndices_Block(IS is,const PetscInt *idx[]) 517 { 518 IS_Block *sub = (IS_Block*)is->data; 519 520 PetscFunctionBegin; 521 *idx = sub->idx; 522 PetscFunctionReturn(0); 523 } 524 525 #undef __FUNCT__ 526 #define __FUNCT__ "ISBlockRestoreIndices_Block" 527 static PetscErrorCode ISBlockRestoreIndices_Block(IS is,const PetscInt *idx[]) 528 { 529 PetscFunctionBegin; 530 PetscFunctionReturn(0); 531 } 532 533 #undef __FUNCT__ 534 #define __FUNCT__ "ISBlockGetIndices" 535 /*@C 536 ISBlockGetIndices - Gets the indices associated with each block. 537 538 Not Collective 539 540 Input Parameter: 541 . is - the index set 542 543 Output Parameter: 544 . idx - the integer indices, one for each block and count of block not indices 545 546 Level: intermediate 547 548 Concepts: IS^block 549 Concepts: index sets^getting indices 550 Concepts: index sets^block 551 552 .seealso: ISGetIndices(), ISBlockRestoreIndices() 553 @*/ 554 PetscErrorCode ISBlockGetIndices(IS is,const PetscInt *idx[]) 555 { 556 PetscErrorCode ierr; 557 558 PetscFunctionBegin; 559 ierr = PetscUseMethod(is,"ISBlockGetIndices_C",(IS,const PetscInt*[]),(is,idx));CHKERRQ(ierr); 560 PetscFunctionReturn(0); 561 } 562 563 #undef __FUNCT__ 564 #define __FUNCT__ "ISBlockRestoreIndices" 565 /*@C 566 ISBlockRestoreIndices - Restores the indices associated with each block. 567 568 Not Collective 569 570 Input Parameter: 571 . is - the index set 572 573 Output Parameter: 574 . idx - the integer indices 575 576 Level: intermediate 577 578 Concepts: IS^block 579 Concepts: index sets^getting indices 580 Concepts: index sets^block 581 582 .seealso: ISRestoreIndices(), ISBlockGetIndices() 583 @*/ 584 PetscErrorCode ISBlockRestoreIndices(IS is,const PetscInt *idx[]) 585 { 586 PetscErrorCode ierr; 587 588 PetscFunctionBegin; 589 ierr = PetscUseMethod(is,"ISBlockRestoreIndices_C",(IS,const PetscInt*[]),(is,idx));CHKERRQ(ierr); 590 PetscFunctionReturn(0); 591 } 592 593 #undef __FUNCT__ 594 #define __FUNCT__ "ISBlockGetLocalSize" 595 /*@ 596 ISBlockGetLocalSize - Returns the local number of blocks in the index set. 597 598 Not Collective 599 600 Input Parameter: 601 . is - the index set 602 603 Output Parameter: 604 . size - the local number of blocks 605 606 Level: intermediate 607 608 Concepts: IS^block sizes 609 Concepts: index sets^block sizes 610 611 .seealso: ISGetBlockSize(), ISBlockGetSize(), ISGetSize(), ISCreateBlock() 612 @*/ 613 PetscErrorCode ISBlockGetLocalSize(IS is,PetscInt *size) 614 { 615 PetscErrorCode ierr; 616 617 PetscFunctionBegin; 618 ierr = PetscUseMethod(is,"ISBlockGetLocalSize_C",(IS,PetscInt*),(is,size));CHKERRQ(ierr); 619 PetscFunctionReturn(0); 620 } 621 622 #undef __FUNCT__ 623 #define __FUNCT__ "ISBlockGetLocalSize_Block" 624 static PetscErrorCode ISBlockGetLocalSize_Block(IS is,PetscInt *size) 625 { 626 PetscInt bs, n; 627 PetscErrorCode ierr; 628 629 PetscFunctionBegin; 630 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 631 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 632 *size = n/bs; 633 PetscFunctionReturn(0); 634 } 635 636 #undef __FUNCT__ 637 #define __FUNCT__ "ISBlockGetSize" 638 /*@ 639 ISBlockGetSize - Returns the global number of blocks in the index set. 640 641 Not Collective 642 643 Input Parameter: 644 . is - the index set 645 646 Output Parameter: 647 . size - the global number of blocks 648 649 Level: intermediate 650 651 Concepts: IS^block sizes 652 Concepts: index sets^block sizes 653 654 .seealso: ISGetBlockSize(), ISBlockGetLocalSize(), ISGetSize(), ISCreateBlock() 655 @*/ 656 PetscErrorCode ISBlockGetSize(IS is,PetscInt *size) 657 { 658 PetscErrorCode ierr; 659 660 PetscFunctionBegin; 661 ierr = PetscUseMethod(is,"ISBlockGetSize_C",(IS,PetscInt*),(is,size));CHKERRQ(ierr); 662 PetscFunctionReturn(0); 663 } 664 665 #undef __FUNCT__ 666 #define __FUNCT__ "ISBlockGetSize_Block" 667 static PetscErrorCode ISBlockGetSize_Block(IS is,PetscInt *size) 668 { 669 PetscInt bs, N; 670 PetscErrorCode ierr; 671 672 PetscFunctionBegin; 673 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 674 ierr = PetscLayoutGetSize(is->map, &N);CHKERRQ(ierr); 675 *size = N/bs; 676 PetscFunctionReturn(0); 677 } 678 679 #undef __FUNCT__ 680 #define __FUNCT__ "ISCreate_Block" 681 PETSC_EXTERN PetscErrorCode ISCreate_Block(IS is) 682 { 683 PetscErrorCode ierr; 684 IS_Block *sub; 685 686 PetscFunctionBegin; 687 ierr = PetscNewLog(is,&sub);CHKERRQ(ierr); 688 is->data = sub; 689 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockSetIndices_C",ISBlockSetIndices_Block);CHKERRQ(ierr); 690 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetIndices_C",ISBlockGetIndices_Block);CHKERRQ(ierr); 691 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockRestoreIndices_C",ISBlockRestoreIndices_Block);CHKERRQ(ierr); 692 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetSize_C",ISBlockGetSize_Block);CHKERRQ(ierr); 693 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetLocalSize_C",ISBlockGetLocalSize_Block);CHKERRQ(ierr); 694 PetscFunctionReturn(0); 695 } 696