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: int ISDuplicate_General(IS is,IS *newIS)
8: {
9: int ierr;
10: IS_General *sub = (IS_General *)is->data;
13: ISCreateGeneral(is->comm,sub->n,sub->idx,newIS);
14: return(0);
15: }
17: int ISDestroy_General(IS is)
18: {
19: IS_General *is_general = (IS_General*)is->data;
20: int ierr;
23: PetscFree(is_general->idx);
24: PetscFree(is_general);
25: PetscLogObjectDestroy(is);
26: PetscHeaderDestroy(is);
27: return(0);
28: }
30: int ISIdentity_General(IS is,PetscTruth *ident)
31: {
32: IS_General *is_general = (IS_General*)is->data;
33: int i,n = is_general->n,*idx = is_general->idx;
36: is->isidentity = PETSC_TRUE;
37: *ident = PETSC_TRUE;
38: for (i=0; i<n; i++) {
39: if (idx[i] != i) {
40: is->isidentity = PETSC_FALSE;
41: *ident = PETSC_FALSE;
42: break;
43: }
44: }
45: return(0);
46: }
48: int ISGetIndices_General(IS in,int **idx)
49: {
50: IS_General *sub = (IS_General*)in->data;
53: *idx = sub->idx;
54: return(0);
55: }
57: int ISRestoreIndices_General(IS in,int **idx)
58: {
59: IS_General *sub = (IS_General*)in->data;
62: if (*idx != sub->idx) {
63: SETERRQ(PETSC_ERR_ARG_WRONG,"Must restore with value from ISGetIndices()");
64: }
65: return(0);
66: }
68: int ISGetSize_General(IS is,int *size)
69: {
70: IS_General *sub = (IS_General *)is->data;
73: *size = sub->N;
74: return(0);
75: }
77: int ISGetLocalSize_General(IS is,int *size)
78: {
79: IS_General *sub = (IS_General *)is->data;
82: *size = sub->n;
83: return(0);
84: }
86: int ISInvertPermutation_General(IS is,int nlocal,IS *isout)
87: {
88: IS_General *sub = (IS_General *)is->data;
89: int i,ierr,*ii,n = sub->n,*idx = sub->idx,size,nstart;
90: IS istmp,nistmp;
93: MPI_Comm_size(is->comm,&size);
94: if (size == 1) {
95: PetscMalloc(n*sizeof(int),&ii);
96: for (i=0; i<n; i++) {
97: ii[idx[i]] = i;
98: }
99: ISCreateGeneral(PETSC_COMM_SELF,n,ii,isout);
100: ISSetPermutation(*isout);
101: PetscFree(ii);
102: } else {
103: /* crude, nonscalable get entire IS on each processor */
104: ISAllGather(is,&istmp);
105: ISSetPermutation(istmp);
106: ISInvertPermutation(istmp,PETSC_DECIDE,&nistmp);
107: ISDestroy(istmp);
108: /* get the part we need */
109: ierr = MPI_Scan(&nlocal,&nstart,1,MPI_INT,MPI_SUM,is->comm);
110: nstart -= nlocal;
111: ierr = ISGetIndices(nistmp,&idx);
112: ierr = ISCreateGeneral(is->comm,nlocal,idx+nstart,isout);
113: ierr = ISRestoreIndices(nistmp,&idx);
114: ierr = ISDestroy(nistmp);
115: }
116: return(0);
117: }
119: int ISView_General(IS is,PetscViewer viewer)
120: {
121: IS_General *sub = (IS_General *)is->data;
122: int i,n = sub->n,*idx = sub->idx,ierr;
123: PetscTruth isascii;
126: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
127: if (isascii) {
128: MPI_Comm comm;
129: int rank,size;
131: PetscObjectGetComm((PetscObject)viewer,&comm);
132: MPI_Comm_rank(comm,&rank);
133: MPI_Comm_size(comm,&size);
135: if (size > 1) {
136: if (is->isperm) {
137: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Index set is permutationn",rank);
138: }
139: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Number of indices in set %dn",rank,n);
140: for (i=0; i<n; i++) {
141: PetscViewerASCIISynchronizedPrintf(viewer,"[%d] %d %dn",rank,i,idx[i]);
142: }
143: } else {
144: if (is->isperm) {
145: PetscViewerASCIISynchronizedPrintf(viewer,"Index set is permutationn");
146: }
147: PetscViewerASCIISynchronizedPrintf(viewer,"Number of indices in set %dn",n);
148: for (i=0; i<n; i++) {
149: PetscViewerASCIISynchronizedPrintf(viewer,"%d %dn",i,idx[i]);
150: }
151: }
152: PetscViewerFlush(viewer);
153: } else {
154: SETERRQ1(1,"Viewer type %s not supported for this object",((PetscObject)viewer)->type_name);
155: }
156: return(0);
157: }
159: int ISSort_General(IS is)
160: {
161: IS_General *sub = (IS_General *)is->data;
162: int ierr;
165: if (sub->sorted) return(0);
166: PetscSortInt(sub->n,sub->idx);
167: sub->sorted = PETSC_TRUE;
168: return(0);
169: }
171: int ISSorted_General(IS is,PetscTruth *flg)
172: {
173: IS_General *sub = (IS_General *)is->data;
176: *flg = sub->sorted;
177: return(0);
178: }
180: static struct _ISOps myops = { ISGetSize_General,
181: ISGetLocalSize_General,
182: ISGetIndices_General,
183: ISRestoreIndices_General,
184: ISInvertPermutation_General,
185: ISSort_General,
186: ISSorted_General,
187: ISDuplicate_General,
188: ISDestroy_General,
189: ISView_General,
190: ISIdentity_General };
192: /*@C
193: ISCreateGeneral - Creates a data structure for an index set
194: containing a list of integers.
196: Collective on MPI_Comm
198: Input Parameters:
199: + comm - the MPI communicator
200: . n - the length of the index set
201: - idx - the list of integers
203: Output Parameter:
204: . is - the new index set
206: Notes:
207: When the communicator is not MPI_COMM_SELF, the operations on IS are NOT
208: conceptually the same as MPI_Group operations. The IS are then
209: distributed sets of indices and thus certain operations on them are collective.
211: Level: beginner
213: Concepts: index sets^creating
214: Concepts: IS^creating
216: .seealso: ISCreateStride(), ISCreateBlock(), ISAllGather()
217: @*/
218: int ISCreateGeneral(MPI_Comm comm,int n,const int idx[],IS *is)
219: {
220: int i,min,max,ierr;
221: PetscTruth sorted = PETSC_TRUE;
222: IS Nindex;
223: IS_General *sub;
224: PetscTruth flg;
228: if (n < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"length < 0");
231: *is = 0;
232: PetscHeaderCreate(Nindex,_p_IS,struct _ISOps,IS_COOKIE,IS_GENERAL,"IS",comm,ISDestroy,ISView);
233: PetscLogObjectCreate(Nindex);
234: ierr = PetscNew(IS_General,&sub);
235: PetscLogObjectMemory(Nindex,sizeof(IS_General)+n*sizeof(int)+sizeof(struct _p_IS));
236: ierr = PetscMalloc((n+1)*sizeof(int),&sub->idx);
237: sub->n = n;
239: MPI_Allreduce(&n,&sub->N,1,MPI_INT,MPI_SUM,comm);
240: for (i=1; i<n; i++) {
241: if (idx[i] < idx[i-1]) {sorted = PETSC_FALSE; break;}
242: }
243: if (n) {min = max = idx[0];} else {min = max = 0;}
244: for (i=1; i<n; i++) {
245: if (idx[i] < min) min = idx[i];
246: if (idx[i] > max) max = idx[i];
247: }
248: PetscMemcpy(sub->idx,idx,n*sizeof(int));
249: sub->sorted = sorted;
250: Nindex->min = min;
251: Nindex->max = max;
252: Nindex->data = (void*)sub;
253: PetscMemcpy(Nindex->ops,&myops,sizeof(myops));
254: Nindex->isperm = PETSC_FALSE;
255: Nindex->isidentity = PETSC_FALSE;
256: PetscOptionsHasName(PETSC_NULL,"-is_view",&flg);
257: if (flg) {
258: ISView(Nindex,PETSC_VIEWER_STDOUT_(Nindex->comm));
259: }
260: *is = Nindex;
261: return(0);
262: }