xref: /petsc/src/vec/is/utils/isltog.c (revision 0752156a28ac8f8e9dfaef7ce98457a01bf27fb6)
1 
2 #ifdef PETSC_RCS_HEADER
3 static char vcid[] = "$Id: isltog.c,v 1.14 1997/09/11 20:38:10 bsmith Exp bsmith $";
4 #endif
5 
6 #include "sys.h"   /*I "sys.h" I*/
7 #include "src/is/isimpl.h"    /*I "is.h"  I*/
8 
9 #undef __FUNC__
10 #define __FUNC__ "ISLocalToGlobalMappingCreate"
11 /*@C
12     ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n)
13     ordering and a global parallel ordering.
14 
15     Input Parameters:
16 .   comm - MPI communicator of size 1.
17 .   n - the number of local elements
18 .   indices - the global index for each local element
19 
20     Output Parameters:
21 .   mapping - new mapping data structure
22 
23 .keywords: IS, local-to-global mapping, create
24 
25 .seealso: ISLocalToGlobalMappingDestroy()
26 @*/
27 int ISLocalToGlobalMappingCreate(MPI_Comm cm,int n, int *indices,ISLocalToGlobalMapping *mapping)
28 {
29   PetscValidIntPointer(indices);
30   PetscValidPointer(mapping);
31 
32   PetscHeaderCreate(*mapping,_p_ISLocalToGlobalMapping,IS_LTOGM_COOKIE,0,cm,ISLocalToGlobalMappingDestroy,0);
33   PLogObjectCreate(*mapping);
34   PLogObjectMemory(*mapping,sizeof(struct _p_ISLocalToGlobalMapping)+n*sizeof(int));
35 
36   (*mapping)->n       = n;
37   (*mapping)->indices = (int *) PetscMalloc((n+1)*sizeof(int));CHKPTRQ((*mapping)->indices);
38   PetscMemcpy((*mapping)->indices,indices,n*sizeof(int));
39 
40   /*
41       Do not create the global to local mapping. This is only created if
42      ISGlobalToLocalMapping() is called
43   */
44   (*mapping)->globals = 0;
45   return 0;
46 }
47 
48 #undef __FUNC__
49 #define __FUNC__ "ISLocalToGlobalMappingDestroy"
50 /*@
51    ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n)
52    ordering and a global parallel ordering.
53 
54    Input Parameters:
55 .  mapping - mapping data structure
56 
57 .keywords: IS, local-to-global mapping, destroy
58 
59 .seealso: ISLocalToGlobalMappingCreate()
60 @*/
61 int ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping mapping)
62 {
63   PetscValidPointer(mapping);
64   if (--mapping->refct > 0) return 0;
65 
66   PetscFree(mapping->indices);
67   if (mapping->globals) PetscFree(mapping->globals);
68   PLogObjectDestroy(mapping);
69   PetscHeaderDestroy(mapping);
70   return 0;
71 }
72 
73 #undef __FUNC__
74 #define __FUNC__ "ISLocalToGlobalMappingApplyIS"
75 /*@
76     ISLocalToGlobalMappingApplyIS - Creates from an IS in the local numbering
77     a new index set using the global numbering defined in an ISLocalToGlobalMapping
78     context.
79 
80     Input Parameters:
81 .   mapping - mapping between local and global numbering
82 .   is - index set in local numbering
83 
84     Output Parameters:
85 .   newis - index set in global numbering
86 
87 .keywords: IS, local-to-global mapping, apply
88 
89 .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),
90           ISLocalToGlobalMappingDestroy(), ISGlobalToLocalMappingApply()
91 @*/
92 int ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping, IS is, IS *newis)
93 {
94   int ierr,n,i,*idxin,*idxmap,*idxout;
95   PetscValidPointer(mapping);
96   PetscValidHeaderSpecific(is,IS_COOKIE);
97   PetscValidPointer(newis);
98 
99   ierr   = ISGetSize(is,&n); CHKERRQ(ierr);
100   ierr   = ISGetIndices(is,&idxin); CHKERRQ(ierr);
101   idxmap = mapping->indices;
102 
103   idxout = (int *) PetscMalloc((n+1)*sizeof(int));CHKPTRQ(idxout);
104   for ( i=0; i<n; i++ ) {
105     idxout[i] = idxmap[idxin[i]];
106   }
107   ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxout,newis); CHKERRQ(ierr);
108   PetscFree(idxout);
109   return 0;
110 }
111 
112 #undef __FUNC__
113 #define __FUNC__ "ISLocalToGlobalMappingApply"
114 /*@C
115    ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering
116    and converts them to the global numbering.
117 
118    Input Parameters:
119 .  mapping - the local to global mapping context
120 .  N - number of integers
121 .  in - input indices in local numbering
122 
123    Output Parameter:
124 .  out - indices in global numbering
125 
126    Notes: The in and out array may be identical
127 
128 .seealso: ISLocalToGlobalMappingCreate(),ISLocalToGlobalMappingDestroy(),
129           ISLocalToGlobalMappingApplyIS(),AOCreateBasic(),AOApplicationToPetsc(),
130           AOPetscToApplication(), ISGlobalToLocalMappingApply()
131 
132 .keywords: local-to-global, mapping, apply
133 
134 @*/
135 int ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,int N,int *in,int *out)
136 {
137   int i,*idx = mapping->indices,Nmax = mapping->n;
138   for ( i=0; i<N; i++ ) {
139     if (in[i] < 0) {out[i] = in[i]; continue;}
140     if (in[i] >= Nmax) SETERRQ(1,1,"Local index too large");
141     out[i] = idx[in[i]];
142   }
143   return 0;
144 }
145 
146 /* -----------------------------------------------------------------------------------------*/
147 
148 #undef __FUNC__
149 #define __FUNC__ "ISGlobalToLocalMappingSetUp_Private"
150 /*
151     Creates the global fields in the ISLocalToGlobalMapping structure
152 */
153 static int ISGlobalToLocalMappingSetUp_Private(ISLocalToGlobalMapping mapping)
154 {
155   int i,*idx = mapping->indices,n = mapping->n,end,start,*globals;
156 
157   end   = 0;
158   start = 100000000;
159 
160   for ( i=0; i<n; i++ ) {
161     if (idx[i] < 0) continue;
162     if (idx[i] < start) start = idx[i];
163     if (idx[i] > end)   end   = idx[i];
164   }
165   if (start > end) {start = 0; end = -1;}
166   mapping->globalstart = start;
167   mapping->globalend   = end;
168 
169   globals = mapping->globals = (int *) PetscMalloc((end-start+2)*sizeof(int));CHKPTRQ(mapping->globals);
170   for ( i=0; i<end-start+1; i++ ) {
171     globals[i] = -1;
172   }
173   for ( i=0; i<n; i++ ) {
174     if (idx[i] < 0) continue;
175     globals[idx[i] - start] = i;
176   }
177 
178   PLogObjectMemory(mapping,(end-start+1)*sizeof(int));
179   return 0;
180 }
181 
182 #undef __FUNC__
183 #define __FUNC__ "ISGlobalToLocalMappingApply"
184 /*@
185     ISGlobalToLocalMappingApply - Takes a list of integers in global numbering
186       and returns the local numbering.
187 
188     Input Parameters:
189 .   mapping - mapping between local and global numbering
190 .   type - IS_GTOLM_MASK - replaces global indices with no local value with -1
191            IS_GTOLM_DROP - drops the indices with no local value from the output list
192 .   n - number of global indices to map
193 .   idx - global indices to map
194 
195     Output Parameters:
196 .   nout - number of indices in output array (if type == IS_GTOLM_MASK then nout = n)
197 .   idxout - local index of each global index, one must pass in an array long enough
198              to hold all the indices. You can call ISGlobalToLocalMappingApply() with
199              idxout == PETSC_NULL to determine the required length (returned in nout)
200              and then allocate the required space and call ISGlobalToLocalMappingApply()
201              a second time to set the values.
202 
203     Notes: Either nout or idxout may be PETSC_NULL. idx and idxout may be identical.
204 
205 .keywords: IS, global-to-local mapping, apply
206 
207 .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),
208           ISLocalToGlobalMappingDestroy()
209 @*/
210 int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingType type,
211                                   int n, int *idx,int *nout,int *idxout)
212 {
213   int i,ierr, *globals,nf = 0,tmp,start,end;
214 
215   if (!mapping->globals) {
216     ierr = ISGlobalToLocalMappingSetUp_Private(mapping); CHKERRQ(ierr);
217   }
218   globals = mapping->globals;
219   start   = mapping->globalstart;
220   end     = mapping->globalend;
221 
222   if (type == IS_GTOLM_MASK) {
223     if (idxout) {
224       for ( i=0; i<n; i++ ) {
225         if (idx[i] < 0) idxout[i] = idx[i];
226         else if (idx[i] < start) idxout[i] = -1;
227         else if (idx[i] > end)   idxout[i] = -1;
228         else                     idxout[i] = globals[idx[i] - start];
229       }
230     }
231     if (nout) *nout = n;
232   } else {
233     if (idxout) {
234       for ( i=0; i<n; i++ ) {
235         if (idx[i] < 0) continue;
236         if (idx[i] < start) continue;
237         if (idx[i] > end) continue;
238         tmp = globals[idx[i] - start];
239         if (tmp < 0) continue;
240         idxout[nf++] = tmp;
241       }
242     } else {
243       for ( i=0; i<n; i++ ) {
244         if (idx[i] < 0) continue;
245         if (idx[i] < start) continue;
246         if (idx[i] > end) continue;
247         tmp = globals[idx[i] - start];
248         if (tmp < 0) continue;
249         nf++;
250       }
251     }
252     if (nout) *nout = nf;
253   }
254 
255   return 0;
256 }
257 
258