Actual source code: index.c

petsc-dev 2014-02-02
Report Typos and Errors
  2: /*
  3:    Defines the abstract operations on index sets, i.e. the public interface.
  4: */
  5: #include <petsc-private/isimpl.h>      /*I "petscis.h" I*/
  6: #include <petscviewer.h>

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

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

 16:    Collective on IS

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

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

 24:    Level: intermediate

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

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

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

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

 51:    Logically Collective on IS

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

 56:    Level: intermediate

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

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

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

 76:    Not Collective

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

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

 87:    Level: developer

 89:    Concepts: index sets^is contiguous

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

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

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

116:    Logically Collective on IS

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

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

124:    Level: intermediate

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

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

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

145:    Logically Collective on IS

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

150:    Level: intermediate

152:   Concepts: permutation
153:   Concepts: index sets^permutation

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

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

169:     MPI_Comm_size(PetscObjectComm((PetscObject)is),&size);
170:     if (size == 1) {
171:       PetscInt       i,n,*idx;
172:       const PetscInt *iidx;

174:       ISGetSize(is,&n);
175:       PetscMalloc1(n,&idx);
176:       ISGetIndices(is,&iidx);
177:       PetscMemcpy(idx,iidx,n*sizeof(PetscInt));
178:       PetscSortInt(n,idx);
179:       for (i=0; i<n; i++) {
180:         if (idx[i] != i) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Index set is not a permutation");
181:       }
182:       PetscFree(idx);
183:       ISRestoreIndices(is,&iidx);
184:     }
185:   }
186: #endif
187:   is->isperm = PETSC_TRUE;
188:   return(0);
189: }

193: /*@
194:    ISDestroy - Destroys an index set.

196:    Collective on IS

198:    Input Parameters:
199: .  is - the index set

201:    Level: beginner

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

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

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

235:    Collective on IS

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

242:    Output Parameter:
243: .  isout - the inverse permutation

245:    Level: intermediate

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

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

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

269: /*@
270:    ISGetSize - Returns the global length of an index set.

272:    Not Collective

274:    Input Parameter:
275: .  is - the index set

277:    Output Parameter:
278: .  size - the global size

280:    Level: beginner

282:    Concepts: size^of index set
283:    Concepts: index sets^size

285: @*/
286: PetscErrorCode  ISGetSize(IS is,PetscInt *size)
287: {

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

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

302:    Not Collective

304:    Input Parameter:
305: .  is - the index set

307:    Output Parameter:
308: .  size - the local size

310:    Level: beginner

312:    Concepts: size^of index set
313:    Concepts: local size^of index set
314:    Concepts: index sets^local size

316: @*/
317: PetscErrorCode  ISGetLocalSize(IS is,PetscInt *size)
318: {

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

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

335:    Not Collective

337:    Input Parameter:
338: .  is - the index set

340:    Output Parameter:
341: .  ptr - the location to put the pointer to the indices

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

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

360:    Level: intermediate

362:    Concepts: index sets^getting indices
363:    Concepts: indices of index set

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

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

380: /*@C
381:    ISGetMinMax - Gets the minimum and maximum values in an IS

383:    Not Collective

385:    Input Parameter:
386: .  is - the index set

388:    Output Parameter:
389: +   min - the minimum value
390: -   max - the maximum value

392:    Level: intermediate

394:    Concepts: index sets^getting indices
395:    Concepts: indices of index set

397: .seealso: ISGetIndices(), ISRestoreIndices(), ISGetIndicesF90()
398: @*/
399: PetscErrorCode  ISGetMinMax(IS is,PetscInt *min,PetscInt *max)
400: {
403:   if (min) *min = is->min;
404:   if (max) *max = is->max;
405:   return(0);
406: }

410: /*@C
411:    ISRestoreIndices - Restores an index set to a usable state after a call
412:                       to ISGetIndices().

414:    Not Collective

416:    Input Parameters:
417: +  is - the index set
418: -  ptr - the pointer obtained by ISGetIndices()

420:    Fortran Note:
421:    This routine is used differently from Fortran
422: $    IS          is
423: $    integer     is_array(1)
424: $    PetscOffset i_is
425: $    int         ierr
426: $       call ISGetIndices(is,is_array,i_is,ierr)
427: $
428: $   Access first local entry in list
429: $      value = is_array(i_is + 1)
430: $
431: $      ...... other code
432: $       call ISRestoreIndices(is,is_array,i_is,ierr)

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

437:    Level: intermediate

439:    Note:
440:    This routine zeros out ptr. This is to prevent accidental us of the array after it has been restored.

442: .seealso: ISGetIndices(), ISRestoreIndicesF90()
443: @*/
444: PetscErrorCode  ISRestoreIndices(IS is,const PetscInt *ptr[])
445: {

451:   if (is->ops->restoreindices) {
452:     (*is->ops->restoreindices)(is,ptr);
453:   }
454:   return(0);
455: }

459: static PetscErrorCode ISGatherTotal_Private(IS is)
460: {
462:   PetscInt       i,n,N;
463:   const PetscInt *lindices;
464:   MPI_Comm       comm;
465:   PetscMPIInt    rank,size,*sizes = NULL,*offsets = NULL,nn;


470:   PetscObjectGetComm((PetscObject)is,&comm);
471:   MPI_Comm_size(comm,&size);
472:   MPI_Comm_rank(comm,&rank);
473:   ISGetLocalSize(is,&n);
474:   PetscMalloc2(size,&sizes,size,&offsets);

476:   PetscMPIIntCast(n,&nn);
477:   MPI_Allgather(&nn,1,MPI_INT,sizes,1,MPI_INT,comm);
478:   offsets[0] = 0;
479:   for (i=1; i<size; ++i) offsets[i] = offsets[i-1] + sizes[i-1];
480:   N = offsets[size-1] + sizes[size-1];

482:   PetscMalloc1(N,&(is->total));
483:   ISGetIndices(is,&lindices);
484:   MPI_Allgatherv((void*)lindices,nn,MPIU_INT,is->total,sizes,offsets,MPIU_INT,comm);
485:   ISRestoreIndices(is,&lindices);
486:   is->local_offset = offsets[rank];
487:   PetscFree2(sizes,offsets);
488:   return(0);
489: }

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

496:    Collective on IS

498:    Input Parameter:
499: .  is - the index set

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

505:    Level: intermediate

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

514:    Concepts: index sets^getting nonlocal indices
515: .seealso: ISRestoreTotalIndices(), ISGetNonlocalIndices(), ISGetSize()
516: @*/
517: PetscErrorCode ISGetTotalIndices(IS is, const PetscInt *indices[])
518: {
520:   PetscMPIInt    size;

525:   MPI_Comm_size(PetscObjectComm((PetscObject)is), &size);
526:   if (size == 1) {
527:     (*is->ops->getindices)(is,indices);
528:   } else {
529:     if (!is->total) {
530:       ISGatherTotal_Private(is);
531:     }
532:     *indices = is->total;
533:   }
534:   return(0);
535: }

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

542:    Not Collective.

544:    Input Parameter:
545: +  is - the index set
546: -  indices - index array; must be the array obtained with ISGetTotalIndices()

548:    Level: intermediate

550:    Concepts: index sets^getting nonlocal indices
551:    Concepts: index sets^restoring nonlocal indices
552: .seealso: ISRestoreTotalIndices(), ISGetNonlocalIndices()
553: @*/
554: PetscErrorCode  ISRestoreTotalIndices(IS is, const PetscInt *indices[])
555: {
557:   PetscMPIInt    size;

562:   MPI_Comm_size(PetscObjectComm((PetscObject)is), &size);
563:   if (size == 1) {
564:     (*is->ops->restoreindices)(is,indices);
565:   } else {
566:     if (is->total != *indices) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Index array pointer being restored does not point to the array obtained from the IS.");
567:   }
568:   return(0);
569: }
572: /*@C
573:    ISGetNonlocalIndices - Retrieve an array of indices from remote processors
574:                        in this communicator.

576:    Collective on IS

578:    Input Parameter:
579: .  is - the index set

581:    Output Parameter:
582: .  indices - indices with rank 0 indices first, and so on,  omitting
583:              the current rank.  Total number of indices is the difference
584:              total and local, obtained with ISGetSize() and ISGetLocalSize(),
585:              respectively.

587:    Level: intermediate

589:    Notes: restore the indices using ISRestoreNonlocalIndices().
590:           The same scalability considerations as those for ISGetTotalIndices
591:           apply here.

593:    Concepts: index sets^getting nonlocal indices
594: .seealso: ISGetTotalIndices(), ISRestoreNonlocalIndices(), ISGetSize(), ISGetLocalSize().
595: @*/
596: PetscErrorCode  ISGetNonlocalIndices(IS is, const PetscInt *indices[])
597: {
599:   PetscMPIInt    size;
600:   PetscInt       n, N;

605:   MPI_Comm_size(PetscObjectComm((PetscObject)is), &size);
606:   if (size == 1) *indices = NULL;
607:   else {
608:     if (!is->total) {
609:       ISGatherTotal_Private(is);
610:     }
611:     ISGetLocalSize(is,&n);
612:     ISGetSize(is,&N);
613:     PetscMalloc(sizeof(PetscInt)*(N-n), &(is->nonlocal));
614:     PetscMemcpy(is->nonlocal, is->total, sizeof(PetscInt)*is->local_offset);
615:     PetscMemcpy(is->nonlocal+is->local_offset, is->total+is->local_offset+n, sizeof(PetscInt)*(N - is->local_offset - n));
616:     *indices = is->nonlocal;
617:   }
618:   return(0);
619: }

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

626:    Not Collective.

628:    Input Parameter:
629: +  is - the index set
630: -  indices - index array; must be the array obtained with ISGetNonlocalIndices()

632:    Level: intermediate

634:    Concepts: index sets^getting nonlocal indices
635:    Concepts: index sets^restoring nonlocal indices
636: .seealso: ISGetTotalIndices(), ISGetNonlocalIndices(), ISRestoreTotalIndices()
637: @*/
638: PetscErrorCode  ISRestoreNonlocalIndices(IS is, const PetscInt *indices[])
639: {
643:   if (is->nonlocal != *indices) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Index array pointer being restored does not point to the array obtained from the IS.");
644:   return(0);
645: }

649: /*@
650:    ISGetNonlocalIS - Gather all nonlocal indices for this IS and present
651:                      them as another sequential index set.


654:    Collective on IS

656:    Input Parameter:
657: .  is - the index set

659:    Output Parameter:
660: .  complement - sequential IS with indices identical to the result of
661:                 ISGetNonlocalIndices()

663:    Level: intermediate

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

669:    Concepts: index sets^getting nonlocal indices
670: .seealso: ISGetNonlocalIndices(), ISRestoreNonlocalIndices(),  ISAllGather(), ISGetSize()
671: @*/
672: PetscErrorCode  ISGetNonlocalIS(IS is, IS *complement)
673: {

679:   /* Check if the complement exists already. */
680:   if (is->complement) {
681:     *complement = is->complement;
682:     PetscObjectReference((PetscObject)(is->complement));
683:   } else {
684:     PetscInt       N, n;
685:     const PetscInt *idx;
686:     ISGetSize(is, &N);
687:     ISGetLocalSize(is,&n);
688:     ISGetNonlocalIndices(is, &idx);
689:     ISCreateGeneral(PETSC_COMM_SELF, N-n,idx, PETSC_USE_POINTER, &(is->complement));
690:     PetscObjectReference((PetscObject)is->complement);
691:     *complement = is->complement;
692:   }
693:   return(0);
694: }


699: /*@
700:    ISRestoreNonlocalIS - Restore the IS obtained with ISGetNonlocalIS().

702:    Not collective.

704:    Input Parameter:
705: +  is         - the index set
706: -  complement - index set of is's nonlocal indices

708:    Level: intermediate


711:    Concepts: index sets^getting nonlocal indices
712:    Concepts: index sets^restoring nonlocal indices
713: .seealso: ISGetNonlocalIS(), ISGetNonlocalIndices(), ISRestoreNonlocalIndices()
714: @*/
715: PetscErrorCode  ISRestoreNonlocalIS(IS is, IS *complement)
716: {
718:   PetscInt       refcnt;

723:   if (*complement != is->complement) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Complement IS being restored was not obtained with ISGetNonlocalIS()");
724:   PetscObjectGetReference((PetscObject)(is->complement), &refcnt);
725:   if (refcnt <= 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Duplicate call to ISRestoreNonlocalIS() detected");
726:   PetscObjectDereference((PetscObject)(is->complement));
727:   return(0);
728: }

732: /*@C
733:    ISView - Displays an index set.

735:    Collective on IS

737:    Input Parameters:
738: +  is - the index set
739: -  viewer - viewer used to display the set, for example PETSC_VIEWER_STDOUT_SELF.

741:    Level: intermediate

743: .seealso: PetscViewerASCIIOpen()
744: @*/
745: PetscErrorCode  ISView(IS is,PetscViewer viewer)
746: {

751:   if (!viewer) {
752:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)is),&viewer);
753:   }

757:   (*is->ops->view)(is,viewer);
758:   return(0);
759: }

763: /*@
764:    ISSort - Sorts the indices of an index set.

766:    Collective on IS

768:    Input Parameters:
769: .  is - the index set

771:    Level: intermediate

773:    Concepts: index sets^sorting
774:    Concepts: sorting^index set

776: .seealso: ISSorted()
777: @*/
778: PetscErrorCode  ISSort(IS is)
779: {

784:   (*is->ops->sort)(is);
785:   return(0);
786: }

790: /*@
791:    ISToGeneral - Converts an IS object of any type to ISGENERAL type

793:    Collective on IS

795:    Input Parameters:
796: .  is - the index set

798:    Level: intermediate

800:    Concepts: index sets^sorting
801:    Concepts: sorting^index set

803: .seealso: ISSorted()
804: @*/
805: PetscErrorCode  ISToGeneral(IS is)
806: {

811:   if (is->ops->togeneral) {
812:     (*is->ops->togeneral)(is);
813:   } else SETERRQ1(PetscObjectComm((PetscObject)is),PETSC_ERR_SUP,"Not written for this type %s",((PetscObject)is)->type_name);
814:   return(0);
815: }

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

822:    Collective on IS

824:    Input Parameter:
825: .  is - the index set

827:    Output Parameter:
828: .  flg - output flag, either PETSC_TRUE if the index set is sorted,
829:          or PETSC_FALSE otherwise.

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

835:    Level: intermediate

837: .seealso: ISSort()
838: @*/
839: PetscErrorCode  ISSorted(IS is,PetscBool  *flg)
840: {

846:   (*is->ops->sorted)(is,flg);
847:   return(0);
848: }

852: /*@
853:    ISDuplicate - Creates a duplicate copy of an index set.

855:    Collective on IS

857:    Input Parmeters:
858: .  is - the index set

860:    Output Parameters:
861: .  isnew - the copy of the index set

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

867:    Level: beginner

869:    Concepts: index sets^duplicating

871: .seealso: ISCreateGeneral(), ISCopy()
872: @*/
873: PetscErrorCode  ISDuplicate(IS is,IS *newIS)
874: {

880:   (*is->ops->duplicate)(is,newIS);
881:   return(0);
882: }

886: /*@
887:    ISCopy - Copies an index set.

889:    Collective on IS

891:    Input Parmeters:
892: .  is - the index set

894:    Output Parameters:
895: .  isy - the copy of the index set

897:    Level: beginner

899:    Concepts: index sets^copying

901: .seealso: ISDuplicate()
902: @*/
903: PetscErrorCode  ISCopy(IS is,IS isy)
904: {

911:   if (is == isy) return(0);
912:   (*is->ops->copy)(is,isy);
913:   isy->isperm     = is->isperm;
914:   isy->max        = is->max;
915:   isy->min        = is->min;
916:   isy->isidentity = is->isidentity;
917:   return(0);
918: }

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

925:    Collective on IS and comm

927:    Input Arguments:
928: + is - index set
929: . comm - communicator for new index set
930: - mode - copy semantics, PETSC_USE_POINTER for no-copy if possible, otherwise PETSC_COPY_VALUES

932:    Output Arguments:
933: . newis - new IS on comm

935:    Level: advanced

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

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

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

945: .seealso: ISSplit()
946: @*/
947: PetscErrorCode  ISOnComm(IS is,MPI_Comm comm,PetscCopyMode mode,IS *newis)
948: {
950:   PetscMPIInt    match;

955:   MPI_Comm_compare(PetscObjectComm((PetscObject)is),comm,&match);
956:   if (mode != PETSC_COPY_VALUES && (match == MPI_IDENT || match == MPI_CONGRUENT)) {
957:     PetscObjectReference((PetscObject)is);
958:     *newis = is;
959:   } else {
960:     (*is->ops->oncomm)(is,comm,mode,newis);
961:   }
962:   return(0);
963: }

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

970:    Logicall Collective on IS

972:    Input Arguments:
973: + is - index set
974: - bs - block size

976:    Level: intermediate

978: .seealso: ISGetBlockSize(), ISCreateBlock()
979: @*/
980: PetscErrorCode  ISSetBlockSize(IS is,PetscInt bs)
981: {

987:   if (bs < 1) SETERRQ1(PetscObjectComm((PetscObject)is),PETSC_ERR_ARG_OUTOFRANGE,"Block size %D, must be positive",bs);
988:   (*is->ops->setblocksize)(is,bs);
989:   return(0);
990: }

994: /*@
995:    ISGetBlockSize - Returns the number of elements in a block.

997:    Not Collective

999:    Input Parameter:
1000: .  is - the index set

1002:    Output Parameter:
1003: .  size - the number of elements in a block

1005:    Level: intermediate

1007:    Concepts: IS^block size
1008:    Concepts: index sets^block size

1010: .seealso: ISBlockGetSize(), ISGetSize(), ISCreateBlock(), ISSetBlockSize()
1011: @*/
1012: PetscErrorCode  ISGetBlockSize(IS is,PetscInt *size)
1013: {
1015:   *size = is->bs;
1016:   return(0);
1017: }

1021: PetscErrorCode ISGetIndicesCopy(IS is, PetscInt idx[])
1022: {
1024:   PetscInt       len,i;
1025:   const PetscInt *ptr;

1028:   ISGetSize(is,&len);
1029:   ISGetIndices(is,&ptr);
1030:   for (i=0; i<len; i++) idx[i] = ptr[i];
1031:   ISRestoreIndices(is,&ptr);
1032:   return(0);
1033: }

1035: /*MC
1036:     ISGetIndicesF90 - Accesses the elements of an index set from Fortran90.
1037:     The users should call ISRestoreIndicesF90() after having looked at the
1038:     indices.  The user should NOT change the indices.

1040:     Synopsis:
1041:     ISGetIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1043:     Not collective

1045:     Input Parameter:
1046: .   x - index set

1048:     Output Parameters:
1049: +   xx_v - the Fortran90 pointer to the array
1050: -   ierr - error code

1052:     Example of Usage:
1053: .vb
1054:     PetscScalar, pointer xx_v(:)
1055:     ....
1056:     call ISGetIndicesF90(x,xx_v,ierr)
1057:     a = xx_v(3)
1058:     call ISRestoreIndicesF90(x,xx_v,ierr)
1059: .ve

1061:     Notes:
1062:     Not yet supported for all F90 compilers.

1064:     Level: intermediate

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

1068:   Concepts: index sets^getting indices in f90
1069:   Concepts: indices of index set in f90

1071: M*/

1073: /*MC
1074:     ISRestoreIndicesF90 - Restores an index set to a usable state after
1075:     a call to ISGetIndicesF90().

1077:     Synopsis:
1078:     ISRestoreIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1080:     Not collective

1082:     Input Parameters:
1083: .   x - index set
1084: .   xx_v - the Fortran90 pointer to the array

1086:     Output Parameter:
1087: .   ierr - error code


1090:     Example of Usage:
1091: .vb
1092:     PetscScalar, pointer xx_v(:)
1093:     ....
1094:     call ISGetIndicesF90(x,xx_v,ierr)
1095:     a = xx_v(3)
1096:     call ISRestoreIndicesF90(x,xx_v,ierr)
1097: .ve

1099:     Notes:
1100:     Not yet supported for all F90 compilers.

1102:     Level: intermediate

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

1106: M*/

1108: /*MC
1109:     ISBlockGetIndicesF90 - Accesses the elements of an index set from Fortran90.
1110:     The users should call ISBlockRestoreIndicesF90() after having looked at the
1111:     indices.  The user should NOT change the indices.

1113:     Synopsis:
1114:     ISBlockGetIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1116:     Not collective

1118:     Input Parameter:
1119: .   x - index set

1121:     Output Parameters:
1122: +   xx_v - the Fortran90 pointer to the array
1123: -   ierr - error code
1124:     Example of Usage:
1125: .vb
1126:     PetscScalar, pointer xx_v(:)
1127:     ....
1128:     call ISBlockGetIndicesF90(x,xx_v,ierr)
1129:     a = xx_v(3)
1130:     call ISBlockRestoreIndicesF90(x,xx_v,ierr)
1131: .ve

1133:     Notes:
1134:     Not yet supported for all F90 compilers

1136:     Level: intermediate

1138: .seealso:  ISBlockRestoreIndicesF90(), ISGetIndices(), ISRestoreIndices(),
1139:            ISRestoreIndices()

1141:   Concepts: index sets^getting block indices in f90
1142:   Concepts: indices of index set in f90
1143:   Concepts: block^ indices of index set in f90

1145: M*/

1147: /*MC
1148:     ISBlockRestoreIndicesF90 - Restores an index set to a usable state after
1149:     a call to ISBlockGetIndicesF90().

1151:     Synopsis:
1152:     ISBlockRestoreIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1154:     Not Collective

1156:     Input Parameters:
1157: +   x - index set
1158: -   xx_v - the Fortran90 pointer to the array

1160:     Output Parameter:
1161: .   ierr - error code

1163:     Example of Usage:
1164: .vb
1165:     PetscScalar, pointer xx_v(:)
1166:     ....
1167:     call ISBlockGetIndicesF90(x,xx_v,ierr)
1168:     a = xx_v(3)
1169:     call ISBlockRestoreIndicesF90(x,xx_v,ierr)
1170: .ve

1172:     Notes:
1173:     Not yet supported for all F90 compilers

1175:     Level: intermediate

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

1179: M*/