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