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