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__ "ISSorted_Block" 171 PetscErrorCode ISSorted_Block(IS is,PetscBool *flg) 172 { 173 IS_Block *sub = (IS_Block*)is->data; 174 175 PetscFunctionBegin; 176 *flg = sub->sorted; 177 PetscFunctionReturn(0); 178 } 179 180 #undef __FUNCT__ 181 #define __FUNCT__ "ISDuplicate_Block" 182 PetscErrorCode ISDuplicate_Block(IS is,IS *newIS) 183 { 184 PetscErrorCode ierr; 185 IS_Block *sub = (IS_Block*)is->data; 186 PetscInt bs, n; 187 188 PetscFunctionBegin; 189 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 190 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 191 n /= bs; 192 ierr = ISCreateBlock(PetscObjectComm((PetscObject)is),bs,n,sub->idx,PETSC_COPY_VALUES,newIS);CHKERRQ(ierr); 193 PetscFunctionReturn(0); 194 } 195 196 #undef __FUNCT__ 197 #define __FUNCT__ "ISIdentity_Block" 198 PetscErrorCode ISIdentity_Block(IS is,PetscBool *ident) 199 { 200 IS_Block *is_block = (IS_Block*)is->data; 201 PetscInt i,bs,n,*idx = is_block->idx; 202 PetscErrorCode ierr; 203 204 PetscFunctionBegin; 205 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 206 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 207 n /= bs; 208 is->isidentity = PETSC_TRUE; 209 *ident = PETSC_TRUE; 210 for (i=0; i<n; i++) { 211 if (idx[i] != bs*i) { 212 is->isidentity = PETSC_FALSE; 213 *ident = PETSC_FALSE; 214 PetscFunctionReturn(0); 215 } 216 } 217 PetscFunctionReturn(0); 218 } 219 220 #undef __FUNCT__ 221 #define __FUNCT__ "ISCopy_Block" 222 static PetscErrorCode ISCopy_Block(IS is,IS isy) 223 { 224 IS_Block *is_block = (IS_Block*)is->data,*isy_block = (IS_Block*)isy->data; 225 PetscInt bs, n, N, bsy, ny, Ny; 226 PetscErrorCode ierr; 227 228 PetscFunctionBegin; 229 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 230 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 231 ierr = PetscLayoutGetSize(is->map, &N);CHKERRQ(ierr); 232 ierr = PetscLayoutGetBlockSize(isy->map, &bsy);CHKERRQ(ierr); 233 ierr = PetscLayoutGetLocalSize(isy->map, &ny);CHKERRQ(ierr); 234 ierr = PetscLayoutGetSize(isy->map, &Ny);CHKERRQ(ierr); 235 if (n != ny || N != Ny || bs != bsy) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Index sets incompatible"); 236 isy_block->sorted = is_block->sorted; 237 ierr = PetscMemcpy(isy_block->idx,is_block->idx,(n/bs)*sizeof(PetscInt));CHKERRQ(ierr); 238 PetscFunctionReturn(0); 239 } 240 241 #undef __FUNCT__ 242 #define __FUNCT__ "ISOnComm_Block" 243 static PetscErrorCode ISOnComm_Block(IS is,MPI_Comm comm,PetscCopyMode mode,IS *newis) 244 { 245 PetscErrorCode ierr; 246 IS_Block *sub = (IS_Block*)is->data; 247 PetscInt bs, n; 248 249 PetscFunctionBegin; 250 if (mode == PETSC_OWN_POINTER) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Cannot use PETSC_OWN_POINTER"); 251 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 252 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 253 ierr = ISCreateBlock(comm,bs,n/bs,sub->idx,mode,newis);CHKERRQ(ierr); 254 PetscFunctionReturn(0); 255 } 256 257 #undef __FUNCT__ 258 #define __FUNCT__ "ISSetBlockSize_Block" 259 static PetscErrorCode ISSetBlockSize_Block(IS is,PetscInt bs) 260 { 261 PetscErrorCode ierr; 262 263 PetscFunctionBegin; 264 ierr = PetscLayoutSetBlockSize(is->map, bs);CHKERRQ(ierr); 265 PetscFunctionReturn(0); 266 } 267 268 269 static struct _ISOps myops = { ISGetSize_Block, 270 ISGetLocalSize_Block, 271 ISGetIndices_Block, 272 ISRestoreIndices_Block, 273 ISInvertPermutation_Block, 274 ISSort_Block, 275 ISSorted_Block, 276 ISDuplicate_Block, 277 ISDestroy_Block, 278 ISView_Block, 279 ISLoad_Default, 280 ISIdentity_Block, 281 ISCopy_Block, 282 0, 283 ISOnComm_Block, 284 ISSetBlockSize_Block, 285 0}; 286 287 #undef __FUNCT__ 288 #define __FUNCT__ "ISBlockSetIndices" 289 /*@ 290 ISBlockSetIndices - The indices are relative to entries, not blocks. 291 292 Collective on IS 293 294 Input Parameters: 295 + is - the index set 296 . bs - number of elements in each block, one for each block and count of block not indices 297 . n - the length of the index set (the number of blocks) 298 . idx - the list of integers, these are by block, not by location 299 + mode - see PetscCopyMode, only PETSC_COPY_VALUES and PETSC_OWN_POINTER are supported 300 301 302 Notes: 303 When the communicator is not MPI_COMM_SELF, the operations on the 304 index sets, IS, are NOT conceptually the same as MPI_Group operations. 305 The index sets are then distributed sets of indices and thus certain operations 306 on them are collective. 307 308 Example: 309 If you wish to index the values {0,1,4,5}, then use 310 a block size of 2 and idx of {0,2}. 311 312 Level: beginner 313 314 Concepts: IS^block 315 Concepts: index sets^block 316 Concepts: block^index set 317 318 .seealso: ISCreateStride(), ISCreateGeneral(), ISAllGather() 319 @*/ 320 PetscErrorCode ISBlockSetIndices(IS is,PetscInt bs,PetscInt n,const PetscInt idx[],PetscCopyMode mode) 321 { 322 PetscErrorCode ierr; 323 324 PetscFunctionBegin; 325 ierr = PetscUseMethod(is,"ISBlockSetIndices_C",(IS,PetscInt,PetscInt,const PetscInt[],PetscCopyMode),(is,bs,n,idx,mode));CHKERRQ(ierr); 326 PetscFunctionReturn(0); 327 } 328 329 #undef __FUNCT__ 330 #define __FUNCT__ "ISBlockSetIndices_Block" 331 PetscErrorCode ISBlockSetIndices_Block(IS is,PetscInt bs,PetscInt n,const PetscInt idx[],PetscCopyMode mode) 332 { 333 PetscErrorCode ierr; 334 PetscInt i,min,max; 335 IS_Block *sub = (IS_Block*)is->data; 336 PetscBool sorted = PETSC_TRUE; 337 338 PetscFunctionBegin; 339 ierr = PetscFree(sub->idx);CHKERRQ(ierr); 340 ierr = PetscLayoutSetLocalSize(is->map, n*bs);CHKERRQ(ierr); 341 ierr = PetscLayoutSetBlockSize(is->map, bs);CHKERRQ(ierr); 342 ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); 343 for (i=1; i<n; i++) { 344 if (idx[i] < idx[i-1]) {sorted = PETSC_FALSE; break;} 345 } 346 if (n) min = max = idx[0]; 347 else min = max = 0; 348 for (i=1; i<n; i++) { 349 if (idx[i] < min) min = idx[i]; 350 if (idx[i] > max) max = idx[i]; 351 } 352 if (mode == PETSC_COPY_VALUES) { 353 ierr = PetscMalloc1(n,&sub->idx);CHKERRQ(ierr); 354 ierr = PetscLogObjectMemory((PetscObject)is,n*sizeof(PetscInt));CHKERRQ(ierr); 355 ierr = PetscMemcpy(sub->idx,idx,n*sizeof(PetscInt));CHKERRQ(ierr); 356 } else if (mode == PETSC_OWN_POINTER) sub->idx = (PetscInt*) idx; 357 else SETERRQ(PetscObjectComm((PetscObject)is),PETSC_ERR_SUP,"Only supports PETSC_COPY_VALUES and PETSC_OWN_POINTER"); 358 359 sub->sorted = sorted; 360 is->min = bs*min; 361 is->max = bs*max+bs-1; 362 is->data = (void*)sub; 363 ierr = PetscMemcpy(is->ops,&myops,sizeof(myops));CHKERRQ(ierr); 364 is->isperm = PETSC_FALSE; 365 PetscFunctionReturn(0); 366 } 367 368 #undef __FUNCT__ 369 #define __FUNCT__ "ISCreateBlock" 370 /*@ 371 ISCreateBlock - Creates a data structure for an index set containing 372 a list of integers. The indices are relative to entries, not blocks. 373 374 Collective on MPI_Comm 375 376 Input Parameters: 377 + comm - the MPI communicator 378 . bs - number of elements in each block 379 . n - the length of the index set (the number of blocks) 380 . idx - the list of integers, one for each block and count of block not indices 381 - mode - see PetscCopyMode, only PETSC_COPY_VALUES and PETSC_OWN_POINTER are supported in this routine 382 383 Output Parameter: 384 . is - the new index set 385 386 Notes: 387 When the communicator is not MPI_COMM_SELF, the operations on the 388 index sets, IS, are NOT conceptually the same as MPI_Group operations. 389 The index sets are then distributed sets of indices and thus certain operations 390 on them are collective. 391 392 Example: 393 If you wish to index the values {0,1,6,7}, then use 394 a block size of 2 and idx of {0,3}. 395 396 Level: beginner 397 398 Concepts: IS^block 399 Concepts: index sets^block 400 Concepts: block^index set 401 402 .seealso: ISCreateStride(), ISCreateGeneral(), ISAllGather() 403 @*/ 404 PetscErrorCode ISCreateBlock(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt idx[],PetscCopyMode mode,IS *is) 405 { 406 PetscErrorCode ierr; 407 408 PetscFunctionBegin; 409 PetscValidPointer(is,5); 410 if (n < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"length < 0"); 411 if (n) PetscValidIntPointer(idx,4); 412 413 ierr = ISCreate(comm,is);CHKERRQ(ierr); 414 ierr = ISSetType(*is,ISBLOCK);CHKERRQ(ierr); 415 ierr = ISBlockSetIndices(*is,bs,n,idx,mode);CHKERRQ(ierr); 416 PetscFunctionReturn(0); 417 } 418 419 #undef __FUNCT__ 420 #define __FUNCT__ "ISBlockGetIndices_Block" 421 PetscErrorCode ISBlockGetIndices_Block(IS is,const PetscInt *idx[]) 422 { 423 IS_Block *sub = (IS_Block*)is->data; 424 425 PetscFunctionBegin; 426 *idx = sub->idx; 427 PetscFunctionReturn(0); 428 } 429 430 #undef __FUNCT__ 431 #define __FUNCT__ "ISBlockRestoreIndices_Block" 432 PetscErrorCode ISBlockRestoreIndices_Block(IS is,const PetscInt *idx[]) 433 { 434 PetscFunctionBegin; 435 PetscFunctionReturn(0); 436 } 437 438 #undef __FUNCT__ 439 #define __FUNCT__ "ISBlockGetIndices" 440 /*@C 441 ISBlockGetIndices - Gets the indices associated with each block. 442 443 Not Collective 444 445 Input Parameter: 446 . is - the index set 447 448 Output Parameter: 449 . idx - the integer indices, one for each block and count of block not indices 450 451 Level: intermediate 452 453 Concepts: IS^block 454 Concepts: index sets^getting indices 455 Concepts: index sets^block 456 457 .seealso: ISGetIndices(), ISBlockRestoreIndices() 458 @*/ 459 PetscErrorCode ISBlockGetIndices(IS is,const PetscInt *idx[]) 460 { 461 PetscErrorCode ierr; 462 463 PetscFunctionBegin; 464 ierr = PetscUseMethod(is,"ISBlockGetIndices_C",(IS,const PetscInt*[]),(is,idx));CHKERRQ(ierr); 465 PetscFunctionReturn(0); 466 } 467 468 #undef __FUNCT__ 469 #define __FUNCT__ "ISBlockRestoreIndices" 470 /*@C 471 ISBlockRestoreIndices - Restores the indices associated with each block. 472 473 Not Collective 474 475 Input Parameter: 476 . is - the index set 477 478 Output Parameter: 479 . idx - the integer indices 480 481 Level: intermediate 482 483 Concepts: IS^block 484 Concepts: index sets^getting indices 485 Concepts: index sets^block 486 487 .seealso: ISRestoreIndices(), ISBlockGetIndices() 488 @*/ 489 PetscErrorCode ISBlockRestoreIndices(IS is,const PetscInt *idx[]) 490 { 491 PetscErrorCode ierr; 492 493 PetscFunctionBegin; 494 ierr = PetscUseMethod(is,"ISBlockRestoreIndices_C",(IS,const PetscInt*[]),(is,idx));CHKERRQ(ierr); 495 PetscFunctionReturn(0); 496 } 497 498 #undef __FUNCT__ 499 #define __FUNCT__ "ISBlockGetLocalSize" 500 /*@ 501 ISBlockGetLocalSize - Returns the local number of blocks in the index set. 502 503 Not Collective 504 505 Input Parameter: 506 . is - the index set 507 508 Output Parameter: 509 . size - the local number of blocks 510 511 Level: intermediate 512 513 Concepts: IS^block sizes 514 Concepts: index sets^block sizes 515 516 .seealso: ISGetBlockSize(), ISBlockGetSize(), ISGetSize(), ISCreateBlock() 517 @*/ 518 PetscErrorCode ISBlockGetLocalSize(IS is,PetscInt *size) 519 { 520 PetscErrorCode ierr; 521 522 PetscFunctionBegin; 523 ierr = PetscUseMethod(is,"ISBlockGetLocalSize_C",(IS,PetscInt*),(is,size));CHKERRQ(ierr); 524 PetscFunctionReturn(0); 525 } 526 527 #undef __FUNCT__ 528 #define __FUNCT__ "ISBlockGetLocalSize_Block" 529 PetscErrorCode ISBlockGetLocalSize_Block(IS is,PetscInt *size) 530 { 531 PetscInt bs, n; 532 PetscErrorCode ierr; 533 534 PetscFunctionBegin; 535 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 536 ierr = PetscLayoutGetLocalSize(is->map, &n);CHKERRQ(ierr); 537 *size = n/bs; 538 PetscFunctionReturn(0); 539 } 540 541 #undef __FUNCT__ 542 #define __FUNCT__ "ISBlockGetSize" 543 /*@ 544 ISBlockGetSize - Returns the global number of blocks in the index set. 545 546 Not Collective 547 548 Input Parameter: 549 . is - the index set 550 551 Output Parameter: 552 . size - the global number of blocks 553 554 Level: intermediate 555 556 Concepts: IS^block sizes 557 Concepts: index sets^block sizes 558 559 .seealso: ISGetBlockSize(), ISBlockGetLocalSize(), ISGetSize(), ISCreateBlock() 560 @*/ 561 PetscErrorCode ISBlockGetSize(IS is,PetscInt *size) 562 { 563 PetscErrorCode ierr; 564 565 PetscFunctionBegin; 566 ierr = PetscUseMethod(is,"ISBlockGetSize_C",(IS,PetscInt*),(is,size));CHKERRQ(ierr); 567 PetscFunctionReturn(0); 568 } 569 570 #undef __FUNCT__ 571 #define __FUNCT__ "ISBlockGetSize_Block" 572 PetscErrorCode ISBlockGetSize_Block(IS is,PetscInt *size) 573 { 574 PetscInt bs, N; 575 PetscErrorCode ierr; 576 577 PetscFunctionBegin; 578 ierr = PetscLayoutGetBlockSize(is->map, &bs);CHKERRQ(ierr); 579 ierr = PetscLayoutGetSize(is->map, &N);CHKERRQ(ierr); 580 *size = N/bs; 581 PetscFunctionReturn(0); 582 } 583 584 #undef __FUNCT__ 585 #define __FUNCT__ "ISToGeneral_Block" 586 PetscErrorCode ISToGeneral_Block(IS inis) 587 { 588 PetscErrorCode ierr; 589 const PetscInt *idx; 590 PetscInt n; 591 592 PetscFunctionBegin; 593 ierr = ISGetLocalSize(inis,&n);CHKERRQ(ierr); 594 ierr = ISGetIndices(inis,&idx);CHKERRQ(ierr); 595 ierr = ISSetType(inis,ISGENERAL);CHKERRQ(ierr); 596 ierr = ISGeneralSetIndices(inis,n,idx,PETSC_OWN_POINTER);CHKERRQ(ierr); 597 PetscFunctionReturn(0); 598 } 599 600 #undef __FUNCT__ 601 #define __FUNCT__ "ISCreate_Block" 602 PETSC_EXTERN PetscErrorCode ISCreate_Block(IS is) 603 { 604 PetscErrorCode ierr; 605 IS_Block *sub; 606 607 PetscFunctionBegin; 608 ierr = PetscNewLog(is,&sub);CHKERRQ(ierr); 609 is->data = sub; 610 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockSetIndices_C",ISBlockSetIndices_Block);CHKERRQ(ierr); 611 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetIndices_C",ISBlockGetIndices_Block);CHKERRQ(ierr); 612 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockRestoreIndices_C",ISBlockRestoreIndices_Block);CHKERRQ(ierr); 613 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetSize_C",ISBlockGetSize_Block);CHKERRQ(ierr); 614 ierr = PetscObjectComposeFunction((PetscObject)is,"ISBlockGetLocalSize_C",ISBlockGetLocalSize_Block);CHKERRQ(ierr); 615 PetscFunctionReturn(0); 616 } 617