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