xref: /petsc/src/vec/is/utils/isltog.c (revision 3f1db9ec2fd39765c6c3a00831044586630c4cca)
1 
2 #ifdef PETSC_RCS_HEADER
3 static char vcid[] = "$Id: isltog.c,v 1.23 1998/07/22 20:18:50 balay Exp bsmith $";
4 #endif
5 
6 #include "sys.h"   /*I "sys.h" I*/
7 #include "src/is/isimpl.h"    /*I "is.h"  I*/
8 
9 #undef __FUNC__
10 #define __FUNC__ "ISLocalToGlobalMappingView"
11 /*@C
12     ISLocalToGlobalMappingView - View a local to global mapping
13 
14     Not Collective
15 
16     Input Parameters:
17 .   ltog - local to global mapping
18 .   viewer - viewer
19 
20 .keywords: IS, local-to-global mapping, create
21 
22 .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate()
23 @*/
24 int ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,Viewer viewer)
25 {
26   int      i;
27 
28   PetscFunctionBegin;
29 
30   for ( i=0; i<mapping->n; i++ ) {
31     printf("%d %d\n",i,mapping->indices[i]);
32   }
33 
34   PetscFunctionReturn(0);
35 }
36 
37 #undef __FUNC__
38 #define __FUNC__ "ISLocalToGlobalMappingCreateIS"
39 /*@C
40     ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n)
41     ordering and a global parallel ordering.
42 
43     Collective on IS
44 
45     Input Parameters:
46 .   is - index set containing the global numbers for each local
47 
48     Output Parameters:
49 .   mapping - new mapping data structure
50 
51 .keywords: IS, local-to-global mapping, create
52 
53 .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreate()
54 @*/
55 int ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping *mapping)
56 {
57   int      n,*indices,ierr;
58   MPI_Comm comm;
59 
60   PetscFunctionBegin;
61   PetscValidHeaderSpecific(is,IS_COOKIE);
62 
63   ierr = PetscObjectGetComm((PetscObject)is,&comm); CHKERRQ(ierr);
64   ierr = ISGetSize(is,&n);CHKERRQ(ierr);
65   ierr = ISGetIndices(is,&indices);CHKERRQ(ierr);
66   ierr = ISLocalToGlobalMappingCreate(comm,n,indices,mapping);CHKERRQ(ierr);
67   ierr = ISRestoreIndices(is,&indices);CHKERRQ(ierr);
68 
69   PetscFunctionReturn(0);
70 }
71 
72 #undef __FUNC__
73 #define __FUNC__ "ISLocalToGlobalMappingCreate"
74 /*@C
75     ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n)
76     ordering and a global parallel ordering.
77 
78     Collective on MPI_Comm
79 
80     Input Parameters:
81 +   comm - MPI communicator of size 1.
82 .   n - the number of local elements
83 -   indices - the global index for each local element
84 
85     Output Parameters:
86 .   mapping - new mapping data structure
87 
88 .keywords: IS, local-to-global mapping, create
89 
90 .seealso: ISLocalToGlobalMappingDestroy(), ISLocalToGlobalMappingCreateIS()
91 @*/
92 int ISLocalToGlobalMappingCreate(MPI_Comm cm,int n,const int indices[],ISLocalToGlobalMapping *mapping)
93 {
94   PetscFunctionBegin;
95   PetscValidIntPointer(indices);
96   PetscValidPointer(mapping);
97 
98   PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,int,IS_LTOGM_COOKIE,0,"ISLocalToGlobalMapping",
99                     cm,ISLocalToGlobalMappingDestroy,ISLocalToGlobalMappingView);
100   PLogObjectCreate(*mapping);
101   PLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(int));
102 
103   (*mapping)->n       = n;
104   (*mapping)->indices = (int *) PetscMalloc((n+1)*sizeof(int));CHKPTRQ((*mapping)->indices);
105   PetscMemcpy((*mapping)->indices,indices,n*sizeof(int));
106 
107   /*
108       Do not create the global to local mapping. This is only created if
109      ISGlobalToLocalMapping() is called
110   */
111   (*mapping)->globals = 0;
112   PetscFunctionReturn(0);
113 }
114 
115 #undef __FUNC__
116 #define __FUNC__ "ISLocalToGlobalMappingDestroy"
117 /*@
118    ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n)
119    ordering and a global parallel ordering.
120 
121    Collective on ISLocalToGlobalMapping
122 
123    Input Parameters:
124 .  mapping - mapping data structure
125 
126 .keywords: IS, local-to-global mapping, destroy
127 
128 .seealso: ISLocalToGlobalMappingCreate()
129 @*/
130 int ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping)
131 {
132   PetscFunctionBegin;
133   PetscValidPointer(mapping);
134   if (--mapping->refct > 0) PetscFunctionReturn(0);
135 
136   PetscFree(mapping->indices);
137   if (mapping->globals) PetscFree(mapping->globals);
138   PLogObjectDestroy(mapping);
139   PetscHeaderDestroy(mapping);
140   PetscFunctionReturn(0);
141 }
142 
143 #undef __FUNC__
144 #define __FUNC__ "ISLocalToGlobalMappingApplyIS"
145 /*@
146     ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering
147     a new index set using the global numbering defined in an ISLocalToGlobalMapping
148     context.
149 
150     Not collective
151 
152     Input Parameters:
153 +   mapping - mapping between local and global numbering
154 -   is - index set in local numbering
155 
156     Output Parameters:
157 .   newis - index set in global numbering
158 
159 .keywords: IS, local-to-global mapping, apply
160 
161 .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),
162           ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply()
163 @*/
164 int ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping, IS is, IS *newis)
165 {
166   int ierr,n,i,*idxin,*idxmap,*idxout;
167 
168   PetscFunctionBegin;
169   PetscValidPointer(mapping);
170   PetscValidHeaderSpecific(is,IS_COOKIE);
171   PetscValidPointer(newis);
172 
173   ierr   = ISGetSize(is,&n); CHKERRQ(ierr);
174   ierr   = ISGetIndices(is,&idxin); CHKERRQ(ierr);
175   idxmap = mapping->indices;
176 
177   idxout = (int *) PetscMalloc((n+1)*sizeof(int));CHKPTRQ(idxout);
178   for ( i=0; i<n; i++ ) {
179     idxout[i] = idxmap[idxin[i]];
180   }
181   ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis); CHKERRQ(ierr);
182   PetscFree(idxout);
183   PetscFunctionReturn(0);
184 }
185 
186 #undef __FUNC__
187 #define __FUNC__ "ISLocalToGlobalMappingApply"
188 /*@C
189    ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering
190    and converts them to the global numbering.
191 
192    Not collective
193 
194    Input Parameters:
195 +  mapping - the local to global mapping context
196 .  N - number of integers
197 -  in - input indices in local numbering
198 
199    Output Parameter:
200 .  out - indices in global numbering
201 
202    Notes:
203    The in and out array parameters may be identical.
204 
205 .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(),
206           ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(),
207           AOPetscToApplication(), ISGlobalToLocalMappingApply()
208 
209 .keywords: local-to-global, mapping, apply
210 
211 @*/
212 int ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,const int in[],int out[])
213 {
214   int i,*idx = mapping->indices,Nmax = mapping->n;
215 
216   PetscFunctionBegin;
217   for ( i=0; i<N; i++ ) {
218     if (in[i] < 0) {out[i] = in[i]; continue;}
219     if (in[i] >= Nmax) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Local index too large");
220     out[i] = idx[in[i]];
221   }
222   PetscFunctionReturn(0);
223 }
224 
225 /* -----------------------------------------------------------------------------------------*/
226 
227 #undef __FUNC__
228 #define __FUNC__ "ISGlobalToLocalMappingSetUp_Private"
229 /*
230     Creates the global fields in the ISLocalToGlobalMapping structure
231 */
232 static int ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping)
233 {
234   int i,*idx = mapping->indices,n = mapping->n,end,start,*globals;
235 
236   PetscFunctionBegin;
237   end   = 0;
238   start = 100000000;
239 
240   for ( i=0; i<n; i++ ) {
241     if (idx[i] < 0) continue;
242     if (idx[i] < start) start = idx[i];
243     if (idx[i] > end)   end   = idx[i];
244   }
245   if (start > end) {start = 0; end = -1;}
246   mapping->globalstart = start;
247   mapping->globalend   = end;
248 
249   globals = mapping->globals = (int *) PetscMalloc((end-start+2)*sizeof(int));CHKPTRQ(mapping->globals);
250   for ( i=0; i<end-start+1; i++ ) {
251     globals[i] = -1;
252   }
253   for ( i=0; i<n; i++ ) {
254     if (idx[i] < 0) continue;
255     globals[idx[i] - start] = i;
256   }
257 
258   PLogObjectMemory(mapping,(end-start+1)*sizeof(int));
259   PetscFunctionReturn(0);
260 }
261 
262 #undef __FUNC__
263 #define __FUNC__ "ISGlobalToLocalMappingApply"
264 /*@
265     ISGlobalToLocalMappingApply - Takes a list of integers in global numbering
266       and returns the local numbering.
267 
268     Not collective
269 
270     Input Parameters:
271 +   mapping - mapping between local and global numbering
272 .   type - IS_GTOLM_MASK - replaces global indices with no local value with -1
273            IS_GTOLM_DROP - drops the indices with no local value from the output list
274 .   n - number of global indices to map
275 -   idx - global indices to map
276 
277     Output Parameters:
278 +   nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n)
279 -   idxout - local index of each global index, one must pass in an array long enough
280              to hold all the indices. You can call ISGlobalToLocalMappingApply() with
281              idxout == PETSC_NULL to determine the required length (returned in nout)
282              and then allocate the required space and call ISGlobalToLocalMappingApply()
283              a second time to set the values.
284 
285     Notes:
286     Either nout or idxout may be PETSC_NULL. idx and idxout may be identical.
287 
288 .keywords: IS, global-to-local mapping, apply
289 
290 .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),
291           ISLocalToGlobalMappingDestroy()
292 @*/
293 int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingType type,
294                                   int n, const int idx[],int *nout,int idxout[])
295 {
296   int i,ierr, *globals,nf = 0,tmp,start,end;
297 
298   PetscFunctionBegin;
299   if (!mapping->globals) {
300     ierr = ISGlobalToLocalMappingSetUp_Private(mapping); CHKERRQ(ierr);
301   }
302   globals = mapping->globals;
303   start   = mapping->globalstart;
304   end     = mapping->globalend;
305 
306   if (type == IS_GTOLM_MASK) {
307     if (idxout) {
308       for ( i=0; i<n; i++ ) {
309         if (idx[i] < 0) idxout[i] = idx[i];
310         else if (idx[i] < start) idxout[i] = -1;
311         else if (idx[i] > end)   idxout[i] = -1;
312         else                     idxout[i] = globals[idx[i] - start];
313       }
314     }
315     if (nout) *nout = n;
316   } else {
317     if (idxout) {
318       for ( i=0; i<n; i++ ) {
319         if (idx[i] < 0) continue;
320         if (idx[i] < start) continue;
321         if (idx[i] > end) continue;
322         tmp = globals[idx[i] - start];
323         if (tmp < 0) continue;
324         idxout[nf++] = tmp;
325       }
326     } else {
327       for ( i=0; i<n; i++ ) {
328         if (idx[i] < 0) continue;
329         if (idx[i] < start) continue;
330         if (idx[i] > end) continue;
331         tmp = globals[idx[i] - start];
332         if (tmp < 0) continue;
333         nf++;
334       }
335     }
336     if (nout) *nout = nf;
337   }
338 
339   PetscFunctionReturn(0);
340 }
341 
342