Actual source code: isblock.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

      2: /* Routines to be used by MatIncreaseOverlap() for BAIJ and SBAIJ matrices */
      3: #include <petscis.h>                       /*I "petscis.h"  I*/
      4: #include <petscbt.h>
      5: #include <petscctable.h>

      9: /*@
     10:    ISCompressIndicesGeneral - convert the indices into block indices
     11:    Input Parameters:
     12: +  n - maximum possible length of the index set
     13: .  nkeys - expected number of keys when PETSC_USE_CTABLE
     14: .  bs - the size of block
     15: .  imax - the number of index sets
     16: -  is_in - the non-blocked array of index sets

     18:    Output Parameter:
     19: .  is_out - the blocked new index set

     21:    Level: intermediate

     23: .seealso: ISExpandIndicesGeneral()
     24: @*/
     25: PetscErrorCode  ISCompressIndicesGeneral(PetscInt n,PetscInt nkeys,PetscInt bs,PetscInt imax,const IS is_in[],IS is_out[])
     26: {
     28:   PetscInt       isz,len,i,j,ival,Nbs;
     29:   const PetscInt *idx;
     30: #if defined(PETSC_USE_CTABLE)
     31:   PetscTable         gid1_lid1;
     32:   PetscInt           tt, gid1, *nidx,Nkbs;
     33:   PetscTablePosition tpos;
     34: #else
     35:   PetscInt *nidx;
     36:   PetscBT  table;
     37: #endif

     40:   Nbs =n/bs;
     41: #if defined(PETSC_USE_CTABLE)
     42:   Nkbs = nkeys/bs;
     43:   PetscTableCreate(Nkbs,Nbs,&gid1_lid1);
     44: #else
     45:   PetscMalloc1(Nbs,&nidx);
     46:   PetscBTCreate(Nbs,&table);
     47: #endif
     48:   for (i=0; i<imax; i++) {
     49:     isz = 0;
     50: #if defined(PETSC_USE_CTABLE)
     51:     PetscTableRemoveAll(gid1_lid1);
     52: #else
     53:     PetscBTMemzero(Nbs,table);
     54: #endif
     55:     ISGetIndices(is_in[i],&idx);
     56:     ISGetLocalSize(is_in[i],&len);
     57:     for (j=0; j<len; j++) {
     58:       ival = idx[j]/bs; /* convert the indices into block indices */
     59: #if defined(PETSC_USE_CTABLE)
     60:       PetscTableFind(gid1_lid1,ival+1,&tt);
     61:       if (!tt) {
     62:         PetscTableAdd(gid1_lid1,ival+1,isz+1,INSERT_VALUES);
     63:         isz++;
     64:       }
     65: #else
     66:       if (ival>Nbs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"index greater than mat-dim");
     67:       if (!PetscBTLookupSet(table,ival)) nidx[isz++] = ival;
     68: #endif
     69:     }
     70:     ISRestoreIndices(is_in[i],&idx);

     72: #if defined(PETSC_USE_CTABLE)
     73:     PetscMalloc1(isz,&nidx);
     74:     PetscTableGetHeadPosition(gid1_lid1,&tpos);
     75:     j    = 0;
     76:     while (tpos) {
     77:       PetscTableGetNext(gid1_lid1,&tpos,&gid1,&tt);
     78:       if (tt-- > isz) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"index greater than array-dim");
     79:       nidx[tt] = gid1 - 1;
     80:       j++;
     81:     }
     82:     if (j != isz) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"table error: jj != isz");
     83:     ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_OWN_POINTER,(is_out+i));
     84: #else
     85:     ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is_out+i));
     86: #endif
     87:   }
     88: #if defined(PETSC_USE_CTABLE)
     89:   PetscTableDestroy(&gid1_lid1);
     90: #else
     91:   PetscBTDestroy(&table);
     92:   PetscFree(nidx);
     93: #endif
     94:   return(0);
     95: }

     99: PetscErrorCode  ISCompressIndicesSorted(PetscInt n,PetscInt bs,PetscInt imax,const IS is_in[],IS is_out[])
    100: {
    102:   PetscInt       i,j,k,val,len,*nidx,bbs;
    103:   const PetscInt *idx,*idx_local;
    104:   PetscBool      flg,isblock;
    105: #if defined(PETSC_USE_CTABLE)
    106:   PetscInt       maxsz;
    107: #else
    108:   PetscInt       Nbs=n/bs;
    109: #endif

    112:   for (i=0; i<imax; i++) {
    113:     ISSorted(is_in[i],&flg);
    114:     if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Indices are not sorted");
    115:   }

    117: #if defined(PETSC_USE_CTABLE)
    118:   /* Now check max size */
    119:   for (i=0,maxsz=0; i<imax; i++) {
    120:     ISGetLocalSize(is_in[i],&len);
    121:     if (len%bs !=0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Indices are not block ordered");
    122:     len = len/bs; /* The reduced index size */
    123:     if (len > maxsz) maxsz = len;
    124:   }
    125:   PetscMalloc1(maxsz,&nidx);
    126: #else
    127:   PetscMalloc1(Nbs,&nidx);
    128: #endif
    129:   /* Now check if the indices are in block order */
    130:   for (i=0; i<imax; i++) {
    131:     ISGetLocalSize(is_in[i],&len);

    133:     /* special case where IS is already block IS of the correct size */
    134:     PetscObjectTypeCompare((PetscObject)is_in[i],ISBLOCK,&isblock);
    135:     if (isblock) {
    136:       ISBlockGetLocalSize(is_in[i],&bbs);
    137:       if (bs == bbs) {
    138:         len  = len/bs;
    139:         ISBlockGetIndices(is_in[i],&idx);
    140:         ISCreateGeneral(PETSC_COMM_SELF,len,idx,PETSC_COPY_VALUES,(is_out+i));
    141:         ISBlockRestoreIndices(is_in[i],&idx);
    142:         continue;
    143:       }
    144:     }
    145:     ISGetIndices(is_in[i],&idx);
    146:     if (len%bs !=0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Indices are not block ordered");

    148:     len       = len/bs; /* The reduced index size */
    149:     idx_local = idx;
    150:     for (j=0; j<len; j++) {
    151:       val = idx_local[0];
    152:       if (val%bs != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Indices are not block ordered");
    153:       for (k=0; k<bs; k++) {
    154:         if (val+k != idx_local[k]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Indices are not block ordered");
    155:       }
    156:       nidx[j]    = val/bs;
    157:       idx_local += bs;
    158:     }
    159:     ISRestoreIndices(is_in[i],&idx);
    160:     ISCreateGeneral(PETSC_COMM_SELF,len,nidx,PETSC_COPY_VALUES,(is_out+i));
    161:   }
    162:   PetscFree(nidx);
    163:   return(0);
    164: }

    168: /*@C
    169:    ISExpandIndicesGeneral - convert the indices into non-block indices
    170:    Input Parameters:
    171: +  n - the length of the index set   (not being used)
    172: .  nkeys - expected number of keys when PETSC_USE_CTABLE (not being used)
    173: .  bs - the size of block
    174: .  imax - the number of index sets
    175: -  is_in - the blocked array of index sets

    177:    Output Parameter:
    178: .  is_out - the non-blocked new index set

    180:    Level: intermediate

    182: .seealso: ISCompressIndicesGeneral()
    183: @*/
    184: PetscErrorCode  ISExpandIndicesGeneral(PetscInt n,PetscInt nkeys,PetscInt bs,PetscInt imax,const IS is_in[],IS is_out[])
    185: {
    187:   PetscInt       len,i,j,k,*nidx;
    188:   const PetscInt *idx;
    189:   PetscInt       maxsz;

    192:   /* Check max size of is_in[] */
    193:   maxsz=0;
    194:   for (i=0; i<imax; i++) {
    195:     ISGetLocalSize(is_in[i],&len);
    196:     if (len > maxsz) maxsz = len;
    197:   }
    198:   PetscMalloc1(maxsz*bs,&nidx);

    200:   for (i=0; i<imax; i++) {
    201:     ISGetLocalSize(is_in[i],&len);
    202:     ISGetIndices(is_in[i],&idx);
    203:     for (j=0; j<len ; ++j) {
    204:       for (k=0; k<bs; k++) nidx[j*bs+k] = idx[j]*bs+k;
    205:     }
    206:     ISRestoreIndices(is_in[i],&idx);
    207:     ISCreateGeneral(PETSC_COMM_SELF,len*bs,nidx,PETSC_COPY_VALUES,is_out+i);
    208:   }
    209:   PetscFree(nidx);
    210:   return(0);
    211: }