Actual source code: index.c

petsc-3.4.5 2014-06-29
  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:       PetscMalloc(n*sizeof(PetscInt),&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: .seealso: ISGetIndices(), ISRestoreIndicesF90()
440: @*/
441: PetscErrorCode  ISRestoreIndices(IS is,const PetscInt *ptr[])
442: {

448:   if (is->ops->restoreindices) {
449:     (*is->ops->restoreindices)(is,ptr);
450:   }
451:   return(0);
452: }

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


467:   PetscObjectGetComm((PetscObject)is,&comm);
468:   MPI_Comm_size(comm,&size);
469:   MPI_Comm_rank(comm,&rank);
470:   ISGetLocalSize(is,&n);
471:   PetscMalloc2(size,PetscMPIInt,&sizes,size,PetscMPIInt,&offsets);

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

479:   PetscMalloc(N*sizeof(PetscInt),&(is->total));
480:   ISGetIndices(is,&lindices);
481:   MPI_Allgatherv((void*)lindices,nn,MPIU_INT,is->total,sizes,offsets,MPIU_INT,comm);
482:   ISRestoreIndices(is,&lindices);
483:   is->local_offset = offsets[rank];
484:   PetscFree2(sizes,offsets);
485:   return(0);
486: }

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

493:    Collective on IS

495:    Input Parameter:
496: .  is - the index set

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

502:    Level: intermediate

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

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

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

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

539:    Not Collective.

541:    Input Parameter:
542: +  is - the index set
543: -  indices - index array; must be the array obtained with ISGetTotalIndices()

545:    Level: intermediate

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

559:   MPI_Comm_size(PetscObjectComm((PetscObject)is), &size);
560:   if (size == 1) {
561:     (*is->ops->restoreindices)(is,indices);
562:   } else {
563:     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.");
564:   }
565:   return(0);
566: }
569: /*@C
570:    ISGetNonlocalIndices - Retrieve an array of indices from remote processors
571:                        in this communicator.

573:    Collective on IS

575:    Input Parameter:
576: .  is - the index set

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

584:    Level: intermediate

586:    Notes: restore the indices using ISRestoreNonlocalIndices().
587:           The same scalability considerations as those for ISGetTotalIndices
588:           apply here.

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

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

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

623:    Not Collective.

625:    Input Parameter:
626: +  is - the index set
627: -  indices - index array; must be the array obtained with ISGetNonlocalIndices()

629:    Level: intermediate

631:    Concepts: index sets^getting nonlocal indices
632:    Concepts: index sets^restoring nonlocal indices
633: .seealso: ISGetTotalIndices(), ISGetNonlocalIndices(), ISRestoreTotalIndices()
634: @*/
635: PetscErrorCode  ISRestoreNonlocalIndices(IS is, const PetscInt *indices[])
636: {
640:   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.");
641:   return(0);
642: }

646: /*@
647:    ISGetNonlocalIS - Gather all nonlocal indices for this IS and present
648:                      them as another sequential index set.


651:    Collective on IS

653:    Input Parameter:
654: .  is - the index set

656:    Output Parameter:
657: .  complement - sequential IS with indices identical to the result of
658:                 ISGetNonlocalIndices()

660:    Level: intermediate

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

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

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


696: /*@
697:    ISRestoreNonlocalIS - Restore the IS obtained with ISGetNonlocalIS().

699:    Not collective.

701:    Input Parameter:
702: +  is         - the index set
703: -  complement - index set of is's nonlocal indices

705:    Level: intermediate


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

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

729: /*@C
730:    ISView - Displays an index set.

732:    Collective on IS

734:    Input Parameters:
735: +  is - the index set
736: -  viewer - viewer used to display the set, for example PETSC_VIEWER_STDOUT_SELF.

738:    Level: intermediate

740: .seealso: PetscViewerASCIIOpen()
741: @*/
742: PetscErrorCode  ISView(IS is,PetscViewer viewer)
743: {

748:   if (!viewer) {
749:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)is),&viewer);
750:   }

754:   (*is->ops->view)(is,viewer);
755:   return(0);
756: }

760: /*@
761:    ISSort - Sorts the indices of an index set.

763:    Collective on IS

765:    Input Parameters:
766: .  is - the index set

768:    Level: intermediate

770:    Concepts: index sets^sorting
771:    Concepts: sorting^index set

773: .seealso: ISSorted()
774: @*/
775: PetscErrorCode  ISSort(IS is)
776: {

781:   (*is->ops->sort)(is);
782:   return(0);
783: }

787: /*@
788:    ISToGeneral - Converts an IS object of any type to ISGENERAL type

790:    Collective on IS

792:    Input Parameters:
793: .  is - the index set

795:    Level: intermediate

797:    Concepts: index sets^sorting
798:    Concepts: sorting^index set

800: .seealso: ISSorted()
801: @*/
802: PetscErrorCode  ISToGeneral(IS is)
803: {

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

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

819:    Collective on IS

821:    Input Parameter:
822: .  is - the index set

824:    Output Parameter:
825: .  flg - output flag, either PETSC_TRUE if the index set is sorted,
826:          or PETSC_FALSE otherwise.

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

832:    Level: intermediate

834: .seealso: ISSort()
835: @*/
836: PetscErrorCode  ISSorted(IS is,PetscBool  *flg)
837: {

843:   (*is->ops->sorted)(is,flg);
844:   return(0);
845: }

849: /*@
850:    ISDuplicate - Creates a duplicate copy of an index set.

852:    Collective on IS

854:    Input Parmeters:
855: .  is - the index set

857:    Output Parameters:
858: .  isnew - the copy of the index set

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

864:    Level: beginner

866:    Concepts: index sets^duplicating

868: .seealso: ISCreateGeneral(), ISCopy()
869: @*/
870: PetscErrorCode  ISDuplicate(IS is,IS *newIS)
871: {

877:   (*is->ops->duplicate)(is,newIS);
878:   return(0);
879: }

883: /*@
884:    ISCopy - Copies an index set.

886:    Collective on IS

888:    Input Parmeters:
889: .  is - the index set

891:    Output Parameters:
892: .  isy - the copy of the index set

894:    Level: beginner

896:    Concepts: index sets^copying

898: .seealso: ISDuplicate()
899: @*/
900: PetscErrorCode  ISCopy(IS is,IS isy)
901: {

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

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

922:    Collective on IS and comm

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

929:    Output Arguments:
930: . newis - new IS on comm

932:    Level: advanced

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

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

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

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

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

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

967:    Logicall Collective on IS

969:    Input Arguments:
970: + is - index set
971: - bs - block size

973:    Level: intermediate

975: .seealso: ISGetBlockSize(), ISCreateBlock()
976: @*/
977: PetscErrorCode  ISSetBlockSize(IS is,PetscInt bs)
978: {

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

991: /*@
992:    ISGetBlockSize - Returns the number of elements in a block.

994:    Not Collective

996:    Input Parameter:
997: .  is - the index set

999:    Output Parameter:
1000: .  size - the number of elements in a block

1002:    Level: intermediate

1004:    Concepts: IS^block size
1005:    Concepts: index sets^block size

1007: .seealso: ISBlockGetSize(), ISGetSize(), ISCreateBlock(), ISSetBlockSize()
1008: @*/
1009: PetscErrorCode  ISGetBlockSize(IS is,PetscInt *size)
1010: {
1012:   *size = is->bs;
1013:   return(0);
1014: }

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

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

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

1037:     Synopsis:
1038:     ISGetIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1040:     Not collective

1042:     Input Parameter:
1043: .   x - index set

1045:     Output Parameters:
1046: +   xx_v - the Fortran90 pointer to the array
1047: -   ierr - error code

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

1058:     Notes:
1059:     Not yet supported for all F90 compilers.

1061:     Level: intermediate

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

1065:   Concepts: index sets^getting indices in f90
1066:   Concepts: indices of index set in f90

1068: M*/

1070: /*MC
1071:     ISRestoreIndicesF90 - Restores an index set to a usable state after
1072:     a call to ISGetIndicesF90().

1074:     Synopsis:
1075:     ISRestoreIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1077:     Not collective

1079:     Input Parameters:
1080: .   x - index set
1081: .   xx_v - the Fortran90 pointer to the array

1083:     Output Parameter:
1084: .   ierr - error code


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

1096:     Notes:
1097:     Not yet supported for all F90 compilers.

1099:     Level: intermediate

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

1103: M*/

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

1110:     Synopsis:
1111:     ISBlockGetIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1113:     Not collective

1115:     Input Parameter:
1116: .   x - index set

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

1130:     Notes:
1131:     Not yet supported for all F90 compilers

1133:     Level: intermediate

1135: .seealso:  ISBlockRestoreIndicesF90(), ISGetIndices(), ISRestoreIndices(),
1136:            ISRestoreIndices()

1138:   Concepts: index sets^getting block indices in f90
1139:   Concepts: indices of index set in f90
1140:   Concepts: block^ indices of index set in f90

1142: M*/

1144: /*MC
1145:     ISBlockRestoreIndicesF90 - Restores an index set to a usable state after
1146:     a call to ISBlockGetIndicesF90().

1148:     Synopsis:
1149:     ISBlockRestoreIndicesF90(IS x,{integer, pointer :: xx_v(:)},integer ierr)

1151:     Not Collective

1153:     Input Parameters:
1154: +   x - index set
1155: -   xx_v - the Fortran90 pointer to the array

1157:     Output Parameter:
1158: .   ierr - error code

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

1169:     Notes:
1170:     Not yet supported for all F90 compilers

1172:     Level: intermediate

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

1176: M*/