Actual source code: index.c

  2: /*  
  3:    Defines the abstract operations on index sets, i.e. the public interface. 
  4: */
  5: #include <private/isimpl.h>      /*I "petscis.h" I*/

  7: /* Logging support */
  8: PetscClassId  IS_CLASSID;

 12: /*@
 13:    ISIdentity - Determines whether index set is the identity mapping.

 15:    Collective on IS

 17:    Input Parmeters:
 18: .  is - the index set

 20:    Output Parameters:
 21: .  ident - PETSC_TRUE if an identity, else PETSC_FALSE

 23:    Level: intermediate

 25:    Concepts: identity mapping
 26:    Concepts: index sets^is identity

 28: .seealso: ISSetIdentity()
 29: @*/
 30: PetscErrorCode  ISIdentity(IS is,PetscBool  *ident)
 31: {

 37:   *ident = is->isidentity;
 38:   if (*ident) return(0);
 39:   if (is->ops->identity) {
 40:     (*is->ops->identity)(is,ident);
 41:   }
 42:   return(0);
 43: }

 47: /*@
 48:    ISSetIdentity - Informs the index set that it is an identity.

 50:    Logically Collective on IS

 52:    Input Parmeters:
 53: .  is - the index set

 55:    Level: intermediate

 57:    Concepts: identity mapping
 58:    Concepts: index sets^is identity

 60: .seealso: ISIdentity()
 61: @*/
 62: PetscErrorCode  ISSetIdentity(IS is)
 63: {
 66:   is->isidentity = PETSC_TRUE;
 67:   return(0);
 68: }

 72: /*@
 73:    ISContiguousLocal - Locates an index set with contiguous range within a global range, if possible

 75:    Not Collective

 77:    Input Parmeters:
 78: +  is - the index set
 79: .  gstart - global start
 80: .  gend - global end

 82:    Output Parameters:
 83: +  start - start of contiguous block, as an offset from gstart
 84: -  contig - PETSC_TRUE if the index set refers to contiguous entries on this process, else PETSC_FALSE

 86:    Level: developer

 88:    Concepts: index sets^is contiguous

 90: .seealso: ISGetLocalSize(), VecGetOwnershipRange()
 91: @*/
 92: PetscErrorCode  ISContiguousLocal(IS is,PetscInt gstart,PetscInt gend,PetscInt *start,PetscBool *contig)
 93: {

100:   if (is->ops->contiguous) {
101:     (*is->ops->contiguous)(is,gstart,gend,start,contig);
102:   } else {
103:     *start = -1;
104:     *contig = PETSC_FALSE;
105:   }
106:   return(0);
107: }

111: /*@
112:    ISPermutation - PETSC_TRUE or PETSC_FALSE depending on whether the 
113:    index set has been declared to be a permutation.

115:    Logically Collective on IS

117:    Input Parmeters:
118: .  is - the index set

120:    Output Parameters:
121: .  perm - PETSC_TRUE if a permutation, else PETSC_FALSE

123:    Level: intermediate

125:   Concepts: permutation
126:   Concepts: index sets^is permutation

128: .seealso: ISSetPermutation()
129: @*/
130: PetscErrorCode  ISPermutation(IS is,PetscBool  *perm)
131: {
135:   *perm = (PetscBool) is->isperm;
136:   return(0);
137: }

141: /*@
142:    ISSetPermutation - Informs the index set that it is a permutation.

144:    Logically Collective on IS

146:    Input Parmeters:
147: .  is - the index set

149:    Level: intermediate

151:   Concepts: permutation
152:   Concepts: index sets^permutation

154:    The debug version of the libraries (./configure --with-debugging=1) checks if the 
155:   index set is actually a permutation. The optimized version just believes you.

157: .seealso: ISPermutation()
158: @*/
159: PetscErrorCode  ISSetPermutation(IS is)
160: {
163: #if defined(PETSC_USE_DEBUG)
164:   {
165:     PetscMPIInt    size;

168:     MPI_Comm_size(((PetscObject)is)->comm,&size);
169:     if (size == 1) {
170:       PetscInt       i,n,*idx;
171:       const PetscInt *iidx;
172: 
173:       ISGetSize(is,&n);
174:       PetscMalloc(n*sizeof(PetscInt),&idx);
175:       ISGetIndices(is,&iidx);
176:       PetscMemcpy(idx,iidx,n*sizeof(PetscInt));
177:       PetscSortInt(n,idx);
178:       for (i=0; i<n; i++) {
179:         if (idx[i] != i) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Index set is not a permutation");
180:       }
181:       PetscFree(idx);
182:     }
183:   }
184: #endif
185:   is->isperm = PETSC_TRUE;
186:   return(0);
187: }

191: /*@
192:    ISDestroy - Destroys an index set.

194:    Collective on IS

196:    Input Parameters:
197: .  is - the index set

199:    Level: beginner

201: .seealso: ISCreateGeneral(), ISCreateStride(), ISCreateBlocked()
202: @*/
203: PetscErrorCode  ISDestroy(IS *is)
204: {

208:   if (!*is) return(0);
210:   if (--((PetscObject)(*is))->refct > 0) {*is = 0; return(0);}
211:   if ((*is)->complement) {
212:     PetscInt refcnt;
213:     PetscObjectGetReference((PetscObject)((*is)->complement), &refcnt);
214:     if (refcnt > 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Nonlocal IS has not been restored");
215:     ISDestroy(&(*is)->complement);
216:   }
217:   if ((*is)->ops->destroy) {
218:     (*(*is)->ops->destroy)(*is);
219:   }
220:   /* Destroy local representations of offproc data. */
221:   PetscFree((*is)->total);
222:   PetscFree((*is)->nonlocal);
223:   PetscHeaderDestroy(is);
224:   return(0);
225: }

229: /*@
230:    ISInvertPermutation - Creates a new permutation that is the inverse of 
231:                          a given permutation.

233:    Collective on IS

235:    Input Parameter:
236: +  is - the index set
237: -  nlocal - number of indices on this processor in result (ignored for 1 proccessor) or
238:             use PETSC_DECIDE

240:    Output Parameter:
241: .  isout - the inverse permutation

243:    Level: intermediate

245:    Notes: For parallel index sets this does the complete parallel permutation, but the 
246:     code is not efficient for huge index sets (10,000,000 indices).

248:    Concepts: inverse permutation
249:    Concepts: permutation^inverse
250:    Concepts: index sets^inverting
251: @*/
252: PetscErrorCode  ISInvertPermutation(IS is,PetscInt nlocal,IS *isout)
253: {

259:   if (!is->isperm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not a permutation, must call ISSetPermutation() on the IS first");
260:   (*is->ops->invertpermutation)(is,nlocal,isout);
261:   ISSetPermutation(*isout);
262:   return(0);
263: }

267: /*@
268:    ISGetSize - Returns the global length of an index set. 

270:    Not Collective

272:    Input Parameter:
273: .  is - the index set

275:    Output Parameter:
276: .  size - the global size

278:    Level: beginner

280:    Concepts: size^of index set
281:    Concepts: index sets^size

283: @*/
284: PetscErrorCode  ISGetSize(IS is,PetscInt *size)
285: {

291:   (*is->ops->getsize)(is,size);
292:   return(0);
293: }

297: /*@
298:    ISGetLocalSize - Returns the local (processor) length of an index set. 

300:    Not Collective

302:    Input Parameter:
303: .  is - the index set

305:    Output Parameter:
306: .  size - the local size

308:    Level: beginner

310:    Concepts: size^of index set
311:    Concepts: local size^of index set
312:    Concepts: index sets^local size
313:   
314: @*/
315: PetscErrorCode  ISGetLocalSize(IS is,PetscInt *size)
316: {

322:   (*is->ops->getlocalsize)(is,size);
323:   return(0);
324: }

328: /*@C
329:    ISGetIndices - Returns a pointer to the indices.  The user should call 
330:    ISRestoreIndices() after having looked at the indices.  The user should 
331:    NOT change the indices.

333:    Not Collective

335:    Input Parameter:
336: .  is - the index set

338:    Output Parameter:
339: .  ptr - the location to put the pointer to the indices

341:    Fortran Note:
342:    This routine is used differently from Fortran
343: $    IS          is
344: $    integer     is_array(1)
345: $    PetscOffset i_is
346: $    int         ierr
347: $       call ISGetIndices(is,is_array,i_is,ierr)
348: $
349: $   Access first local entry in list
350: $      value = is_array(i_is + 1)
351: $
352: $      ...... other code
353: $       call ISRestoreIndices(is,is_array,i_is,ierr)

355:    See the Fortran chapter of the users manual and 
356:    petsc/src/is/examples/[tutorials,tests] for details.

358:    Level: intermediate

360:    Concepts: index sets^getting indices
361:    Concepts: indices of index set

363: .seealso: ISRestoreIndices(), ISGetIndicesF90()
364: @*/
365: PetscErrorCode  ISGetIndices(IS is,const PetscInt *ptr[])
366: {

372:   (*is->ops->getindices)(is,ptr);
373:   return(0);
374: }

378: /*@C
379:    ISRestoreIndices - Restores an index set to a usable state after a call 
380:                       to ISGetIndices().

382:    Not Collective

384:    Input Parameters:
385: +  is - the index set
386: -  ptr - the pointer obtained by ISGetIndices()

388:    Fortran Note:
389:    This routine is used differently from Fortran
390: $    IS          is
391: $    integer     is_array(1)
392: $    PetscOffset i_is
393: $    int         ierr
394: $       call ISGetIndices(is,is_array,i_is,ierr)
395: $
396: $   Access first local entry in list
397: $      value = is_array(i_is + 1)
398: $
399: $      ...... other code
400: $       call ISRestoreIndices(is,is_array,i_is,ierr)

402:    See the Fortran chapter of the users manual and 
403:    petsc/src/is/examples/[tutorials,tests] for details.

405:    Level: intermediate

407: .seealso: ISGetIndices(), ISRestoreIndicesF90()
408: @*/
409: PetscErrorCode  ISRestoreIndices(IS is,const PetscInt *ptr[])
410: {

416:   if (is->ops->restoreindices) {
417:     (*is->ops->restoreindices)(is,ptr);
418:   }
419:   return(0);
420: }

424: static PetscErrorCode ISGatherTotal_Private(IS is)
425: {
427:   PetscInt       i,n,N;
428:   const PetscInt *lindices;
429:   MPI_Comm       comm;
430:   PetscMPIInt    rank,size,*sizes = PETSC_NULL,*offsets = PETSC_NULL,nn;


435:   PetscObjectGetComm((PetscObject)is,&comm);
436:   MPI_Comm_size(comm,&size);
437:   MPI_Comm_rank(comm,&rank);
438:   ISGetLocalSize(is,&n);
439:   PetscMalloc2(size,PetscMPIInt,&sizes,size,PetscMPIInt,&offsets);
440: 
441:   nn   = PetscMPIIntCast(n);
442:   MPI_Allgather(&nn,1,MPIU_INT,sizes,1,MPIU_INT,comm);
443:   offsets[0] = 0;
444:   for (i=1;i<size; ++i) offsets[i] = offsets[i-1] + sizes[i-1];
445:   N = offsets[size-1] + sizes[size-1];
446: 
447:   PetscMalloc(N*sizeof(PetscInt),&(is->total));
448:   ISGetIndices(is,&lindices);
449:   MPI_Allgatherv((void*)lindices,nn,MPIU_INT,is->total,sizes,offsets,MPIU_INT,comm);
450:   ISRestoreIndices(is,&lindices);
451:   is->local_offset = offsets[rank];
452:   PetscFree2(sizes,offsets);

454:   return(0);
455: }

459: /*@C
460:    ISGetTotalIndices - Retrieve an array containing all indices across the communicator.

462:    Collective on IS

464:    Input Parameter:
465: .  is - the index set

467:    Output Parameter:
468: .  indices - total indices with rank 0 indices first, and so on; total array size is 
469:              the same as returned with ISGetSize().

471:    Level: intermediate

473:    Notes: this is potentially nonscalable, but depends on the size of the total index set
474:      and the size of the communicator. This may be feasible for index sets defined on
475:      subcommunicators, such that the set size does not grow with PETSC_WORLD_COMM.
476:      Note also that there is no way to tell where the local part of the indices starts
477:      (use ISGetIndices() and ISGetNonlocalIndices() to retrieve just the local and just
478:       the nonlocal part (complement), respectively).

480:    Concepts: index sets^getting nonlocal indices
481: .seealso: ISRestoreTotalIndices(), ISGetNonlocalIndices(), ISGetSize()
482: @*/
483: PetscErrorCode ISGetTotalIndices(IS is, const PetscInt *indices[])
484: {
486:   PetscMPIInt    size;

491:   MPI_Comm_size(((PetscObject)is)->comm, &size);
492:   if(size == 1) {
493:     (*is->ops->getindices)(is,indices);
494:   }
495:   else {
496:     if(!is->total) {
497:       ISGatherTotal_Private(is);
498:     }
499:     *indices = is->total;
500:   }
501:   return(0);
502: }

506: /*@C
507:    ISRestoreTotalIndices - Restore the index array obtained with ISGetTotalIndices().

509:    Not Collective.

511:    Input Parameter:
512: +  is - the index set
513: -  indices - index array; must be the array obtained with ISGetTotalIndices()

515:    Level: intermediate

517:    Concepts: index sets^getting nonlocal indices
518:    Concepts: index sets^restoring nonlocal indices
519: .seealso: ISRestoreTotalIndices(), ISGetNonlocalIndices()
520: @*/
521: PetscErrorCode  ISRestoreTotalIndices(IS is, const PetscInt *indices[])
522: {
524:   PetscMPIInt size;
528:   MPI_Comm_size(((PetscObject)is)->comm, &size);
529:   if(size == 1) {
530:     (*is->ops->restoreindices)(is,indices);
531:   }
532:   else {
533:     if(is->total != *indices) {
534:       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Index array pointer being restored does not point to the array obtained from the IS.");
535:     }
536:   }
537:   return(0);
538: }
541: /*@C
542:    ISGetNonlocalIndices - Retrieve an array of indices from remote processors
543:                        in this communicator.

545:    Collective on IS

547:    Input Parameter:
548: .  is - the index set

550:    Output Parameter:
551: .  indices - indices with rank 0 indices first, and so on,  omitting 
552:              the current rank.  Total number of indices is the difference
553:              total and local, obtained with ISGetSize() and ISGetLocalSize(),
554:              respectively.

556:    Level: intermediate

558:    Notes: restore the indices using ISRestoreNonlocalIndices().   
559:           The same scalability considerations as those for ISGetTotalIndices
560:           apply here.

562:    Concepts: index sets^getting nonlocal indices
563: .seealso: ISGetTotalIndices(), ISRestoreNonlocalIndices(), ISGetSize(), ISGetLocalSize().
564: @*/
565: PetscErrorCode  ISGetNonlocalIndices(IS is, const PetscInt *indices[])
566: {
568:   PetscMPIInt size;
569:   PetscInt n, N;
573:   MPI_Comm_size(((PetscObject)is)->comm, &size);
574:   if(size == 1) {
575:       *indices = PETSC_NULL;
576:   }
577:   else {
578:     if(!is->total) {
579:       ISGatherTotal_Private(is);
580:     }
581:     ISGetLocalSize(is,&n);
582:     ISGetSize(is,&N);
583:     PetscMalloc(sizeof(PetscInt)*(N-n), &(is->nonlocal));
584:     PetscMemcpy(is->nonlocal, is->total, sizeof(PetscInt)*is->local_offset);
585:     PetscMemcpy(is->nonlocal+is->local_offset, is->total+is->local_offset+n, sizeof(PetscInt)*(N - is->local_offset - n));
586:     *indices = is->nonlocal;
587:   }
588:   return(0);
589: }

593: /*@C
594:    ISRestoreTotalIndices - Restore the index array obtained with ISGetNonlocalIndices().

596:    Not Collective.

598:    Input Parameter:
599: +  is - the index set
600: -  indices - index array; must be the array obtained with ISGetNonlocalIndices()

602:    Level: intermediate

604:    Concepts: index sets^getting nonlocal indices
605:    Concepts: index sets^restoring nonlocal indices
606: .seealso: ISGetTotalIndices(), ISGetNonlocalIndices(), ISRestoreTotalIndices()
607: @*/
608: PetscErrorCode  ISRestoreNonlocalIndices(IS is, const PetscInt *indices[])
609: {

614:   if(is->nonlocal != *indices) {
615:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Index array pointer being restored does not point to the array obtained from the IS.");
616:   }
617:   return(0);
618: }

622: /*@
623:    ISGetNonlocalIS - Gather all nonlocal indices for this IS and present 
624:                      them as another sequential index set.  


627:    Collective on IS

629:    Input Parameter:
630: .  is - the index set

632:    Output Parameter:
633: .  complement - sequential IS with indices identical to the result of
634:                 ISGetNonlocalIndices()

636:    Level: intermediate

638:    Notes: complement represents the result of ISGetNonlocalIndices as an IS.
639:           Therefore scalability issues similar to ISGetNonlocalIndices apply.
640:           The resulting IS must be restored using ISRestoreNonlocalIS().

642:    Concepts: index sets^getting nonlocal indices
643: .seealso: ISGetNonlocalIndices(), ISRestoreNonlocalIndices(),  ISAllGather(), ISGetSize()
644: @*/
645: PetscErrorCode  ISGetNonlocalIS(IS is, IS *complement)
646: {

652:   /* Check if the complement exists already. */
653:   if(is->complement) {
654:     *complement = is->complement;
655:     PetscObjectReference((PetscObject)(is->complement));
656:   }
657:   else {
658:     PetscInt       N, n;
659:     const PetscInt *idx;
660:     ISGetSize(is, &N);
661:     ISGetLocalSize(is,&n);
662:     ISGetNonlocalIndices(is, &idx);
663:     ISCreateGeneral(PETSC_COMM_SELF, N-n,idx, PETSC_USE_POINTER, &(is->complement));
664:     PetscObjectReference((PetscObject)is->complement);
665:     *complement = is->complement;
666:   }
667:   return(0);
668: }


673: /*@
674:    ISRestoreNonlocalIS - Restore the IS obtained with ISGetNonlocalIS().

676:    Not collective.

678:    Input Parameter:
679: +  is         - the index set
680: -  complement - index set of is's nonlocal indices

682:    Level: intermediate


685:    Concepts: index sets^getting nonlocal indices
686:    Concepts: index sets^restoring nonlocal indices
687: .seealso: ISGetNonlocalIS(), ISGetNonlocalIndices(), ISRestoreNonlocalIndices()
688: @*/
689: PetscErrorCode  ISRestoreNonlocalIS(IS is, IS *complement)
690: {
692:   PetscInt       refcnt;

697:   if(*complement != is->complement) {
698:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Complement IS being restored was not obtained with ISGetNonlocalIS()");
699:   }
700:   PetscObjectGetReference((PetscObject)(is->complement), &refcnt);
701:   if(refcnt <= 1) {
702:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Duplicate call to ISRestoreNonlocalIS() detected");
703:   }
704:   PetscObjectDereference((PetscObject)(is->complement));
705:   return(0);
706: }

710: /*@C
711:    ISView - Displays an index set.

713:    Collective on IS

715:    Input Parameters:
716: +  is - the index set
717: -  viewer - viewer used to display the set, for example PETSC_VIEWER_STDOUT_SELF.

719:    Level: intermediate

721: .seealso: PetscViewerASCIIOpen()
722: @*/
723: PetscErrorCode  ISView(IS is,PetscViewer viewer)
724: {

729:   if (!viewer) {
730:     PetscViewerASCIIGetStdout(((PetscObject)is)->comm,&viewer);
731:   }
734: 
735:   (*is->ops->view)(is,viewer);
736:   return(0);
737: }

741: /*@
742:    ISSort - Sorts the indices of an index set.

744:    Collective on IS

746:    Input Parameters:
747: .  is - the index set

749:    Level: intermediate

751:    Concepts: index sets^sorting
752:    Concepts: sorting^index set

754: .seealso: ISSorted()
755: @*/
756: PetscErrorCode  ISSort(IS is)
757: {

762:   (*is->ops->sort)(is);
763:   return(0);
764: }

768: /*@
769:    ISToGeneral - Converts an IS object of any type to ISGENERAL type

771:    Collective on IS

773:    Input Parameters:
774: .  is - the index set

776:    Level: intermediate

778:    Concepts: index sets^sorting
779:    Concepts: sorting^index set

781: .seealso: ISSorted()
782: @*/
783: PetscErrorCode  ISToGeneral(IS is)
784: {

789:   if (is->ops->togeneral) {
790:     (*is->ops->togeneral)(is);
791:   } else SETERRQ1(((PetscObject)is)->comm,PETSC_ERR_SUP,"Not written for this type %s",((PetscObject)is)->type_name);
792:   return(0);
793: }

797: /*@
798:    ISSorted - Checks the indices to determine whether they have been sorted.

800:    Collective on IS

802:    Input Parameter:
803: .  is - the index set

805:    Output Parameter:
806: .  flg - output flag, either PETSC_TRUE if the index set is sorted, 
807:          or PETSC_FALSE otherwise.

809:    Notes: For parallel IS objects this only indicates if the local part of the IS
810:           is sorted. So some processors may return PETSC_TRUE while others may 
811:           return PETSC_FALSE.

813:    Level: intermediate

815: .seealso: ISSort()
816: @*/
817: PetscErrorCode  ISSorted(IS is,PetscBool  *flg)
818: {

824:   (*is->ops->sorted)(is,flg);
825:   return(0);
826: }

830: /*@
831:    ISDuplicate - Creates a duplicate copy of an index set.

833:    Collective on IS

835:    Input Parmeters:
836: .  is - the index set

838:    Output Parameters:
839: .  isnew - the copy of the index set

841:    Notes:
842:    ISDuplicate() does not copy the index set, but rather allocates storage
843:    for the new one.  Use ISCopy() to copy an index set.

845:    Level: beginner

847:    Concepts: index sets^duplicating

849: .seealso: ISCreateGeneral(), ISCopy()
850: @*/
851: PetscErrorCode  ISDuplicate(IS is,IS *newIS)
852: {

858:   (*is->ops->duplicate)(is,newIS);
859:   return(0);
860: }

864: /*@
865:    ISCopy - Copies an index set.

867:    Collective on IS

869:    Input Parmeters:
870: .  is - the index set

872:    Output Parameters:
873: .  isy - the copy of the index set

875:    Level: beginner

877:    Concepts: index sets^copying

879: .seealso: ISDuplicate()
880: @*/
881: PetscErrorCode  ISCopy(IS is,IS isy)
882: {

889:   if (is == isy) return(0);
890:   (*is->ops->copy)(is,isy);
891:   isy->isperm     = is->isperm;
892:   isy->max        = is->max;
893:   isy->min        = is->min;
894:   isy->isidentity = is->isidentity;
895:   return(0);
896: }

900: /*@
901:    ISOnComm - Split a parallel IS on subcomms (usually self) or concatenate index sets on subcomms into a parallel index set

903:    Collective on IS and comm

905:    Input Arguments:
906: + is - index set
907: . comm - communicator for new index set
908: - mode - copy semantics, PETSC_USE_POINTER for no-copy if possible, otherwise PETSC_COPY_VALUES

910:    Output Arguments:
911: . newis - new IS on comm

913:    Level: advanced

915:    Notes:
916:    It is usually desirable to create a parallel IS and look at the local part when necessary.

918:    This function is useful if serial ISs must be created independently, or to view many
919:    logically independent serial ISs.

921:    The input IS must have the same type on every process.

923: .seealso: ISSplit()
924: @*/
925: PetscErrorCode  ISOnComm(IS is,MPI_Comm comm,PetscCopyMode mode,IS *newis)
926: {
928:   PetscMPIInt match;

933:   MPI_Comm_compare(((PetscObject)is)->comm,comm,&match);
934:   if (mode != PETSC_COPY_VALUES && (match == MPI_IDENT || match == MPI_CONGRUENT)) {
935:     PetscObjectReference((PetscObject)is);
936:     *newis = is;
937:   } else {
938:     (*is->ops->oncomm)(is,comm,mode,newis);
939:   }
940:   return(0);
941: }

945: /*@
946:    ISSetBlockSize - informs an index set that it has a given block size

948:    Logicall Collective on IS

950:    Input Arguments:
951: + is - index set
952: - bs - block size

954:    Level: intermediate

956: .seealso: ISGetBlockSize(), ISCreateBlock()
957: @*/
958: PetscErrorCode  ISSetBlockSize(IS is,PetscInt bs)
959: {

965:   if (bs < 1) SETERRQ1(((PetscObject)is)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
966:   (*is->ops->setblocksize)(is,bs);
967:   return(0);
968: }

972: /*@
973:    ISGetBlockSize - Returns the number of elements in a block.

975:    Not Collective

977:    Input Parameter:
978: .  is - the index set

980:    Output Parameter:
981: .  size - the number of elements in a block

983:    Level: intermediate

985:    Concepts: IS^block size
986:    Concepts: index sets^block size

988: .seealso: ISBlockGetSize(), ISGetSize(), ISCreateBlock(), ISSetBlockSize()
989: @*/
990: PetscErrorCode  ISGetBlockSize(IS is,PetscInt *size)
991: {
993:   *size = is->bs;
994:   return(0);
995: }

997: #if defined(PETSC_HAVE_MATLAB_ENGINE)
998: #include <engine.h>   /* MATLAB include file */
999: #include <mex.h>      /* MATLAB include file */
1003: PetscErrorCode ISGetIndicesMatlab(IS is, PetscInt idx[])
1004: {
1006:   PetscInt       len,i;
1007:   const PetscInt *ptr;

1010:   ISGetSize(is,&len);
1011:   ISGetIndices(is,&ptr);
1012:   for(i=0;i<len;i++) idx[i] = ptr[i];
1013:   ISRestoreIndices(is,&ptr);
1014:   return(0);
1015: }
1017: #endif

1019: /*MC
1020:     ISGetIndicesF90 - Accesses the elements of an index set from Fortran90.
1021:     The users should call ISRestoreIndicesF90() after having looked at the
1022:     indices.  The user should NOT change the indices.

1024:     Synopsis:
1025:     ISGetIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1027:     Not collective

1029:     Input Parameter:
1030: .   x - index set

1032:     Output Parameters:
1033: +   xx_v - the Fortran90 pointer to the array
1034: -   ierr - error code

1036:     Example of Usage: 
1037: .vb
1038:     PetscScalar, pointer xx_v(:)
1039:     ....
1040:     call ISGetIndicesF90(x,xx_v,ierr)
1041:     a = xx_v(3)
1042:     call ISRestoreIndicesF90(x,xx_v,ierr)
1043: .ve

1045:     Notes:
1046:     Not yet supported for all F90 compilers.

1048:     Level: intermediate

1050: .seealso:  ISRestoreIndicesF90(), ISGetIndices(), ISRestoreIndices()

1052:   Concepts: index sets^getting indices in f90
1053:   Concepts: indices of index set in f90

1055: M*/

1057: /*MC
1058:     ISRestoreIndicesF90 - Restores an index set to a usable state after
1059:     a call to ISGetIndicesF90().

1061:     Synopsis:
1062:     ISRestoreIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1064:     Not collective

1066:     Input Parameters:
1067: .   x - index set
1068: .   xx_v - the Fortran90 pointer to the array

1070:     Output Parameter:
1071: .   ierr - error code


1074:     Example of Usage: 
1075: .vb
1076:     PetscScalar, pointer xx_v(:)
1077:     ....
1078:     call ISGetIndicesF90(x,xx_v,ierr)
1079:     a = xx_v(3)
1080:     call ISRestoreIndicesF90(x,xx_v,ierr)
1081: .ve
1082:    
1083:     Notes:
1084:     Not yet supported for all F90 compilers.

1086:     Level: intermediate

1088: .seealso:  ISGetIndicesF90(), ISGetIndices(), ISRestoreIndices()

1090: M*/

1092: /*MC
1093:     ISBlockGetIndicesF90 - Accesses the elements of an index set from Fortran90.
1094:     The users should call ISBlockRestoreIndicesF90() after having looked at the
1095:     indices.  The user should NOT change the indices.

1097:     Synopsis:
1098:     ISBlockGetIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1100:     Not collective

1102:     Input Parameter:
1103: .   x - index set

1105:     Output Parameters:
1106: +   xx_v - the Fortran90 pointer to the array
1107: -   ierr - error code
1108:     Example of Usage: 
1109: .vb
1110:     PetscScalar, pointer xx_v(:)
1111:     ....
1112:     call ISBlockGetIndicesF90(x,xx_v,ierr)
1113:     a = xx_v(3)
1114:     call ISBlockRestoreIndicesF90(x,xx_v,ierr)
1115: .ve

1117:     Notes:
1118:     Not yet supported for all F90 compilers

1120:     Level: intermediate

1122: .seealso:  ISBlockRestoreIndicesF90(), ISGetIndices(), ISRestoreIndices(),
1123:            ISRestoreIndices()

1125:   Concepts: index sets^getting block indices in f90
1126:   Concepts: indices of index set in f90
1127:   Concepts: block^ indices of index set in f90

1129: M*/

1131: /*MC
1132:     ISBlockRestoreIndicesF90 - Restores an index set to a usable state after
1133:     a call to ISBlockGetIndicesF90().

1135:     Synopsis:
1136:     ISBlockRestoreIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1138:     Not Collective

1140:     Input Parameters:
1141: +   x - index set
1142: -   xx_v - the Fortran90 pointer to the array

1144:     Output Parameter:
1145: .   ierr - error code

1147:     Example of Usage: 
1148: .vb
1149:     PetscScalar, pointer xx_v(:)
1150:     ....
1151:     call ISBlockGetIndicesF90(x,xx_v,ierr)
1152:     a = xx_v(3)
1153:     call ISBlockRestoreIndicesF90(x,xx_v,ierr)
1154: .ve
1155:    
1156:     Notes:
1157:     Not yet supported for all F90 compilers

1159:     Level: intermediate

1161: .seealso:  ISBlockGetIndicesF90(), ISGetIndices(), ISRestoreIndices(), ISRestoreIndicesF90()

1163: M*/