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