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