xref: /petsc/src/vec/is/utils/isltog.c (revision d08a53c38dd4bae43ea11adda40bc48bec0e9e9e)
1 
2 #ifdef PETSC_RCS_HEADER
3 static char vcid[] = "$Id: isltog.c,v 1.12 1997/08/22 15:10:18 bsmith Exp balay $";
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(),AOCreateDebug(),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
198 
199 
200     Notes: Either nout or idxout may be PETSC_NULL. idx and idxout may be identical.
201 
202 .keywords: IS, global-to-local mapping, apply
203 
204 .seealso: ISLocalToGlobalMappingApply(), ISLocalToGlobalMappingCreate(),
205           ISLocalToGlobalMappingDestroy()
206 @*/
207 int ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingType type,
208                                   int n, int *idx,int *nout,int *idxout)
209 {
210   int i,ierr, *globals,nf = 0,tmp,start,end;
211 
212   if (!mapping->globals) {
213     ierr = ISGlobalToLocalMappingSetUp_Private(mapping); CHKERRQ(ierr);
214   }
215   globals = mapping->globals;
216   start   = mapping->globalstart;
217   end     = mapping->globalend;
218 
219   if (type == IS_GTOLM_MASK) {
220     if (idxout) {
221       for ( i=0; i<n; i++ ) {
222         if (idx[i] < 0) idxout[i] = idx[i];
223         else if (idx[i] < start) idxout[i] = -1;
224         else if (idx[i] > end)   idxout[i] = -1;
225         else                     idxout[i] = globals[idx[i] - start];
226       }
227     }
228     if (nout) *nout = n;
229   } else {
230     if (idxout) {
231       for ( i=0; i<n; i++ ) {
232         if (idx[i] < 0) continue;
233         if (idx[i] < start) continue;
234         if (idx[i] > end) continue;
235         tmp = globals[idx[i] - start];
236         if (tmp < 0) continue;
237         idxout[nf++] = tmp;
238       }
239     } else {
240       for ( i=0; i<n; i++ ) {
241         if (idx[i] < 0) continue;
242         if (idx[i] < start) continue;
243         if (idx[i] > end) continue;
244         tmp = globals[idx[i] - start];
245         if (tmp < 0) continue;
246         nf++;
247       }
248     }
249     if (nout) *nout = nf;
250   }
251 
252   return 0;
253 }
254 
255