Actual source code: general.c
1: /*$Id: general.c,v 1.103 2001/03/23 23:21:08 balay Exp $*/
2: /*
3: Provides the functions for index sets (IS) defined by a list of integers.
4: */
5: #include src/vec/is/impls/general/general.h
7: EXTERN int VecInitializePackage(char *);
9: int ISDuplicate_General(IS is,IS *newIS)
10: {
11: int ierr;
12: IS_General *sub = (IS_General *)is->data;
15: ISCreateGeneral(is->comm,sub->n,sub->idx,newIS);
16: return(0);
17: }
19: int ISDestroy_General(IS is)
20: {
21: IS_General *is_general = (IS_General*)is->data;
22: int ierr;
25: PetscFree(is_general->idx);
26: PetscFree(is_general);
27: PetscLogObjectDestroy(is);
28: PetscHeaderDestroy(is);
29: return(0);
30: }
32: int ISIdentity_General(IS is,PetscTruth *ident)
33: {
34: IS_General *is_general = (IS_General*)is->data;
35: int i,n = is_general->n,*idx = is_general->idx;
38: is->isidentity = PETSC_TRUE;
39: *ident = PETSC_TRUE;
40: for (i=0; i<n; i++) {
41: if (idx[i] != i) {
42: is->isidentity = PETSC_FALSE;
43: *ident = PETSC_FALSE;
44: break;
45: }
46: }
47: return(0);
48: }
50: int ISGetIndices_General(IS in,int **idx)
51: {
52: IS_General *sub = (IS_General*)in->data;
55: *idx = sub->idx;
56: return(0);
57: }
59: int ISRestoreIndices_General(IS in,int **idx)
60: {
61: IS_General *sub = (IS_General*)in->data;
64: if (*idx != sub->idx) {
65: SETERRQ(PETSC_ERR_ARG_WRONG,"Must restore with value from ISGetIndices()");
66: }
67: return(0);
68: }
70: int ISGetSize_General(IS is,int *size)
71: {
72: IS_General *sub = (IS_General *)is->data;
75: *size = sub->N;
76: return(0);
77: }
79: int ISGetLocalSize_General(IS is,int *size)
80: {
81: IS_General *sub = (IS_General *)is->data;
84: *size = sub->n;
85: return(0);
86: }
88: int ISInvertPermutation_General(IS is,int nlocal,IS *isout)
89: {
90: IS_General *sub = (IS_General *)is->data;
91: int i,ierr,*ii,n = sub->n,*idx = sub->idx,size,nstart;
92: IS istmp,nistmp;
95: MPI_Comm_size(is->comm,&size);
96: if (size == 1) {
97: PetscMalloc(n*sizeof(int),&ii);
98: for (i=0; i<n; i++) {
99: ii[idx[i]] = i;
100: }
101: ISCreateGeneral(PETSC_COMM_SELF,n,ii,isout);
102: ISSetPermutation(*isout);
103: PetscFree(ii);
104: } else {
105: /* crude, nonscalable get entire IS on each processor */
106: ISAllGather(is,&istmp);
107: ISSetPermutation(istmp);
108: ISInvertPermutation(istmp,PETSC_DECIDE,&nistmp);
109: ISDestroy(istmp);
110: /* get the part we need */
111: ierr = MPI_Scan(&nlocal,&nstart,1,MPI_INT,MPI_SUM,is->comm);
112: nstart -= nlocal;
113: ierr = ISGetIndices(nistmp,&idx);
114: ierr = ISCreateGeneral(is->comm,nlocal,idx+nstart,isout);
115: ierr = ISRestoreIndices(nistmp,&idx);
116: ierr = ISDestroy(nistmp);
117: }
118: return(0);
119: }
121: int ISView_General(IS is,PetscViewer viewer)
122: {
123: IS_General *sub = (IS_General *)is->data;
124: int i,n = sub->n,*idx = sub->idx,ierr;
125: PetscTruth isascii;
128: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
129: if (isascii) {
130: MPI_Comm comm;
131: int rank,size;
133: PetscObjectGetComm((PetscObject)viewer,&comm);
134: MPI_Comm_rank(comm,&rank);
135: MPI_Comm_size(comm,&size);
137: if (size > 1) {
138: if (is->isperm) {
139: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Index set is permutationn",rank);
140: }
141: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Number of indices in set %dn",rank,n);
142: for (i=0; i<n; i++) {
143: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %dn",rank,i,idx[i]);
144: }
145: } else {
146: if (is->isperm) {
147: PetscViewerASCIISynchronizedPrintf(viewer,"Index set is permutationn");
148: }
149: PetscViewerASCIISynchronizedPrintf(viewer,"Number of indices in set %dn",n);
150: for (i=0; i<n; i++) {
151: PetscViewerASCIISynchronizedPrintf(viewer,"%d %dn",i,idx[i]);
152: }
153: }
154: PetscViewerFlush(viewer);
155: } else {
156: SETERRQ1(1,"Viewer type %s not supported for this object",((PetscObject)viewer)->type_name);
157: }
158: return(0);
159: }
161: int ISSort_General(IS is)
162: {
163: IS_General *sub = (IS_General *)is->data;
164: int ierr;
167: if (sub->sorted) return(0);
168: PetscSortInt(sub->n,sub->idx);
169: sub->sorted = PETSC_TRUE;
170: return(0);
171: }
173: int ISSorted_General(IS is,PetscTruth *flg)
174: {
175: IS_General *sub = (IS_General *)is->data;
178: *flg = sub->sorted;
179: return(0);
180: }
182: static struct _ISOps myops = { ISGetSize_General,
183: ISGetLocalSize_General,
184: ISGetIndices_General,
185: ISRestoreIndices_General,
186: ISInvertPermutation_General,
187: ISSort_General,
188: ISSorted_General,
189: ISDuplicate_General,
190: ISDestroy_General,
191: ISView_General,
192: ISIdentity_General };
194: /*@C
195: ISCreateGeneral - Creates a data structure for an index set
196: containing a list of integers.
198: Collective on MPI_Comm
200: Input Parameters:
201: + comm - the MPI communicator
202: . n - the length of the index set
203: - idx - the list of integers
205: Output Parameter:
206: . is - the new index set
208: Notes:
209: When the communicator is not MPI_COMM_SELF, the operations on IS are NOT
210: conceptually the same as MPI_Group operations. The IS are then
211: distributed sets of indices and thus certain operations on them are collective.
213: Level: beginner
215: Concepts: index sets^creating
216: Concepts: IS^creating
218: .seealso: ISCreateStride(), ISCreateBlock(), ISAllGather()
219: @*/
220: int ISCreateGeneral(MPI_Comm comm,int n,const int idx[],IS *is)
221: {
222: int i,min,max,ierr;
223: PetscTruth sorted = PETSC_TRUE;
224: IS Nindex;
225: IS_General *sub;
226: PetscTruth flg;
230: if (n < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"length < 0");
232: *is = PETSC_NULL;
233: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
234: VecInitializePackage(PETSC_NULL);
235: #endif
237: PetscHeaderCreate(Nindex,_p_IS,struct _ISOps,IS_COOKIE,IS_GENERAL,"IS",comm,ISDestroy,ISView);
238: PetscLogObjectCreate(Nindex);
239: ierr = PetscNew(IS_General,&sub);
240: PetscLogObjectMemory(Nindex,sizeof(IS_General)+n*sizeof(int)+sizeof(struct _p_IS));
241: ierr = PetscMalloc((n+1)*sizeof(int),&sub->idx);
242: sub->n = n;
244: MPI_Allreduce(&n,&sub->N,1,MPI_INT,MPI_SUM,comm);
245: for (i=1; i<n; i++) {
246: if (idx[i] < idx[i-1]) {sorted = PETSC_FALSE; break;}
247: }
248: if (n) {min = max = idx[0];} else {min = max = 0;}
249: for (i=1; i<n; i++) {
250: if (idx[i] < min) min = idx[i];
251: if (idx[i] > max) max = idx[i];
252: }
253: PetscMemcpy(sub->idx,idx,n*sizeof(int));
254: sub->sorted = sorted;
255: Nindex->min = min;
256: Nindex->max = max;
257: Nindex->data = (void*)sub;
258: PetscMemcpy(Nindex->ops,&myops,sizeof(myops));
259: Nindex->isperm = PETSC_FALSE;
260: Nindex->isidentity = PETSC_FALSE;
261: PetscOptionsHasName(PETSC_NULL,"-is_view",&flg);
262: if (flg) {
263: ISView(Nindex,PETSC_VIEWER_STDOUT_(Nindex->comm));
264: }
265: *is = Nindex;
266: return(0);
267: }