Actual source code: isblock.c

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


 10: /*@C
 11:    ISCompressIndicesGeneral - convert the indices into block indices
 12:    Input Parameters:
 13: +  n - the length of the index set
 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
 22: @*/
 23: PetscErrorCode  ISCompressIndicesGeneral(PetscInt n,PetscInt bs,PetscInt imax,const IS is_in[],IS is_out[])
 24: {
 25:   PetscErrorCode     ierr;
 26:   PetscInt           isz,len,i,j,ival,Nbs;
 27:   const PetscInt     *idx;
 28: #if defined (PETSC_USE_CTABLE)
 29:   PetscTable         gid1_lid1;
 30:   PetscInt           tt, gid1, *nidx;
 31:   PetscTablePosition tpos;
 32: #else
 33:   PetscInt           *nidx;
 34:   PetscBT            table;
 35: #endif

 38:   Nbs =n/bs;
 39: #if defined (PETSC_USE_CTABLE)
 40:   PetscTableCreate(Nbs,&gid1_lid1);
 41: #else
 42:   PetscMalloc(Nbs*sizeof(PetscInt),&nidx);
 43:   PetscBTCreate(Nbs,table);
 44: #endif
 45:   for (i=0; i<imax; i++) {
 46:     isz  = 0;
 47: #if defined (PETSC_USE_CTABLE)
 48:     PetscTableRemoveAll(gid1_lid1);
 49: #else
 50:     PetscBTMemzero(Nbs,table);
 51: #endif
 52:     ISGetIndices(is_in[i],&idx);
 53:     ISGetLocalSize(is_in[i],&len);
 54:     for (j=0; j<len ; j++) {
 55:       ival = idx[j]/bs; /* convert the indices into block indices */
 56: #if defined (PETSC_USE_CTABLE)
 57:       PetscTableFind(gid1_lid1,ival+1,&tt);
 58:       if (!tt) {
 59:         PetscTableAdd(gid1_lid1,ival+1,isz+1);
 60:         isz++;
 61:       }
 62: #else
 63:       if (ival>Nbs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"index greater than mat-dim");
 64:       if(!PetscBTLookupSet(table,ival)) { nidx[isz++] = ival;}
 65: #endif
 66:     }
 67:     ISRestoreIndices(is_in[i],&idx);
 68: #if defined (PETSC_USE_CTABLE)
 69:     PetscMalloc(isz*sizeof(PetscInt),&nidx);
 70:     PetscTableGetHeadPosition(gid1_lid1,&tpos);
 71:     j = 0;
 72:     while (tpos) {
 73:       PetscTableGetNext(gid1_lid1,&tpos,&gid1,&tt);
 74:       if (tt-- > isz) { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"index greater than array-dim"); }
 75:       nidx[tt] = gid1 - 1;
 76:       j++;
 77:     }
 78:     if (j != isz) { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"table error: jj != isz"); }
 79:     ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_OWN_POINTER,(is_out+i));
 80: #else
 81:     ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is_out+i));
 82: #endif
 83:   }
 84: #if defined (PETSC_USE_CTABLE)
 85:   PetscTableDestroy(&gid1_lid1);
 86: #else
 87:   PetscBTDestroy(table);
 88:   PetscFree(nidx);
 89: #endif
 90:   return(0);
 91: }

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

108:   for (i=0; i<imax; i++) {
109:     ISSorted(is_in[i],&flg);
110:     if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Indices are not sorted");
111:   }

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

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

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

160:   return(0);
161: }

165: PetscErrorCode  ISExpandIndicesGeneral(PetscInt n,PetscInt bs,PetscInt imax,const IS is_in[],IS is_out[])
166: {
168:   PetscInt       len,i,j,k,*nidx;
169:   const PetscInt *idx;
170: #if defined (PETSC_USE_CTABLE)
171:   PetscInt       maxsz;
172: #else
173:   PetscInt       Nbs;
174: #endif

177: #if defined (PETSC_USE_CTABLE)
178:   /* Now check max size */
179:   for (i=0,maxsz=0; i<imax; i++) {
180:     ISGetIndices(is_in[i],&idx);
181:     ISGetLocalSize(is_in[i],&len);
182:     if (len*bs > maxsz) maxsz = len*bs;
183:   }
184:   PetscMalloc(maxsz*sizeof(PetscInt),&nidx);
185: #else
186:   Nbs = n/bs;
187:   PetscMalloc(Nbs*bs*sizeof(PetscInt),&nidx);
188: #endif

190:   for (i=0; i<imax; i++) {
191:     ISGetIndices(is_in[i],&idx);
192:     ISGetLocalSize(is_in[i],&len);
193:     for (j=0; j<len ; ++j){
194:       for (k=0; k<bs; k++)
195:         nidx[j*bs+k] = idx[j]*bs+k;
196:     }
197:     ISRestoreIndices(is_in[i],&idx);
198:     ISCreateGeneral(PETSC_COMM_SELF,len*bs,nidx,PETSC_COPY_VALUES,is_out+i);
199:   }
200:   PetscFree(nidx);
201:   return(0);
202: }