Date: 2013-07-02T14:40:23+00:00

Actual source code: index.c
petsc-3.4.2 2013-07-02

      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*/