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: }