xref: /petsc/src/vec/is/utils/isltog.c (revision 633354d9cb03a0dcc5a871fca002dba4b1523513)
1af0996ceSBarry Smith #include <petsc/private/isimpl.h> /*I "petscis.h"  I*/
2e8f14785SLisandro Dalcin #include <petsc/private/hashmapi.h>
30c312b8eSJed Brown #include <petscsf.h>
4665c2dedSJed Brown #include <petscviewer.h>
5*633354d9SStefano Zampini #include <petscbt.h>
62362add9SBarry Smith 
77087cfbeSBarry Smith PetscClassId          IS_LTOGM_CLASSID;
8*633354d9SStefano Zampini static PetscErrorCode ISLocalToGlobalMappingSetUpBlockInfo_Private(ISLocalToGlobalMapping);
98e58c17dSMatthew Knepley 
10413f72f0SBarry Smith typedef struct {
11413f72f0SBarry Smith   PetscInt *globals;
12413f72f0SBarry Smith } ISLocalToGlobalMapping_Basic;
13413f72f0SBarry Smith 
14413f72f0SBarry Smith typedef struct {
15e8f14785SLisandro Dalcin   PetscHMapI globalht;
16413f72f0SBarry Smith } ISLocalToGlobalMapping_Hash;
17413f72f0SBarry Smith 
186528b96dSMatthew G. Knepley /*@C
19cab54364SBarry Smith   ISGetPointRange - Returns a description of the points in an `IS` suitable for traversal
20413f72f0SBarry Smith 
2120662ed9SBarry Smith   Not Collective
226528b96dSMatthew G. Knepley 
236528b96dSMatthew G. Knepley   Input Parameter:
24cab54364SBarry Smith . pointIS - The `IS` object
256528b96dSMatthew G. Knepley 
266528b96dSMatthew G. Knepley   Output Parameters:
276528b96dSMatthew G. Knepley + pStart - The first index, see notes
286528b96dSMatthew G. Knepley . pEnd   - One past the last index, see notes
296528b96dSMatthew G. Knepley - points - The indices, see notes
306528b96dSMatthew G. Knepley 
316528b96dSMatthew G. Knepley   Level: intermediate
326528b96dSMatthew G. Knepley 
33cab54364SBarry Smith   Notes:
3420662ed9SBarry Smith   If the `IS` contains contiguous indices in an `ISSTRIDE`, then the indices are contained in [pStart, pEnd) and points = `NULL`.
3520662ed9SBarry Smith   Otherwise, `pStart = 0`, `pEnd = numIndices`, and points is an array of the indices. This supports the following pattern
36cab54364SBarry Smith .vb
37cab54364SBarry Smith   ISGetPointRange(is, &pStart, &pEnd, &points);
38cab54364SBarry Smith   for (p = pStart; p < pEnd; ++p) {
39cab54364SBarry Smith     const PetscInt point = points ? points[p] : p;
4020662ed9SBarry Smith     // use point
41cab54364SBarry Smith   }
42cab54364SBarry Smith   ISRestorePointRange(is, &pstart, &pEnd, &points);
43cab54364SBarry Smith .ve
4420662ed9SBarry Smith   Hence the same code can be written for `pointIS` being a `ISSTRIDE` or `ISGENERAL`
45cab54364SBarry Smith 
46cab54364SBarry Smith .seealso: [](sec_scatter), `IS`, `ISRestorePointRange()`, `ISGetPointSubrange()`, `ISGetIndices()`, `ISCreateStride()`
476528b96dSMatthew G. Knepley @*/
48d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGetPointRange(IS pointIS, PetscInt *pStart, PetscInt *pEnd, const PetscInt **points)
49d71ae5a4SJacob Faibussowitsch {
509305a4c7SMatthew G. Knepley   PetscInt  numCells, step = 1;
519305a4c7SMatthew G. Knepley   PetscBool isStride;
529305a4c7SMatthew G. Knepley 
539305a4c7SMatthew G. Knepley   PetscFunctionBeginHot;
549305a4c7SMatthew G. Knepley   *pStart = 0;
559305a4c7SMatthew G. Knepley   *points = NULL;
569566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(pointIS, &numCells));
579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pointIS, ISSTRIDE, &isStride));
589566063dSJacob Faibussowitsch   if (isStride) PetscCall(ISStrideGetInfo(pointIS, pStart, &step));
599305a4c7SMatthew G. Knepley   *pEnd = *pStart + numCells;
609566063dSJacob Faibussowitsch   if (!isStride || step != 1) PetscCall(ISGetIndices(pointIS, points));
613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
629305a4c7SMatthew G. Knepley }
639305a4c7SMatthew G. Knepley 
646528b96dSMatthew G. Knepley /*@C
65cab54364SBarry Smith   ISRestorePointRange - Destroys the traversal description created with `ISGetPointRange()`
666528b96dSMatthew G. Knepley 
6720662ed9SBarry Smith   Not Collective
686528b96dSMatthew G. Knepley 
696528b96dSMatthew G. Knepley   Input Parameters:
70cab54364SBarry Smith + pointIS - The `IS` object
71cab54364SBarry Smith . pStart  - The first index, from `ISGetPointRange()`
72cab54364SBarry Smith . pEnd    - One past the last index, from `ISGetPointRange()`
73cab54364SBarry Smith - points  - The indices, from `ISGetPointRange()`
746528b96dSMatthew G. Knepley 
756528b96dSMatthew G. Knepley   Level: intermediate
766528b96dSMatthew G. Knepley 
77cab54364SBarry Smith .seealso: [](sec_scatter), `IS`, `ISGetPointRange()`, `ISGetPointSubrange()`, `ISGetIndices()`, `ISCreateStride()`
786528b96dSMatthew G. Knepley @*/
79d71ae5a4SJacob Faibussowitsch PetscErrorCode ISRestorePointRange(IS pointIS, PetscInt *pStart, PetscInt *pEnd, const PetscInt **points)
80d71ae5a4SJacob Faibussowitsch {
819305a4c7SMatthew G. Knepley   PetscInt  step = 1;
829305a4c7SMatthew G. Knepley   PetscBool isStride;
839305a4c7SMatthew G. Knepley 
849305a4c7SMatthew G. Knepley   PetscFunctionBeginHot;
859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pointIS, ISSTRIDE, &isStride));
869566063dSJacob Faibussowitsch   if (isStride) PetscCall(ISStrideGetInfo(pointIS, pStart, &step));
879566063dSJacob Faibussowitsch   if (!isStride || step != 1) PetscCall(ISGetIndices(pointIS, points));
883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
899305a4c7SMatthew G. Knepley }
909305a4c7SMatthew G. Knepley 
916528b96dSMatthew G. Knepley /*@C
92cab54364SBarry Smith   ISGetPointSubrange - Configures the input `IS` to be a subrange for the traversal information given
936528b96dSMatthew G. Knepley 
9420662ed9SBarry Smith   Not Collective
956528b96dSMatthew G. Knepley 
966528b96dSMatthew G. Knepley   Input Parameters:
97cab54364SBarry Smith + subpointIS - The `IS` object to be configured
986528b96dSMatthew G. Knepley . pStart     - The first index of the subrange
996528b96dSMatthew G. Knepley . pEnd       - One past the last index for the subrange
100cab54364SBarry Smith - points     - The indices for the entire range, from `ISGetPointRange()`
1016528b96dSMatthew G. Knepley 
1026528b96dSMatthew G. Knepley   Output Parameters:
103cab54364SBarry Smith . subpointIS - The `IS` object now configured to be a subrange
1046528b96dSMatthew G. Knepley 
1056528b96dSMatthew G. Knepley   Level: intermediate
1066528b96dSMatthew G. Knepley 
107cab54364SBarry Smith   Note:
108cab54364SBarry Smith   The input `IS` will now respond properly to calls to `ISGetPointRange()` and return the subrange.
109cab54364SBarry Smith 
110cab54364SBarry Smith .seealso: [](sec_scatter), `IS`, `ISGetPointRange()`, `ISRestorePointRange()`, `ISGetIndices()`, `ISCreateStride()`
1116528b96dSMatthew G. Knepley @*/
112d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGetPointSubrange(IS subpointIS, PetscInt pStart, PetscInt pEnd, const PetscInt *points)
113d71ae5a4SJacob Faibussowitsch {
1149305a4c7SMatthew G. Knepley   PetscFunctionBeginHot;
1159305a4c7SMatthew G. Knepley   if (points) {
1169566063dSJacob Faibussowitsch     PetscCall(ISSetType(subpointIS, ISGENERAL));
1179566063dSJacob Faibussowitsch     PetscCall(ISGeneralSetIndices(subpointIS, pEnd - pStart, &points[pStart], PETSC_USE_POINTER));
1189305a4c7SMatthew G. Knepley   } else {
1199566063dSJacob Faibussowitsch     PetscCall(ISSetType(subpointIS, ISSTRIDE));
1209566063dSJacob Faibussowitsch     PetscCall(ISStrideSetStride(subpointIS, pEnd - pStart, pStart, 1));
1219305a4c7SMatthew G. Knepley   }
1223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1239305a4c7SMatthew G. Knepley }
1249305a4c7SMatthew G. Knepley 
125413f72f0SBarry Smith /* -----------------------------------------------------------------------------------------*/
126413f72f0SBarry Smith 
127413f72f0SBarry Smith /*
128413f72f0SBarry Smith     Creates the global mapping information in the ISLocalToGlobalMapping structure
129413f72f0SBarry Smith 
130413f72f0SBarry Smith     If the user has not selected how to handle the global to local mapping then use HASH for "large" problems
131413f72f0SBarry Smith */
132d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISGlobalToLocalMappingSetUp(ISLocalToGlobalMapping mapping)
133d71ae5a4SJacob Faibussowitsch {
134413f72f0SBarry Smith   PetscInt i, *idx = mapping->indices, n = mapping->n, end, start;
135413f72f0SBarry Smith 
136413f72f0SBarry Smith   PetscFunctionBegin;
1373ba16761SJacob Faibussowitsch   if (mapping->data) PetscFunctionReturn(PETSC_SUCCESS);
138413f72f0SBarry Smith   end   = 0;
139413f72f0SBarry Smith   start = PETSC_MAX_INT;
140413f72f0SBarry Smith 
141413f72f0SBarry Smith   for (i = 0; i < n; i++) {
142413f72f0SBarry Smith     if (idx[i] < 0) continue;
143413f72f0SBarry Smith     if (idx[i] < start) start = idx[i];
144413f72f0SBarry Smith     if (idx[i] > end) end = idx[i];
145413f72f0SBarry Smith   }
1469371c9d4SSatish Balay   if (start > end) {
1479371c9d4SSatish Balay     start = 0;
1489371c9d4SSatish Balay     end   = -1;
1499371c9d4SSatish Balay   }
150413f72f0SBarry Smith   mapping->globalstart = start;
151413f72f0SBarry Smith   mapping->globalend   = end;
152413f72f0SBarry Smith   if (!((PetscObject)mapping)->type_name) {
153413f72f0SBarry Smith     if ((end - start) > PetscMax(4 * n, 1000000)) {
1549566063dSJacob Faibussowitsch       PetscCall(ISLocalToGlobalMappingSetType(mapping, ISLOCALTOGLOBALMAPPINGHASH));
155413f72f0SBarry Smith     } else {
1569566063dSJacob Faibussowitsch       PetscCall(ISLocalToGlobalMappingSetType(mapping, ISLOCALTOGLOBALMAPPINGBASIC));
157413f72f0SBarry Smith     }
158413f72f0SBarry Smith   }
159dbbe0bcdSBarry Smith   PetscTryTypeMethod(mapping, globaltolocalmappingsetup);
1603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
161413f72f0SBarry Smith }
162413f72f0SBarry Smith 
163d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISGlobalToLocalMappingSetUp_Basic(ISLocalToGlobalMapping mapping)
164d71ae5a4SJacob Faibussowitsch {
165413f72f0SBarry Smith   PetscInt                      i, *idx = mapping->indices, n = mapping->n, end, start, *globals;
166413f72f0SBarry Smith   ISLocalToGlobalMapping_Basic *map;
167413f72f0SBarry Smith 
168413f72f0SBarry Smith   PetscFunctionBegin;
169413f72f0SBarry Smith   start = mapping->globalstart;
170413f72f0SBarry Smith   end   = mapping->globalend;
1719566063dSJacob Faibussowitsch   PetscCall(PetscNew(&map));
1729566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(end - start + 2, &globals));
173413f72f0SBarry Smith   map->globals = globals;
174413f72f0SBarry Smith   for (i = 0; i < end - start + 1; i++) globals[i] = -1;
175413f72f0SBarry Smith   for (i = 0; i < n; i++) {
176413f72f0SBarry Smith     if (idx[i] < 0) continue;
177413f72f0SBarry Smith     globals[idx[i] - start] = i;
178413f72f0SBarry Smith   }
179413f72f0SBarry Smith   mapping->data = (void *)map;
1803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
181413f72f0SBarry Smith }
182413f72f0SBarry Smith 
183d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISGlobalToLocalMappingSetUp_Hash(ISLocalToGlobalMapping mapping)
184d71ae5a4SJacob Faibussowitsch {
185413f72f0SBarry Smith   PetscInt                     i, *idx = mapping->indices, n = mapping->n;
186413f72f0SBarry Smith   ISLocalToGlobalMapping_Hash *map;
187413f72f0SBarry Smith 
188413f72f0SBarry Smith   PetscFunctionBegin;
1899566063dSJacob Faibussowitsch   PetscCall(PetscNew(&map));
1909566063dSJacob Faibussowitsch   PetscCall(PetscHMapICreate(&map->globalht));
191413f72f0SBarry Smith   for (i = 0; i < n; i++) {
192413f72f0SBarry Smith     if (idx[i] < 0) continue;
1939566063dSJacob Faibussowitsch     PetscCall(PetscHMapISet(map->globalht, idx[i], i));
194413f72f0SBarry Smith   }
195413f72f0SBarry Smith   mapping->data = (void *)map;
1963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
197413f72f0SBarry Smith }
198413f72f0SBarry Smith 
199d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISLocalToGlobalMappingDestroy_Basic(ISLocalToGlobalMapping mapping)
200d71ae5a4SJacob Faibussowitsch {
201413f72f0SBarry Smith   ISLocalToGlobalMapping_Basic *map = (ISLocalToGlobalMapping_Basic *)mapping->data;
202413f72f0SBarry Smith 
203413f72f0SBarry Smith   PetscFunctionBegin;
2043ba16761SJacob Faibussowitsch   if (!map) PetscFunctionReturn(PETSC_SUCCESS);
2059566063dSJacob Faibussowitsch   PetscCall(PetscFree(map->globals));
2069566063dSJacob Faibussowitsch   PetscCall(PetscFree(mapping->data));
2073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
208413f72f0SBarry Smith }
209413f72f0SBarry Smith 
210d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISLocalToGlobalMappingDestroy_Hash(ISLocalToGlobalMapping mapping)
211d71ae5a4SJacob Faibussowitsch {
212413f72f0SBarry Smith   ISLocalToGlobalMapping_Hash *map = (ISLocalToGlobalMapping_Hash *)mapping->data;
213413f72f0SBarry Smith 
214413f72f0SBarry Smith   PetscFunctionBegin;
2153ba16761SJacob Faibussowitsch   if (!map) PetscFunctionReturn(PETSC_SUCCESS);
2169566063dSJacob Faibussowitsch   PetscCall(PetscHMapIDestroy(&map->globalht));
2179566063dSJacob Faibussowitsch   PetscCall(PetscFree(mapping->data));
2183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
219413f72f0SBarry Smith }
220413f72f0SBarry Smith 
221413f72f0SBarry Smith #define GTOLTYPE _Basic
222413f72f0SBarry Smith #define GTOLNAME _Basic
223541bf97eSAdrian Croucher #define GTOLBS   mapping->bs
2249371c9d4SSatish Balay #define GTOL(g, local) \
2259371c9d4SSatish Balay   do { \
226413f72f0SBarry Smith     local = map->globals[g / bs - start]; \
2270040bde1SJunchao Zhang     if (local >= 0) local = bs * local + (g % bs); \
228413f72f0SBarry Smith   } while (0)
229541bf97eSAdrian Croucher 
230413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h>
231413f72f0SBarry Smith 
232413f72f0SBarry Smith #define GTOLTYPE _Basic
233413f72f0SBarry Smith #define GTOLNAME Block_Basic
234541bf97eSAdrian Croucher #define GTOLBS   1
2359371c9d4SSatish Balay #define GTOL(g, local) \
236d71ae5a4SJacob Faibussowitsch   do { \
237d71ae5a4SJacob Faibussowitsch     local = map->globals[g - start]; \
238d71ae5a4SJacob Faibussowitsch   } while (0)
239413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h>
240413f72f0SBarry Smith 
241413f72f0SBarry Smith #define GTOLTYPE _Hash
242413f72f0SBarry Smith #define GTOLNAME _Hash
243541bf97eSAdrian Croucher #define GTOLBS   mapping->bs
2449371c9d4SSatish Balay #define GTOL(g, local) \
2459371c9d4SSatish Balay   do { \
246e8f14785SLisandro Dalcin     (void)PetscHMapIGet(map->globalht, g / bs, &local); \
2470040bde1SJunchao Zhang     if (local >= 0) local = bs * local + (g % bs); \
248413f72f0SBarry Smith   } while (0)
249413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h>
250413f72f0SBarry Smith 
251413f72f0SBarry Smith #define GTOLTYPE _Hash
252413f72f0SBarry Smith #define GTOLNAME Block_Hash
253541bf97eSAdrian Croucher #define GTOLBS   1
2549371c9d4SSatish Balay #define GTOL(g, local) \
255d71ae5a4SJacob Faibussowitsch   do { \
256d71ae5a4SJacob Faibussowitsch     (void)PetscHMapIGet(map->globalht, g, &local); \
257d71ae5a4SJacob Faibussowitsch   } while (0)
258413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h>
259413f72f0SBarry Smith 
2606658fb44Sstefano_zampini /*@
2616658fb44Sstefano_zampini   ISLocalToGlobalMappingDuplicate - Duplicates the local to global mapping object
2626658fb44Sstefano_zampini 
2636658fb44Sstefano_zampini   Not Collective
2646658fb44Sstefano_zampini 
2656658fb44Sstefano_zampini   Input Parameter:
2666658fb44Sstefano_zampini . ltog - local to global mapping
2676658fb44Sstefano_zampini 
2686658fb44Sstefano_zampini   Output Parameter:
2696658fb44Sstefano_zampini . nltog - the duplicated local to global mapping
2706658fb44Sstefano_zampini 
2716658fb44Sstefano_zampini   Level: advanced
2726658fb44Sstefano_zampini 
273cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`
2746658fb44Sstefano_zampini @*/
275d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingDuplicate(ISLocalToGlobalMapping ltog, ISLocalToGlobalMapping *nltog)
276d71ae5a4SJacob Faibussowitsch {
277a0d79125SStefano Zampini   ISLocalToGlobalMappingType l2gtype;
2786658fb44Sstefano_zampini 
2796658fb44Sstefano_zampini   PetscFunctionBegin;
2806658fb44Sstefano_zampini   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
2819566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)ltog), ltog->bs, ltog->n, ltog->indices, PETSC_COPY_VALUES, nltog));
2829566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingGetType(ltog, &l2gtype));
2839566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingSetType(*nltog, l2gtype));
2843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2856658fb44Sstefano_zampini }
2866658fb44Sstefano_zampini 
287565245c5SBarry Smith /*@
288107e9a97SBarry Smith   ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping
2893b9aefa3SBarry Smith 
2903b9aefa3SBarry Smith   Not Collective
2913b9aefa3SBarry Smith 
2923b9aefa3SBarry Smith   Input Parameter:
29338b5cf2dSJacob Faibussowitsch . mapping - local to global mapping
2943b9aefa3SBarry Smith 
2953b9aefa3SBarry Smith   Output Parameter:
296cab54364SBarry Smith . n - the number of entries in the local mapping, `ISLocalToGlobalMappingGetIndices()` returns an array of this length
2973b9aefa3SBarry Smith 
2983b9aefa3SBarry Smith   Level: advanced
2993b9aefa3SBarry Smith 
300cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`
3013b9aefa3SBarry Smith @*/
302d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping, PetscInt *n)
303d71ae5a4SJacob Faibussowitsch {
3043b9aefa3SBarry Smith   PetscFunctionBegin;
3050700a824SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
3064f572ea9SToby Isaac   PetscAssertPointer(n, 2);
307107e9a97SBarry Smith   *n = mapping->bs * mapping->n;
3083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3093b9aefa3SBarry Smith }
3103b9aefa3SBarry Smith 
3115a5d4f66SBarry Smith /*@C
312cab54364SBarry Smith   ISLocalToGlobalMappingViewFromOptions - View an `ISLocalToGlobalMapping` based on values in the options database
313fe2efc57SMark 
314c3339decSBarry Smith   Collective
315fe2efc57SMark 
316fe2efc57SMark   Input Parameters:
317fe2efc57SMark + A    - the local to global mapping object
31820662ed9SBarry Smith . obj  - Optional object that provides the options prefix used for the options database query
319736c3998SJose E. Roman - name - command line option
320fe2efc57SMark 
321fe2efc57SMark   Level: intermediate
322cab54364SBarry Smith 
32320662ed9SBarry Smith   Note:
32420662ed9SBarry Smith   See `PetscObjectViewFromOptions()` for the available `PetscViewer` and `PetscViewerFormat`
32520662ed9SBarry Smith 
32620662ed9SBarry Smith .seealso: [](sec_scatter), `PetscViewer`, ``ISLocalToGlobalMapping`, `ISLocalToGlobalMappingView`, `PetscObjectViewFromOptions()`, `ISLocalToGlobalMappingCreate()`
327fe2efc57SMark @*/
328d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingViewFromOptions(ISLocalToGlobalMapping A, PetscObject obj, const char name[])
329d71ae5a4SJacob Faibussowitsch {
330fe2efc57SMark   PetscFunctionBegin;
331fe2efc57SMark   PetscValidHeaderSpecific(A, IS_LTOGM_CLASSID, 1);
3329566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
3333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
334fe2efc57SMark }
335fe2efc57SMark 
336fe2efc57SMark /*@C
3375a5d4f66SBarry Smith   ISLocalToGlobalMappingView - View a local to global mapping
3385a5d4f66SBarry Smith 
339b9cd556bSLois Curfman McInnes   Not Collective
340b9cd556bSLois Curfman McInnes 
3415a5d4f66SBarry Smith   Input Parameters:
34238b5cf2dSJacob Faibussowitsch + mapping - local to global mapping
3433b9aefa3SBarry Smith - viewer  - viewer
3445a5d4f66SBarry Smith 
345a997ad1aSLois Curfman McInnes   Level: advanced
346a997ad1aSLois Curfman McInnes 
34720662ed9SBarry Smith .seealso: [](sec_scatter), `PetscViewer`, `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`
3485a5d4f66SBarry Smith @*/
349d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping, PetscViewer viewer)
350d71ae5a4SJacob Faibussowitsch {
35132dcc486SBarry Smith   PetscInt    i;
35232dcc486SBarry Smith   PetscMPIInt rank;
353ace3abfcSBarry Smith   PetscBool   iascii;
3545a5d4f66SBarry Smith 
3555a5d4f66SBarry Smith   PetscFunctionBegin;
3560700a824SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
35748a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping), &viewer));
3580700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
3595a5d4f66SBarry Smith 
3609566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)mapping), &rank));
3619566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
36232077d6dSBarry Smith   if (iascii) {
3639566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mapping, viewer));
3649566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushSynchronized(viewer));
365f2c6b1a2SJed Brown     for (i = 0; i < mapping->n; i++) {
366f2c6b1a2SJed Brown       PetscInt bs = mapping->bs, g = mapping->indices[i];
367f2c6b1a2SJed Brown       if (bs == 1) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT " %" PetscInt_FMT "\n", rank, i, g));
368f2c6b1a2SJed Brown       else PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":%" PetscInt_FMT " %" PetscInt_FMT ":%" PetscInt_FMT "\n", rank, i * bs, (i + 1) * bs, g * bs, (g + 1) * bs));
369f2c6b1a2SJed Brown     }
3709566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
3719566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopSynchronized(viewer));
3721575c14dSBarry Smith   }
3733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3745a5d4f66SBarry Smith }
3755a5d4f66SBarry Smith 
3761f428162SBarry Smith /*@
3772bdab257SBarry Smith   ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n)
3782bdab257SBarry Smith   ordering and a global parallel ordering.
3792bdab257SBarry Smith 
38020662ed9SBarry Smith   Not Collective
381b9cd556bSLois Curfman McInnes 
382a997ad1aSLois Curfman McInnes   Input Parameter:
3838c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number
3842bdab257SBarry Smith 
385a997ad1aSLois Curfman McInnes   Output Parameter:
3862bdab257SBarry Smith . mapping - new mapping data structure
3872bdab257SBarry Smith 
388a997ad1aSLois Curfman McInnes   Level: advanced
389a997ad1aSLois Curfman McInnes 
390cab54364SBarry Smith   Note:
391cab54364SBarry Smith   the block size of the `IS` determines the block size of the mapping
392cab54364SBarry Smith 
393cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetFromOptions()`
3942bdab257SBarry Smith @*/
395d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is, ISLocalToGlobalMapping *mapping)
396d71ae5a4SJacob Faibussowitsch {
3973bbf0e92SBarry Smith   PetscInt        n, bs;
3985d0c19d7SBarry Smith   const PetscInt *indices;
3992bdab257SBarry Smith   MPI_Comm        comm;
4003bbf0e92SBarry Smith   PetscBool       isblock;
4013a40ed3dSBarry Smith 
4023a40ed3dSBarry Smith   PetscFunctionBegin;
4030700a824SBarry Smith   PetscValidHeaderSpecific(is, IS_CLASSID, 1);
4044f572ea9SToby Isaac   PetscAssertPointer(mapping, 2);
4052bdab257SBarry Smith 
4069566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)is, &comm));
4079566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(is, &n));
4089566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)is, ISBLOCK, &isblock));
4096006e8d2SBarry Smith   if (!isblock) {
4109566063dSJacob Faibussowitsch     PetscCall(ISGetIndices(is, &indices));
4119566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingCreate(comm, 1, n, indices, PETSC_COPY_VALUES, mapping));
4129566063dSJacob Faibussowitsch     PetscCall(ISRestoreIndices(is, &indices));
4136006e8d2SBarry Smith   } else {
4149566063dSJacob Faibussowitsch     PetscCall(ISGetBlockSize(is, &bs));
4159566063dSJacob Faibussowitsch     PetscCall(ISBlockGetIndices(is, &indices));
4169566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingCreate(comm, bs, n / bs, indices, PETSC_COPY_VALUES, mapping));
4179566063dSJacob Faibussowitsch     PetscCall(ISBlockRestoreIndices(is, &indices));
4186006e8d2SBarry Smith   }
4193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4202bdab257SBarry Smith }
4215a5d4f66SBarry Smith 
422a4d96a55SJed Brown /*@C
423a4d96a55SJed Brown   ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n)
424a4d96a55SJed Brown   ordering and a global parallel ordering.
425a4d96a55SJed Brown 
426a4d96a55SJed Brown   Collective
427a4d96a55SJed Brown 
428d8d19677SJose E. Roman   Input Parameters:
429a4d96a55SJed Brown + sf    - star forest mapping contiguous local indices to (rank, offset)
430cab54364SBarry Smith - start - first global index on this process, or `PETSC_DECIDE` to compute contiguous global numbering automatically
431a4d96a55SJed Brown 
432a4d96a55SJed Brown   Output Parameter:
433a4d96a55SJed Brown . mapping - new mapping data structure
434a4d96a55SJed Brown 
435a4d96a55SJed Brown   Level: advanced
436a4d96a55SJed Brown 
43720662ed9SBarry Smith   Note:
438*633354d9SStefano Zampini   If a process calls this function with `start` = `PETSC_DECIDE` then all processes must, otherwise the program will hang.
4399a535bafSVaclav Hapla 
440cab54364SBarry Smith .seealso: [](sec_scatter), `PetscSF`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingSetFromOptions()`
441a4d96a55SJed Brown @*/
442d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf, PetscInt start, ISLocalToGlobalMapping *mapping)
443d71ae5a4SJacob Faibussowitsch {
444a4d96a55SJed Brown   PetscInt i, maxlocal, nroots, nleaves, *globals, *ltog;
445a4d96a55SJed Brown   MPI_Comm comm;
446a4d96a55SJed Brown 
447a4d96a55SJed Brown   PetscFunctionBegin;
448a4d96a55SJed Brown   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1);
4494f572ea9SToby Isaac   PetscAssertPointer(mapping, 3);
4509566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)sf, &comm));
45141f4c31fSVaclav Hapla   PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL));
4529a535bafSVaclav Hapla   if (start == PETSC_DECIDE) {
4539a535bafSVaclav Hapla     start = 0;
4549566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Exscan(&nroots, &start, 1, MPIU_INT, MPI_SUM, comm));
45541f4c31fSVaclav Hapla   } else PetscCheck(start >= 0, comm, PETSC_ERR_ARG_OUTOFRANGE, "start must be nonnegative or PETSC_DECIDE");
45641f4c31fSVaclav Hapla   PetscCall(PetscSFGetLeafRange(sf, NULL, &maxlocal));
45741f4c31fSVaclav Hapla   ++maxlocal;
4589566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(nroots, &globals));
4599566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(maxlocal, &ltog));
460a4d96a55SJed Brown   for (i = 0; i < nroots; i++) globals[i] = start + i;
461a4d96a55SJed Brown   for (i = 0; i < maxlocal; i++) ltog[i] = -1;
4629566063dSJacob Faibussowitsch   PetscCall(PetscSFBcastBegin(sf, MPIU_INT, globals, ltog, MPI_REPLACE));
4639566063dSJacob Faibussowitsch   PetscCall(PetscSFBcastEnd(sf, MPIU_INT, globals, ltog, MPI_REPLACE));
4649566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingCreate(comm, 1, maxlocal, ltog, PETSC_OWN_POINTER, mapping));
4659566063dSJacob Faibussowitsch   PetscCall(PetscFree(globals));
4663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
467a4d96a55SJed Brown }
468b46b645bSBarry Smith 
469*633354d9SStefano Zampini static PetscErrorCode ISLocalToGlobalMappingResetBlockInfo_Private(ISLocalToGlobalMapping mapping)
470*633354d9SStefano Zampini {
471*633354d9SStefano Zampini   PetscFunctionBegin;
472*633354d9SStefano Zampini   PetscCall(PetscFree(mapping->info_procs));
473*633354d9SStefano Zampini   PetscCall(PetscFree(mapping->info_numprocs));
474*633354d9SStefano Zampini   if (mapping->info_indices) {
475*633354d9SStefano Zampini     for (PetscInt i = 0; i < mapping->info_nproc; i++) PetscCall(PetscFree(mapping->info_indices[i]));
476*633354d9SStefano Zampini     PetscCall(PetscFree(mapping->info_indices));
477*633354d9SStefano Zampini   }
478*633354d9SStefano Zampini   if (mapping->info_nodei) PetscCall(PetscFree(mapping->info_nodei[0]));
479*633354d9SStefano Zampini   PetscCall(PetscFree2(mapping->info_nodec, mapping->info_nodei));
480*633354d9SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
481*633354d9SStefano Zampini }
482*633354d9SStefano Zampini 
48363fa5c83Sstefano_zampini /*@
48463fa5c83Sstefano_zampini   ISLocalToGlobalMappingSetBlockSize - Sets the blocksize of the mapping
48563fa5c83Sstefano_zampini 
48620662ed9SBarry Smith   Not Collective
48763fa5c83Sstefano_zampini 
48863fa5c83Sstefano_zampini   Input Parameters:
489a2b725a8SWilliam Gropp + mapping - mapping data structure
490a2b725a8SWilliam Gropp - bs      - the blocksize
49163fa5c83Sstefano_zampini 
49263fa5c83Sstefano_zampini   Level: advanced
49363fa5c83Sstefano_zampini 
494cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`
49563fa5c83Sstefano_zampini @*/
496d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingSetBlockSize(ISLocalToGlobalMapping mapping, PetscInt bs)
497d71ae5a4SJacob Faibussowitsch {
498a59f3c4dSstefano_zampini   PetscInt       *nid;
499a59f3c4dSstefano_zampini   const PetscInt *oid;
500a59f3c4dSstefano_zampini   PetscInt        i, cn, on, obs, nn;
50163fa5c83Sstefano_zampini 
50263fa5c83Sstefano_zampini   PetscFunctionBegin;
50363fa5c83Sstefano_zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
50408401ef6SPierre Jolivet   PetscCheck(bs >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid block size %" PetscInt_FMT, bs);
5053ba16761SJacob Faibussowitsch   if (bs == mapping->bs) PetscFunctionReturn(PETSC_SUCCESS);
50663fa5c83Sstefano_zampini   on  = mapping->n;
50763fa5c83Sstefano_zampini   obs = mapping->bs;
50863fa5c83Sstefano_zampini   oid = mapping->indices;
50963fa5c83Sstefano_zampini   nn  = (on * obs) / bs;
51008401ef6SPierre Jolivet   PetscCheck((on * obs) % bs == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Block size %" PetscInt_FMT " is inconsistent with block size %" PetscInt_FMT " and number of block indices %" PetscInt_FMT, bs, obs, on);
511a59f3c4dSstefano_zampini 
5129566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(nn, &nid));
5139566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingGetIndices(mapping, &oid));
514a59f3c4dSstefano_zampini   for (i = 0; i < nn; i++) {
515a59f3c4dSstefano_zampini     PetscInt j;
516a59f3c4dSstefano_zampini     for (j = 0, cn = 0; j < bs - 1; j++) {
5179371c9d4SSatish Balay       if (oid[i * bs + j] < 0) {
5189371c9d4SSatish Balay         cn++;
5199371c9d4SSatish Balay         continue;
5209371c9d4SSatish Balay       }
52108401ef6SPierre Jolivet       PetscCheck(oid[i * bs + j] == oid[i * bs + j + 1] - 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Block sizes %" PetscInt_FMT " and %" PetscInt_FMT " are incompatible with the block indices: non consecutive indices %" PetscInt_FMT " %" PetscInt_FMT, bs, obs, oid[i * bs + j], oid[i * bs + j + 1]);
522a59f3c4dSstefano_zampini     }
523a59f3c4dSstefano_zampini     if (oid[i * bs + j] < 0) cn++;
5248b7cb0e6Sstefano_zampini     if (cn) {
52508401ef6SPierre Jolivet       PetscCheck(cn == bs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Block sizes %" PetscInt_FMT " and %" PetscInt_FMT " are incompatible with the block indices: invalid number of negative entries in block %" PetscInt_FMT, bs, obs, cn);
526a59f3c4dSstefano_zampini       nid[i] = -1;
5278b7cb0e6Sstefano_zampini     } else {
528a59f3c4dSstefano_zampini       nid[i] = oid[i * bs] / bs;
52963fa5c83Sstefano_zampini     }
53063fa5c83Sstefano_zampini   }
5319566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingRestoreIndices(mapping, &oid));
532a59f3c4dSstefano_zampini 
53363fa5c83Sstefano_zampini   mapping->n  = nn;
53463fa5c83Sstefano_zampini   mapping->bs = bs;
5359566063dSJacob Faibussowitsch   PetscCall(PetscFree(mapping->indices));
53663fa5c83Sstefano_zampini   mapping->indices     = nid;
537c9345713Sstefano_zampini   mapping->globalstart = 0;
538c9345713Sstefano_zampini   mapping->globalend   = 0;
5391bd0b88eSStefano Zampini 
5401bd0b88eSStefano Zampini   /* reset the cached information */
541*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingResetBlockInfo_Private(mapping));
542dbbe0bcdSBarry Smith   PetscTryTypeMethod(mapping, destroy);
5433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
54463fa5c83Sstefano_zampini }
54563fa5c83Sstefano_zampini 
54645b6f7e9SBarry Smith /*@
54745b6f7e9SBarry Smith   ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping
54845b6f7e9SBarry Smith   ordering and a global parallel ordering.
54945b6f7e9SBarry Smith 
55045b6f7e9SBarry Smith   Not Collective
55145b6f7e9SBarry Smith 
5522fe279fdSBarry Smith   Input Parameter:
55345b6f7e9SBarry Smith . mapping - mapping data structure
55445b6f7e9SBarry Smith 
55545b6f7e9SBarry Smith   Output Parameter:
55645b6f7e9SBarry Smith . bs - the blocksize
55745b6f7e9SBarry Smith 
55845b6f7e9SBarry Smith   Level: advanced
55945b6f7e9SBarry Smith 
560cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`
56145b6f7e9SBarry Smith @*/
562d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping, PetscInt *bs)
563d71ae5a4SJacob Faibussowitsch {
56445b6f7e9SBarry Smith   PetscFunctionBegin;
565cbc1caf0SMatthew G. Knepley   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
56645b6f7e9SBarry Smith   *bs = mapping->bs;
5673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
56845b6f7e9SBarry Smith }
56945b6f7e9SBarry Smith 
570ba5bb76aSSatish Balay /*@
57190f02eecSBarry Smith   ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n)
57290f02eecSBarry Smith   ordering and a global parallel ordering.
5732362add9SBarry Smith 
57489d82c54SBarry Smith   Not Collective, but communicator may have more than one process
575b9cd556bSLois Curfman McInnes 
5762362add9SBarry Smith   Input Parameters:
57789d82c54SBarry Smith + comm    - MPI communicator
578f0413b6fSBarry Smith . bs      - the block size
57928bc9809SBarry Smith . n       - the number of local elements divided by the block size, or equivalently the number of block indices
58028bc9809SBarry Smith . indices - the global index for each local element, these do not need to be in increasing order (sorted), these values should not be scaled (i.e. multiplied) by the blocksize bs
581d5ad8652SBarry Smith - mode    - see PetscCopyMode
5822362add9SBarry Smith 
583a997ad1aSLois Curfman McInnes   Output Parameter:
58490f02eecSBarry Smith . mapping - new mapping data structure
5852362add9SBarry Smith 
586cab54364SBarry Smith   Level: advanced
587cab54364SBarry Smith 
58895452b02SPatrick Sanan   Notes:
58995452b02SPatrick Sanan   There is one integer value in indices per block and it represents the actual indices bs*idx + j, where j=0,..,bs-1
590413f72f0SBarry Smith 
591cab54364SBarry Smith   For "small" problems when using `ISGlobalToLocalMappingApply()` and `ISGlobalToLocalMappingApplyBlock()`, the `ISLocalToGlobalMappingType`
592cab54364SBarry Smith   of `ISLOCALTOGLOBALMAPPINGBASIC` will be used; this uses more memory but is faster; this approach is not scalable for extremely large mappings.
593413f72f0SBarry Smith 
594cab54364SBarry Smith   For large problems `ISLOCALTOGLOBALMAPPINGHASH` is used, this is scalable.
59520662ed9SBarry Smith   Use `ISLocalToGlobalMappingSetType()` or call `ISLocalToGlobalMappingSetFromOptions()` with the option
59620662ed9SBarry Smith   `-islocaltoglobalmapping_type` <`basic`,`hash`> to control which is used.
597a997ad1aSLois Curfman McInnes 
59820662ed9SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingSetFromOptions()`,
59920662ed9SBarry Smith           `ISLOCALTOGLOBALMAPPINGBASIC`, `ISLOCALTOGLOBALMAPPINGHASH`
600db781477SPatrick Sanan           `ISLocalToGlobalMappingSetType()`, `ISLocalToGlobalMappingType`
6012362add9SBarry Smith @*/
602d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm comm, PetscInt bs, PetscInt n, const PetscInt indices[], PetscCopyMode mode, ISLocalToGlobalMapping *mapping)
603d71ae5a4SJacob Faibussowitsch {
60432dcc486SBarry Smith   PetscInt *in;
605b46b645bSBarry Smith 
606b46b645bSBarry Smith   PetscFunctionBegin;
6074f572ea9SToby Isaac   if (n) PetscAssertPointer(indices, 4);
6084f572ea9SToby Isaac   PetscAssertPointer(mapping, 6);
609b46b645bSBarry Smith 
6100298fd71SBarry Smith   *mapping = NULL;
6119566063dSJacob Faibussowitsch   PetscCall(ISInitializePackage());
6122362add9SBarry Smith 
6139566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(*mapping, IS_LTOGM_CLASSID, "ISLocalToGlobalMapping", "Local to global mapping", "IS", comm, ISLocalToGlobalMappingDestroy, ISLocalToGlobalMappingView));
614d4bb536fSBarry Smith   (*mapping)->n  = n;
615f0413b6fSBarry Smith   (*mapping)->bs = bs;
616d5ad8652SBarry Smith   if (mode == PETSC_COPY_VALUES) {
6179566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &in));
6189566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(in, indices, n));
619d5ad8652SBarry Smith     (*mapping)->indices         = in;
62071910c26SVaclav Hapla     (*mapping)->dealloc_indices = PETSC_TRUE;
6216389a1a1SBarry Smith   } else if (mode == PETSC_OWN_POINTER) {
6226389a1a1SBarry Smith     (*mapping)->indices         = (PetscInt *)indices;
62371910c26SVaclav Hapla     (*mapping)->dealloc_indices = PETSC_TRUE;
62471910c26SVaclav Hapla   } else if (mode == PETSC_USE_POINTER) {
62571910c26SVaclav Hapla     (*mapping)->indices = (PetscInt *)indices;
6269371c9d4SSatish Balay   } else SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid mode %d", mode);
6273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6282362add9SBarry Smith }
6292362add9SBarry Smith 
630413f72f0SBarry Smith PetscFunctionList ISLocalToGlobalMappingList = NULL;
631413f72f0SBarry Smith 
63290f02eecSBarry Smith /*@
6337e99dc12SLawrence Mitchell   ISLocalToGlobalMappingSetFromOptions - Set mapping options from the options database.
6347e99dc12SLawrence Mitchell 
63520662ed9SBarry Smith   Not Collective
6367e99dc12SLawrence Mitchell 
6372fe279fdSBarry Smith   Input Parameter:
6387e99dc12SLawrence Mitchell . mapping - mapping data structure
6397e99dc12SLawrence Mitchell 
64020662ed9SBarry Smith   Options Database Key:
64120662ed9SBarry Smith . -islocaltoglobalmapping_type - <basic,hash> nonscalable and scalable versions
64220662ed9SBarry Smith 
6437e99dc12SLawrence Mitchell   Level: advanced
6447e99dc12SLawrence Mitchell 
64542747ad1SJacob Faibussowitsch .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`,
64642747ad1SJacob Faibussowitsch `ISLocalToGlobalMappingCreateIS()`, `ISLOCALTOGLOBALMAPPINGBASIC`,
64742747ad1SJacob Faibussowitsch `ISLOCALTOGLOBALMAPPINGHASH`, `ISLocalToGlobalMappingSetType()`, `ISLocalToGlobalMappingType`
6487e99dc12SLawrence Mitchell @*/
649d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingSetFromOptions(ISLocalToGlobalMapping mapping)
650d71ae5a4SJacob Faibussowitsch {
651413f72f0SBarry Smith   char                       type[256];
652413f72f0SBarry Smith   ISLocalToGlobalMappingType defaulttype = "Not set";
6537e99dc12SLawrence Mitchell   PetscBool                  flg;
6547e99dc12SLawrence Mitchell 
6557e99dc12SLawrence Mitchell   PetscFunctionBegin;
6567e99dc12SLawrence Mitchell   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
6579566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingRegisterAll());
658d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)mapping);
6599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-islocaltoglobalmapping_type", "ISLocalToGlobalMapping method", "ISLocalToGlobalMappingSetType", ISLocalToGlobalMappingList, (char *)(((PetscObject)mapping)->type_name) ? ((PetscObject)mapping)->type_name : defaulttype, type, 256, &flg));
6601baa6e33SBarry Smith   if (flg) PetscCall(ISLocalToGlobalMappingSetType(mapping, type));
661d0609cedSBarry Smith   PetscOptionsEnd();
6623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6637e99dc12SLawrence Mitchell }
6647e99dc12SLawrence Mitchell 
6657e99dc12SLawrence Mitchell /*@
66690f02eecSBarry Smith   ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n)
66790f02eecSBarry Smith   ordering and a global parallel ordering.
66890f02eecSBarry Smith 
66920662ed9SBarry Smith   Not Collective
670b9cd556bSLois Curfman McInnes 
6712fe279fdSBarry Smith   Input Parameter:
67290f02eecSBarry Smith . mapping - mapping data structure
67390f02eecSBarry Smith 
674a997ad1aSLois Curfman McInnes   Level: advanced
675a997ad1aSLois Curfman McInnes 
676cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingCreate()`
67790f02eecSBarry Smith @*/
678d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping)
679d71ae5a4SJacob Faibussowitsch {
6803a40ed3dSBarry Smith   PetscFunctionBegin;
6813ba16761SJacob Faibussowitsch   if (!*mapping) PetscFunctionReturn(PETSC_SUCCESS);
682f4f49eeaSPierre Jolivet   PetscValidHeaderSpecific(*mapping, IS_LTOGM_CLASSID, 1);
683f4f49eeaSPierre Jolivet   if (--((PetscObject)*mapping)->refct > 0) {
6849371c9d4SSatish Balay     *mapping = NULL;
6853ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
68671910c26SVaclav Hapla   }
68748a46eb9SPierre Jolivet   if ((*mapping)->dealloc_indices) PetscCall(PetscFree((*mapping)->indices));
688*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingResetBlockInfo_Private(*mapping));
689213acdd3SPierre Jolivet   PetscTryTypeMethod(*mapping, destroy);
6909566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(mapping));
6913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
69290f02eecSBarry Smith }
69390f02eecSBarry Smith 
69490f02eecSBarry Smith /*@
695cab54364SBarry Smith   ISLocalToGlobalMappingApplyIS - Creates from an `IS` in the local numbering
696cab54364SBarry Smith   a new index set using the global numbering defined in an `ISLocalToGlobalMapping`
6973acfe500SLois Curfman McInnes   context.
69890f02eecSBarry Smith 
699c3339decSBarry Smith   Collective
700b9cd556bSLois Curfman McInnes 
70190f02eecSBarry Smith   Input Parameters:
702b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering
703b9cd556bSLois Curfman McInnes - is      - index set in local numbering
70490f02eecSBarry Smith 
705cab54364SBarry Smith   Output Parameter:
70690f02eecSBarry Smith . newis - index set in global numbering
70790f02eecSBarry Smith 
708a997ad1aSLois Curfman McInnes   Level: advanced
709a997ad1aSLois Curfman McInnes 
710cab54364SBarry Smith   Note:
71120662ed9SBarry Smith   The output `IS` will have the same communicator as the input `IS`.
712cab54364SBarry Smith 
713cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingCreate()`,
714db781477SPatrick Sanan           `ISLocalToGlobalMappingDestroy()`, `ISGlobalToLocalMappingApply()`
71590f02eecSBarry Smith @*/
716d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping, IS is, IS *newis)
717d71ae5a4SJacob Faibussowitsch {
718e24637baSBarry Smith   PetscInt        n, *idxout;
7195d0c19d7SBarry Smith   const PetscInt *idxin;
7203a40ed3dSBarry Smith 
7213a40ed3dSBarry Smith   PetscFunctionBegin;
7220700a824SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
7230700a824SBarry Smith   PetscValidHeaderSpecific(is, IS_CLASSID, 2);
7244f572ea9SToby Isaac   PetscAssertPointer(newis, 3);
72590f02eecSBarry Smith 
7269566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(is, &n));
7279566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(is, &idxin));
7289566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &idxout));
7299566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingApply(mapping, n, idxin, idxout));
7309566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(is, &idxin));
7319566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)is), n, idxout, PETSC_OWN_POINTER, newis));
7323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
73390f02eecSBarry Smith }
73490f02eecSBarry Smith 
735b89cb25eSSatish Balay /*@
7363acfe500SLois Curfman McInnes   ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering
7373acfe500SLois Curfman McInnes   and converts them to the global numbering.
73890f02eecSBarry Smith 
73920662ed9SBarry Smith   Not Collective
740b9cd556bSLois Curfman McInnes 
741bb25748dSBarry Smith   Input Parameters:
742b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context
743bb25748dSBarry Smith . N       - number of integers
744b9cd556bSLois Curfman McInnes - in      - input indices in local numbering
745bb25748dSBarry Smith 
746bb25748dSBarry Smith   Output Parameter:
747bb25748dSBarry Smith . out - indices in global numbering
748bb25748dSBarry Smith 
749a997ad1aSLois Curfman McInnes   Level: advanced
750a997ad1aSLois Curfman McInnes 
751cab54364SBarry Smith   Note:
75220662ed9SBarry Smith   The `in` and `out` array parameters may be identical.
753cab54364SBarry Smith 
754cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApplyBlock()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingDestroy()`,
755c2e3fba1SPatrick Sanan           `ISLocalToGlobalMappingApplyIS()`, `AOCreateBasic()`, `AOApplicationToPetsc()`,
756db781477SPatrick Sanan           `AOPetscToApplication()`, `ISGlobalToLocalMappingApply()`
757afcb2eb5SJed Brown @*/
758d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping, PetscInt N, const PetscInt in[], PetscInt out[])
759d71ae5a4SJacob Faibussowitsch {
760cbc1caf0SMatthew G. Knepley   PetscInt i, bs, Nmax;
76145b6f7e9SBarry Smith 
76245b6f7e9SBarry Smith   PetscFunctionBegin;
763cbc1caf0SMatthew G. Knepley   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
764cbc1caf0SMatthew G. Knepley   bs   = mapping->bs;
765cbc1caf0SMatthew G. Knepley   Nmax = bs * mapping->n;
76645b6f7e9SBarry Smith   if (bs == 1) {
767cbc1caf0SMatthew G. Knepley     const PetscInt *idx = mapping->indices;
76845b6f7e9SBarry Smith     for (i = 0; i < N; i++) {
76945b6f7e9SBarry Smith       if (in[i] < 0) {
77045b6f7e9SBarry Smith         out[i] = in[i];
77145b6f7e9SBarry Smith         continue;
77245b6f7e9SBarry Smith       }
77308401ef6SPierre Jolivet       PetscCheck(in[i] < Nmax, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local index %" PetscInt_FMT " too large %" PetscInt_FMT " (max) at %" PetscInt_FMT, in[i], Nmax - 1, i);
77445b6f7e9SBarry Smith       out[i] = idx[in[i]];
77545b6f7e9SBarry Smith     }
77645b6f7e9SBarry Smith   } else {
777cbc1caf0SMatthew G. Knepley     const PetscInt *idx = mapping->indices;
77845b6f7e9SBarry Smith     for (i = 0; i < N; i++) {
77945b6f7e9SBarry Smith       if (in[i] < 0) {
78045b6f7e9SBarry Smith         out[i] = in[i];
78145b6f7e9SBarry Smith         continue;
78245b6f7e9SBarry Smith       }
78308401ef6SPierre Jolivet       PetscCheck(in[i] < Nmax, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local index %" PetscInt_FMT " too large %" PetscInt_FMT " (max) at %" PetscInt_FMT, in[i], Nmax - 1, i);
78445b6f7e9SBarry Smith       out[i] = idx[in[i] / bs] * bs + (in[i] % bs);
78545b6f7e9SBarry Smith     }
78645b6f7e9SBarry Smith   }
7873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
78845b6f7e9SBarry Smith }
78945b6f7e9SBarry Smith 
79045b6f7e9SBarry Smith /*@
7916006e8d2SBarry Smith   ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering
79245b6f7e9SBarry Smith 
79320662ed9SBarry Smith   Not Collective
79445b6f7e9SBarry Smith 
79545b6f7e9SBarry Smith   Input Parameters:
79645b6f7e9SBarry Smith + mapping - the local to global mapping context
79745b6f7e9SBarry Smith . N       - number of integers
7986006e8d2SBarry Smith - in      - input indices in local block numbering
79945b6f7e9SBarry Smith 
80045b6f7e9SBarry Smith   Output Parameter:
8016006e8d2SBarry Smith . out - indices in global block numbering
80245b6f7e9SBarry Smith 
8036006e8d2SBarry Smith   Example:
804cab54364SBarry Smith   If the index values are {0,1,6,7} set with a call to `ISLocalToGlobalMappingCreate`(`PETSC_COMM_SELF`,2,2,{0,3}) then the mapping applied to 0
8056006e8d2SBarry Smith   (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3.
8066006e8d2SBarry Smith 
80720662ed9SBarry Smith   Level: advanced
80820662ed9SBarry Smith 
80920662ed9SBarry Smith   Note:
81020662ed9SBarry Smith   The `in` and `out` array parameters may be identical.
81120662ed9SBarry Smith 
812cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingDestroy()`,
813c2e3fba1SPatrick Sanan           `ISLocalToGlobalMappingApplyIS()`, `AOCreateBasic()`, `AOApplicationToPetsc()`,
814db781477SPatrick Sanan           `AOPetscToApplication()`, `ISGlobalToLocalMappingApply()`
81545b6f7e9SBarry Smith @*/
816d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping, PetscInt N, const PetscInt in[], PetscInt out[])
817d71ae5a4SJacob Faibussowitsch {
8188a1f772fSStefano Zampini   PetscInt        i, Nmax;
8198a1f772fSStefano Zampini   const PetscInt *idx;
820d4bb536fSBarry Smith 
821a0d79125SStefano Zampini   PetscFunctionBegin;
822a0d79125SStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
8238a1f772fSStefano Zampini   Nmax = mapping->n;
8248a1f772fSStefano Zampini   idx  = mapping->indices;
825afcb2eb5SJed Brown   for (i = 0; i < N; i++) {
826afcb2eb5SJed Brown     if (in[i] < 0) {
827afcb2eb5SJed Brown       out[i] = in[i];
828afcb2eb5SJed Brown       continue;
829afcb2eb5SJed Brown     }
83008401ef6SPierre Jolivet     PetscCheck(in[i] < Nmax, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local block index %" PetscInt_FMT " too large %" PetscInt_FMT " (max) at %" PetscInt_FMT, in[i], Nmax - 1, i);
831afcb2eb5SJed Brown     out[i] = idx[in[i]];
832afcb2eb5SJed Brown   }
8333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
834afcb2eb5SJed Brown }
835d4bb536fSBarry Smith 
8367e99dc12SLawrence Mitchell /*@
837a997ad1aSLois Curfman McInnes   ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers
838a997ad1aSLois Curfman McInnes   specified with a global numbering.
839d4bb536fSBarry Smith 
84020662ed9SBarry Smith   Not Collective
841b9cd556bSLois Curfman McInnes 
842d4bb536fSBarry Smith   Input Parameters:
843b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering
844cab54364SBarry Smith . type    - `IS_GTOLM_MASK` - maps global indices with no local value to -1 in the output list (i.e., mask them)
845cab54364SBarry Smith            `IS_GTOLM_DROP` - drops the indices with no local value from the output list
846d4bb536fSBarry Smith . n       - number of global indices to map
847b9cd556bSLois Curfman McInnes - idx     - global indices to map
848d4bb536fSBarry Smith 
849d4bb536fSBarry Smith   Output Parameters:
850cab54364SBarry Smith + nout   - number of indices in output array (if type == `IS_GTOLM_MASK` then nout = n)
851b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough
852cab54364SBarry Smith              to hold all the indices. You can call `ISGlobalToLocalMappingApply()` with
8530298fd71SBarry Smith              idxout == NULL to determine the required length (returned in nout)
854cab54364SBarry Smith              and then allocate the required space and call `ISGlobalToLocalMappingApply()`
855e182c471SBarry Smith              a second time to set the values.
856d4bb536fSBarry Smith 
857cab54364SBarry Smith   Level: advanced
858cab54364SBarry Smith 
859b9cd556bSLois Curfman McInnes   Notes:
86020662ed9SBarry Smith   Either `nout` or `idxout` may be `NULL`. `idx` and `idxout` may be identical.
861d4bb536fSBarry Smith 
86220662ed9SBarry Smith   For "small" problems when using `ISGlobalToLocalMappingApply()` and `ISGlobalToLocalMappingApplyBlock()`, the `ISLocalToGlobalMappingType` of
86320662ed9SBarry Smith   `ISLOCALTOGLOBALMAPPINGBASIC` will be used;
864cab54364SBarry Smith   this uses more memory but is faster; this approach is not scalable for extremely large mappings. For large problems `ISLOCALTOGLOBALMAPPINGHASH` is used, this is scalable.
865cab54364SBarry Smith   Use `ISLocalToGlobalMappingSetType()` or call `ISLocalToGlobalMappingSetFromOptions()` with the option -islocaltoglobalmapping_type <basic,hash> to control which is used.
8660f5bd95cSBarry Smith 
86738b5cf2dSJacob Faibussowitsch   Developer Notes:
86820662ed9SBarry Smith   The manual page states that `idx` and `idxout` may be identical but the calling
86920662ed9SBarry Smith   sequence declares `idx` as const so it cannot be the same as `idxout`.
87032fd6b96SBarry Smith 
871cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApply()`, `ISGlobalToLocalMappingApplyBlock()`, `ISLocalToGlobalMappingCreate()`,
872db781477SPatrick Sanan           `ISLocalToGlobalMappingDestroy()`
873d4bb536fSBarry Smith @*/
874d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingMode type, PetscInt n, const PetscInt idx[], PetscInt *nout, PetscInt idxout[])
875d71ae5a4SJacob Faibussowitsch {
8769d90f715SBarry Smith   PetscFunctionBegin;
8779d90f715SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
87848a46eb9SPierre Jolivet   if (!mapping->data) PetscCall(ISGlobalToLocalMappingSetUp(mapping));
879dbbe0bcdSBarry Smith   PetscUseTypeMethod(mapping, globaltolocalmappingapply, type, n, idx, nout, idxout);
8803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8819d90f715SBarry Smith }
8829d90f715SBarry Smith 
883d4fe737eSStefano Zampini /*@
884cab54364SBarry Smith   ISGlobalToLocalMappingApplyIS - Creates from an `IS` in the global numbering
885cab54364SBarry Smith   a new index set using the local numbering defined in an `ISLocalToGlobalMapping`
886d4fe737eSStefano Zampini   context.
887d4fe737eSStefano Zampini 
88820662ed9SBarry Smith   Not Collective
889d4fe737eSStefano Zampini 
890d4fe737eSStefano Zampini   Input Parameters:
891d4fe737eSStefano Zampini + mapping - mapping between local and global numbering
892cab54364SBarry Smith . type    - `IS_GTOLM_MASK` - maps global indices with no local value to -1 in the output list (i.e., mask them)
893cab54364SBarry Smith            `IS_GTOLM_DROP` - drops the indices with no local value from the output list
894d4fe737eSStefano Zampini - is      - index set in global numbering
895d4fe737eSStefano Zampini 
8962fe279fdSBarry Smith   Output Parameter:
897d4fe737eSStefano Zampini . newis - index set in local numbering
898d4fe737eSStefano Zampini 
899d4fe737eSStefano Zampini   Level: advanced
900d4fe737eSStefano Zampini 
901cab54364SBarry Smith   Note:
902cab54364SBarry Smith   The output `IS` will be sequential, as it encodes a purely local operation
903cab54364SBarry Smith 
904cab54364SBarry Smith .seealso: [](sec_scatter), `ISGlobalToLocalMapping`, `ISGlobalToLocalMappingApply()`, `ISLocalToGlobalMappingCreate()`,
905db781477SPatrick Sanan           `ISLocalToGlobalMappingDestroy()`
906d4fe737eSStefano Zampini @*/
907d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingMode type, IS is, IS *newis)
908d71ae5a4SJacob Faibussowitsch {
909d4fe737eSStefano Zampini   PetscInt        n, nout, *idxout;
910d4fe737eSStefano Zampini   const PetscInt *idxin;
911d4fe737eSStefano Zampini 
912d4fe737eSStefano Zampini   PetscFunctionBegin;
913d4fe737eSStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
914d4fe737eSStefano Zampini   PetscValidHeaderSpecific(is, IS_CLASSID, 3);
9154f572ea9SToby Isaac   PetscAssertPointer(newis, 4);
916d4fe737eSStefano Zampini 
9179566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(is, &n));
9189566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(is, &idxin));
919d4fe737eSStefano Zampini   if (type == IS_GTOLM_MASK) {
9209566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &idxout));
921d4fe737eSStefano Zampini   } else {
9229566063dSJacob Faibussowitsch     PetscCall(ISGlobalToLocalMappingApply(mapping, type, n, idxin, &nout, NULL));
9239566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nout, &idxout));
924d4fe737eSStefano Zampini   }
9259566063dSJacob Faibussowitsch   PetscCall(ISGlobalToLocalMappingApply(mapping, type, n, idxin, &nout, idxout));
9269566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(is, &idxin));
9279566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, nout, idxout, PETSC_OWN_POINTER, newis));
9283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
929d4fe737eSStefano Zampini }
930d4fe737eSStefano Zampini 
9319d90f715SBarry Smith /*@
9329d90f715SBarry Smith   ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers
9339d90f715SBarry Smith   specified with a block global numbering.
9349d90f715SBarry Smith 
93520662ed9SBarry Smith   Not Collective
9369d90f715SBarry Smith 
9379d90f715SBarry Smith   Input Parameters:
9389d90f715SBarry Smith + mapping - mapping between local and global numbering
939cab54364SBarry Smith . type    - `IS_GTOLM_MASK` - maps global indices with no local value to -1 in the output list (i.e., mask them)
940cab54364SBarry Smith            `IS_GTOLM_DROP` - drops the indices with no local value from the output list
9419d90f715SBarry Smith . n       - number of global indices to map
9429d90f715SBarry Smith - idx     - global indices to map
9439d90f715SBarry Smith 
9449d90f715SBarry Smith   Output Parameters:
945cab54364SBarry Smith + nout   - number of indices in output array (if type == `IS_GTOLM_MASK` then nout = n)
9469d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough
947cab54364SBarry Smith              to hold all the indices. You can call `ISGlobalToLocalMappingApplyBlock()` with
9489d90f715SBarry Smith              idxout == NULL to determine the required length (returned in nout)
949cab54364SBarry Smith              and then allocate the required space and call `ISGlobalToLocalMappingApplyBlock()`
9509d90f715SBarry Smith              a second time to set the values.
9519d90f715SBarry Smith 
952cab54364SBarry Smith   Level: advanced
953cab54364SBarry Smith 
9549d90f715SBarry Smith   Notes:
95520662ed9SBarry Smith   Either `nout` or `idxout` may be `NULL`. `idx` and `idxout` may be identical.
9569d90f715SBarry Smith 
95720662ed9SBarry Smith   For "small" problems when using `ISGlobalToLocalMappingApply()` and `ISGlobalToLocalMappingApplyBlock()`, the `ISLocalToGlobalMappingType` of
95820662ed9SBarry Smith   `ISLOCALTOGLOBALMAPPINGBASIC` will be used;
959cab54364SBarry Smith   this uses more memory but is faster; this approach is not scalable for extremely large mappings. For large problems `ISLOCALTOGLOBALMAPPINGHASH` is used, this is scalable.
960cab54364SBarry Smith   Use `ISLocalToGlobalMappingSetType()` or call `ISLocalToGlobalMappingSetFromOptions()` with the option -islocaltoglobalmapping_type <basic,hash> to control which is used.
9619d90f715SBarry Smith 
96238b5cf2dSJacob Faibussowitsch   Developer Notes:
96320662ed9SBarry Smith   The manual page states that `idx` and `idxout` may be identical but the calling
96420662ed9SBarry Smith   sequence declares `idx` as const so it cannot be the same as `idxout`.
9659d90f715SBarry Smith 
966cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApply()`, `ISGlobalToLocalMappingApply()`, `ISLocalToGlobalMappingCreate()`,
967db781477SPatrick Sanan           `ISLocalToGlobalMappingDestroy()`
9689d90f715SBarry Smith @*/
969d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingMode type, PetscInt n, const PetscInt idx[], PetscInt *nout, PetscInt idxout[])
970d71ae5a4SJacob Faibussowitsch {
9713a40ed3dSBarry Smith   PetscFunctionBegin;
9720700a824SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
97348a46eb9SPierre Jolivet   if (!mapping->data) PetscCall(ISGlobalToLocalMappingSetUp(mapping));
974dbbe0bcdSBarry Smith   PetscUseTypeMethod(mapping, globaltolocalmappingapplyblock, type, n, idx, nout, idxout);
9753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
976d4bb536fSBarry Smith }
97790f02eecSBarry Smith 
97889d82c54SBarry Smith /*@C
979*633354d9SStefano Zampini   ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information
98089d82c54SBarry Smith 
981*633354d9SStefano Zampini   Collective the first time it is called
98289d82c54SBarry Smith 
983f899ff85SJose E. Roman   Input Parameter:
98489d82c54SBarry Smith . mapping - the mapping from local to global indexing
98589d82c54SBarry Smith 
986d8d19677SJose E. Roman   Output Parameters:
987*633354d9SStefano Zampini + nproc    - number of processes that are connected to the calling process
988*633354d9SStefano Zampini . procs    - neighboring processes
989*633354d9SStefano Zampini . numprocs - number of block indices for each process
990*633354d9SStefano Zampini - indices  - block indices (in local numbering) shared with neighbors (sorted by global numbering)
99189d82c54SBarry Smith 
99289d82c54SBarry Smith   Level: advanced
99389d82c54SBarry Smith 
994cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
995*633354d9SStefano Zampini           `ISLocalToGlobalMappingRestoreBlockInfo()`
99689d82c54SBarry Smith @*/
997d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[])
998d71ae5a4SJacob Faibussowitsch {
999268a049cSStefano Zampini   PetscFunctionBegin;
1000268a049cSStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1001*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingSetUpBlockInfo_Private(mapping));
1002*633354d9SStefano Zampini   if (nproc) *nproc = mapping->info_nproc;
1003*633354d9SStefano Zampini   if (procs) *procs = mapping->info_procs;
1004*633354d9SStefano Zampini   if (numprocs) *numprocs = mapping->info_numprocs;
1005*633354d9SStefano Zampini   if (indices) *indices = mapping->info_indices;
10063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1007268a049cSStefano Zampini }
1008268a049cSStefano Zampini 
1009*633354d9SStefano Zampini /*@C
1010*633354d9SStefano Zampini   ISLocalToGlobalMappingGetBlockNodeInfo - Gets the neighbor information for each local block index
1011*633354d9SStefano Zampini 
1012*633354d9SStefano Zampini   Collective the first time it is called
1013*633354d9SStefano Zampini 
1014*633354d9SStefano Zampini   Input Parameter:
1015*633354d9SStefano Zampini . mapping - the mapping from local to global indexing
1016*633354d9SStefano Zampini 
1017*633354d9SStefano Zampini   Output Parameter:
1018*633354d9SStefano Zampini + n       - number of local block nodes
1019*633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local block node (including self)
1020*633354d9SStefano Zampini - procs   - the processes' rank for each local block node (sorted, self is first)
1021*633354d9SStefano Zampini 
1022*633354d9SStefano Zampini   Level: advanced
1023*633354d9SStefano Zampini 
1024*633354d9SStefano Zampini   Notes:
1025*633354d9SStefano Zampini   The user needs to call `ISLocalToGlobalMappingRestoreBlockNodeInfo()` when the data is no longer needed.
1026*633354d9SStefano Zampini   The information returned by this function complements that of `ISLocalToGlobalMappingGetBlockInfo()`.
1027*633354d9SStefano Zampini   The latter only provides local information, and the neighboring information
1028*633354d9SStefano Zampini   cannot be inferred in the general case, unless the mapping is locally one-to-one on each process.
1029*633354d9SStefano Zampini 
1030*633354d9SStefano Zampini .seealso: `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1031*633354d9SStefano Zampini           `ISLocalToGlobalMappingGetBlockInfo()`, `ISLocalToGlobalMappingRestoreBlockNodeInfo()`, `ISLocalToGlobalMappingGetNodeInfo()`
1032*633354d9SStefano Zampini @*/
1033*633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingGetBlockNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[])
1034d71ae5a4SJacob Faibussowitsch {
1035*633354d9SStefano Zampini   PetscFunctionBegin;
1036*633354d9SStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1037*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingSetUpBlockInfo_Private(mapping));
1038*633354d9SStefano Zampini   if (n) *n = mapping->n;
1039*633354d9SStefano Zampini   if (n_procs) *n_procs = mapping->info_nodec;
1040*633354d9SStefano Zampini   if (procs) *procs = mapping->info_nodei;
1041*633354d9SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
1042*633354d9SStefano Zampini }
1043*633354d9SStefano Zampini 
1044*633354d9SStefano Zampini /*@C
1045*633354d9SStefano Zampini   ISLocalToGlobalMappingRestoreBlockNodeInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetBlockNodeInfo()`
1046*633354d9SStefano Zampini 
1047*633354d9SStefano Zampini   Not Collective
1048*633354d9SStefano Zampini 
1049*633354d9SStefano Zampini   Input Parameters:
1050*633354d9SStefano Zampini + mapping - the mapping from local to global indexing
1051*633354d9SStefano Zampini . n       - number of local block nodes
1052*633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local block nodes (including self)
1053*633354d9SStefano Zampini - procs   - the processes' rank for each local block node (sorted, self is first)
1054*633354d9SStefano Zampini 
1055*633354d9SStefano Zampini   Level: advanced
1056*633354d9SStefano Zampini 
1057*633354d9SStefano Zampini .seealso: `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1058*633354d9SStefano Zampini           `ISLocalToGlobalMappingGetBlockNodeInfo()`
1059*633354d9SStefano Zampini @*/
1060*633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingRestoreBlockNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[])
1061*633354d9SStefano Zampini {
1062*633354d9SStefano Zampini   PetscFunctionBegin;
1063*633354d9SStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1064*633354d9SStefano Zampini   if (n) *n = 0;
1065*633354d9SStefano Zampini   if (n_procs) *n_procs = NULL;
1066*633354d9SStefano Zampini   if (procs) *procs = NULL;
1067*633354d9SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
1068*633354d9SStefano Zampini }
1069*633354d9SStefano Zampini 
1070*633354d9SStefano Zampini static PetscErrorCode ISLocalToGlobalMappingSetUpBlockInfo_Private(ISLocalToGlobalMapping mapping)
1071*633354d9SStefano Zampini {
1072*633354d9SStefano Zampini   PetscSF            sf;
1073ce94432eSBarry Smith   MPI_Comm           comm;
1074*633354d9SStefano Zampini   const PetscSFNode *sfnode;
1075*633354d9SStefano Zampini   PetscSFNode       *newsfnode;
1076*633354d9SStefano Zampini   PetscLayout        layout;
1077*633354d9SStefano Zampini   PetscHMapI         neighs;
1078*633354d9SStefano Zampini   PetscHashIter      iter;
1079*633354d9SStefano Zampini   PetscBool          missing;
1080*633354d9SStefano Zampini   const PetscInt    *gidxs, *rootdegree;
1081*633354d9SStefano Zampini   PetscInt          *mask, *mrootdata, *leafdata, *newleafdata, *leafrd, *tmpg;
1082*633354d9SStefano Zampini   PetscInt           nroots, nleaves, newnleaves, bs, i, j, m, mnroots, p;
1083*633354d9SStefano Zampini   PetscMPIInt        rank, size;
108489d82c54SBarry Smith 
108589d82c54SBarry Smith   PetscFunctionBegin;
1086*633354d9SStefano Zampini   if (mapping->info_numprocs) PetscFunctionReturn(PETSC_SUCCESS);
10879566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)mapping, &comm));
10889566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
10899566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
1090*633354d9SStefano Zampini 
1091*633354d9SStefano Zampini   /* Get mapping indices */
1092*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingGetBlockSize(mapping, &bs));
1093*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingGetBlockIndices(mapping, &gidxs));
1094*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingGetSize(mapping, &nleaves));
1095*633354d9SStefano Zampini   nleaves /= bs;
1096*633354d9SStefano Zampini 
1097*633354d9SStefano Zampini   /* Create layout for global indices */
1098*633354d9SStefano Zampini   for (i = 0, m = 0; i < nleaves; i++) m = PetscMax(m, gidxs[i]);
1099*633354d9SStefano Zampini   PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &m, 1, MPIU_INT, MPI_MAX, comm));
1100*633354d9SStefano Zampini   PetscCall(PetscLayoutCreate(comm, &layout));
1101*633354d9SStefano Zampini   PetscCall(PetscLayoutSetSize(layout, m + 1));
1102*633354d9SStefano Zampini   PetscCall(PetscLayoutSetUp(layout));
1103*633354d9SStefano Zampini 
1104*633354d9SStefano Zampini   /* Create SF to share global indices */
1105*633354d9SStefano Zampini   PetscCall(PetscSFCreate(comm, &sf));
1106*633354d9SStefano Zampini   PetscCall(PetscSFSetGraphLayout(sf, layout, nleaves, NULL, PETSC_OWN_POINTER, gidxs));
1107*633354d9SStefano Zampini   PetscCall(PetscSFSetUp(sf));
1108*633354d9SStefano Zampini   PetscCall(PetscLayoutDestroy(&layout));
1109*633354d9SStefano Zampini 
1110*633354d9SStefano Zampini   /* communicate root degree to leaves */
1111*633354d9SStefano Zampini   PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, &sfnode));
1112*633354d9SStefano Zampini   PetscCall(PetscSFComputeDegreeBegin(sf, &rootdegree));
1113*633354d9SStefano Zampini   PetscCall(PetscSFComputeDegreeEnd(sf, &rootdegree));
1114*633354d9SStefano Zampini   for (i = 0, mnroots = 0; i < nroots; i++) mnroots += rootdegree[i];
1115*633354d9SStefano Zampini   PetscCall(PetscMalloc3(2 * PetscMax(mnroots, nroots), &mrootdata, 2 * nleaves, &leafdata, nleaves, &leafrd));
1116*633354d9SStefano Zampini   for (i = 0, m = 0; i < nroots; i++) {
1117*633354d9SStefano Zampini     mrootdata[2 * i + 0] = rootdegree[i];
1118*633354d9SStefano Zampini     mrootdata[2 * i + 1] = m;
1119*633354d9SStefano Zampini     m += rootdegree[i];
1120*633354d9SStefano Zampini   }
1121*633354d9SStefano Zampini   PetscCall(PetscSFBcastBegin(sf, MPIU_2INT, mrootdata, leafdata, MPI_REPLACE));
1122*633354d9SStefano Zampini   PetscCall(PetscSFBcastEnd(sf, MPIU_2INT, mrootdata, leafdata, MPI_REPLACE));
1123*633354d9SStefano Zampini 
1124*633354d9SStefano Zampini   /* allocate enough space to store ranks */
1125*633354d9SStefano Zampini   for (i = 0, newnleaves = 0; i < nleaves; i++) {
1126*633354d9SStefano Zampini     newnleaves += leafdata[2 * i];
1127*633354d9SStefano Zampini     leafrd[i] = leafdata[2 * i];
112824cf384cSBarry Smith   }
112924cf384cSBarry Smith 
1130*633354d9SStefano Zampini   /* create new SF nodes to collect multi-root data at leaves */
1131*633354d9SStefano Zampini   PetscCall(PetscMalloc1(newnleaves, &newsfnode));
1132*633354d9SStefano Zampini   for (i = 0, m = 0; i < nleaves; i++) {
1133*633354d9SStefano Zampini     for (j = 0; j < leafrd[i]; j++) {
1134*633354d9SStefano Zampini       newsfnode[m].rank  = sfnode[i].rank;
1135*633354d9SStefano Zampini       newsfnode[m].index = leafdata[2 * i + 1] + j;
1136*633354d9SStefano Zampini       m++;
1137bc8ff85bSBarry Smith     }
1138bc8ff85bSBarry Smith   }
1139bc8ff85bSBarry Smith 
1140*633354d9SStefano Zampini   /* gather ranks at multi roots */
1141*633354d9SStefano Zampini   for (i = 0; i < mnroots; i++) mrootdata[i] = -1;
1142*633354d9SStefano Zampini   for (i = 0; i < nleaves; i++) leafdata[i] = (PetscInt)rank;
114330dcb7c9SBarry Smith 
1144*633354d9SStefano Zampini   PetscCall(PetscSFGatherBegin(sf, MPIU_INT, leafdata, mrootdata));
1145*633354d9SStefano Zampini   PetscCall(PetscSFGatherEnd(sf, MPIU_INT, leafdata, mrootdata));
11463677ff5aSBarry Smith 
1147*633354d9SStefano Zampini   /* set new multi-leaves graph into the SF */
1148*633354d9SStefano Zampini   PetscCall(PetscSFSetGraph(sf, mnroots, newnleaves, NULL, PETSC_OWN_POINTER, newsfnode, PETSC_OWN_POINTER));
1149*633354d9SStefano Zampini   PetscCall(PetscSFSetUp(sf));
1150f6e5521dSKarl Rupp 
1151*633354d9SStefano Zampini   /* broadcast multi-root data to multi-leaves */
1152*633354d9SStefano Zampini   PetscCall(PetscMalloc1(newnleaves, &newleafdata));
1153*633354d9SStefano Zampini   PetscCall(PetscSFBcastBegin(sf, MPIU_INT, mrootdata, newleafdata, MPI_REPLACE));
1154*633354d9SStefano Zampini   PetscCall(PetscSFBcastEnd(sf, MPIU_INT, mrootdata, newleafdata, MPI_REPLACE));
1155f6e5521dSKarl Rupp 
1156*633354d9SStefano Zampini   /* sort sharing ranks */
1157*633354d9SStefano Zampini   for (i = 0, m = 0; i < nleaves; i++) {
1158*633354d9SStefano Zampini     PetscCall(PetscSortInt(leafrd[i], newleafdata + m));
1159*633354d9SStefano Zampini     m += leafrd[i];
116030dcb7c9SBarry Smith   }
116130dcb7c9SBarry Smith 
1162*633354d9SStefano Zampini   /* Number of neighbors and their ranks */
1163*633354d9SStefano Zampini   PetscCall(PetscHMapICreate(&neighs));
1164*633354d9SStefano Zampini   for (i = 0; i < newnleaves; i++) PetscCall(PetscHMapIPut(neighs, newleafdata[i], &iter, &missing));
1165*633354d9SStefano Zampini   PetscCall(PetscHMapIGetSize(neighs, &mapping->info_nproc));
1166*633354d9SStefano Zampini   PetscCall(PetscMalloc1(mapping->info_nproc + 1, &mapping->info_procs));
1167*633354d9SStefano Zampini   PetscCall(PetscHMapIGetKeys(neighs, (i = 0, &i), mapping->info_procs));
1168*633354d9SStefano Zampini   for (i = 0; i < mapping->info_nproc; i++) { /* put info for self first */
1169*633354d9SStefano Zampini     if (mapping->info_procs[i] == rank) {
1170*633354d9SStefano Zampini       PetscInt newr = mapping->info_procs[0];
1171d44834fbSBarry Smith 
1172*633354d9SStefano Zampini       mapping->info_procs[0] = rank;
1173*633354d9SStefano Zampini       mapping->info_procs[i] = newr;
117424cf384cSBarry Smith       break;
117524cf384cSBarry Smith     }
117624cf384cSBarry Smith   }
1177*633354d9SStefano Zampini   if (mapping->info_nproc) PetscCall(PetscSortInt(mapping->info_nproc - 1, mapping->info_procs + 1));
1178*633354d9SStefano Zampini   PetscCall(PetscHMapIDestroy(&neighs));
1179268a049cSStefano Zampini 
1180*633354d9SStefano Zampini   /* collect info data */
1181*633354d9SStefano Zampini   PetscCall(PetscMalloc1(mapping->info_nproc + 1, &mapping->info_numprocs));
1182*633354d9SStefano Zampini   PetscCall(PetscMalloc1(mapping->info_nproc + 1, &mapping->info_indices));
1183*633354d9SStefano Zampini   for (i = 0; i < mapping->info_nproc + 1; i++) mapping->info_indices[i] = NULL;
1184*633354d9SStefano Zampini 
1185*633354d9SStefano Zampini   PetscCall(PetscMalloc1(nleaves, &mask));
1186*633354d9SStefano Zampini   PetscCall(PetscMalloc1(nleaves, &tmpg));
1187*633354d9SStefano Zampini   for (p = 0; p < mapping->info_nproc; p++) {
1188*633354d9SStefano Zampini     PetscInt *tmp, trank = mapping->info_procs[p];
1189*633354d9SStefano Zampini 
1190*633354d9SStefano Zampini     PetscCall(PetscMemzero(mask, nleaves * sizeof(*mask)));
1191*633354d9SStefano Zampini     for (i = 0, m = 0; i < nleaves; i++) {
1192*633354d9SStefano Zampini       for (j = 0; j < leafrd[i]; j++) {
1193*633354d9SStefano Zampini         if (newleafdata[m] == trank) mask[i]++;
1194*633354d9SStefano Zampini         if (!p && newleafdata[m] != rank) mask[i]++;
1195*633354d9SStefano Zampini         m++;
1196*633354d9SStefano Zampini       }
1197*633354d9SStefano Zampini     }
1198*633354d9SStefano Zampini     for (i = 0, m = 0; i < nleaves; i++)
1199*633354d9SStefano Zampini       if (mask[i] > (!p ? 1 : 0)) m++;
1200*633354d9SStefano Zampini 
1201*633354d9SStefano Zampini     PetscCall(PetscMalloc1(m, &tmp));
1202*633354d9SStefano Zampini     for (i = 0, m = 0; i < nleaves; i++)
1203*633354d9SStefano Zampini       if (mask[i] > (!p ? 1 : 0)) {
1204*633354d9SStefano Zampini         tmp[m]  = i;
1205*633354d9SStefano Zampini         tmpg[m] = gidxs[i];
1206*633354d9SStefano Zampini         m++;
1207*633354d9SStefano Zampini       }
1208*633354d9SStefano Zampini     PetscCall(PetscSortIntWithArray(m, tmpg, tmp));
1209*633354d9SStefano Zampini     mapping->info_indices[p]  = tmp;
1210*633354d9SStefano Zampini     mapping->info_numprocs[p] = m;
1211*633354d9SStefano Zampini   }
1212*633354d9SStefano Zampini 
1213*633354d9SStefano Zampini   /* Node info */
1214*633354d9SStefano Zampini   PetscCall(PetscMalloc2(nleaves, &mapping->info_nodec, nleaves + 1, &mapping->info_nodei));
1215*633354d9SStefano Zampini   PetscCall(PetscArraycpy(mapping->info_nodec, leafrd, nleaves));
1216*633354d9SStefano Zampini   PetscCall(PetscMalloc1(newnleaves, &mapping->info_nodei[0]));
1217*633354d9SStefano Zampini   for (i = 0; i < nleaves - 1; i++) mapping->info_nodei[i + 1] = mapping->info_nodei[i] + mapping->info_nodec[i];
1218*633354d9SStefano Zampini   PetscCall(PetscArraycpy(mapping->info_nodei[0], newleafdata, newnleaves));
1219*633354d9SStefano Zampini 
1220*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingRestoreBlockIndices(mapping, &gidxs));
1221*633354d9SStefano Zampini   PetscCall(PetscFree(tmpg));
1222*633354d9SStefano Zampini   PetscCall(PetscFree(mask));
1223*633354d9SStefano Zampini   PetscCall(PetscSFDestroy(&sf));
1224*633354d9SStefano Zampini   PetscCall(PetscFree3(mrootdata, leafdata, leafrd));
1225*633354d9SStefano Zampini   PetscCall(PetscFree(newleafdata));
12263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
122789d82c54SBarry Smith }
122889d82c54SBarry Smith 
12296a818285SBarry Smith /*@C
1230cab54364SBarry Smith   ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetBlockInfo()`
12316a818285SBarry Smith 
1232*633354d9SStefano Zampini   Not Collective
12336a818285SBarry Smith 
1234*633354d9SStefano Zampini   Input Parameters:
1235*633354d9SStefano Zampini + mapping  - the mapping from local to global indexing
1236*633354d9SStefano Zampini . nproc    - number of processes that are connected to the calling process
1237*633354d9SStefano Zampini . procs    - neighboring processes
1238*633354d9SStefano Zampini . numprocs - number of block indices for each process
1239*633354d9SStefano Zampini - indices  - block indices (in local numbering) shared with neighbors (sorted by global numbering)
12406a818285SBarry Smith 
12416a818285SBarry Smith   Level: advanced
12426a818285SBarry Smith 
1243cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1244db781477SPatrick Sanan           `ISLocalToGlobalMappingGetInfo()`
12456a818285SBarry Smith @*/
1246d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[])
1247d71ae5a4SJacob Faibussowitsch {
12486a818285SBarry Smith   PetscFunctionBegin;
1249cbc1caf0SMatthew G. Knepley   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1250*633354d9SStefano Zampini   if (nproc) *nproc = 0;
1251*633354d9SStefano Zampini   if (procs) *procs = NULL;
1252*633354d9SStefano Zampini   if (numprocs) *numprocs = NULL;
1253*633354d9SStefano Zampini   if (indices) *indices = NULL;
12543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12556a818285SBarry Smith }
12566a818285SBarry Smith 
12576a818285SBarry Smith /*@C
1258*633354d9SStefano Zampini   ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each process
12596a818285SBarry Smith 
1260*633354d9SStefano Zampini   Collective the first time it is called
12616a818285SBarry Smith 
1262f899ff85SJose E. Roman   Input Parameter:
12636a818285SBarry Smith . mapping - the mapping from local to global indexing
12646a818285SBarry Smith 
1265d8d19677SJose E. Roman   Output Parameters:
1266*633354d9SStefano Zampini + nproc    - number of processes that are connected to the calling process
1267*633354d9SStefano Zampini . procs    - neighboring processes
1268*633354d9SStefano Zampini . numprocs - number of indices for each process
1269*633354d9SStefano Zampini - indices  - indices (in local numbering) shared with neighbors (sorted by global numbering)
12706a818285SBarry Smith 
12716a818285SBarry Smith   Level: advanced
12726a818285SBarry Smith 
1273cab54364SBarry Smith   Note:
1274cab54364SBarry Smith   The user needs to call `ISLocalToGlobalMappingRestoreInfo()` when the data is no longer needed.
12751bd0b88eSStefano Zampini 
127638b5cf2dSJacob Faibussowitsch   Fortran Notes:
1277e33f79d8SJacob Faibussowitsch   There is no `ISLocalToGlobalMappingRestoreInfo()` in Fortran. You must make sure that
1278e33f79d8SJacob Faibussowitsch   `procs`[], `numprocs`[] and `indices`[][] are large enough arrays, either by allocating them
1279e33f79d8SJacob Faibussowitsch   dynamically or defining static ones large enough.
1280e33f79d8SJacob Faibussowitsch 
1281cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1282*633354d9SStefano Zampini           `ISLocalToGlobalMappingRestoreInfo()`, `ISLocalToGlobalMappingGetNodeInfo()`
12836a818285SBarry Smith @*/
1284d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[])
1285d71ae5a4SJacob Faibussowitsch {
1286*633354d9SStefano Zampini   PetscInt **bindices = NULL, *bnumprocs = NULL, bs, i, j, k, n, *bprocs;
12876a818285SBarry Smith 
12886a818285SBarry Smith   PetscFunctionBegin;
12896a818285SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
12908a1f772fSStefano Zampini   bs = mapping->bs;
1291*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingGetBlockInfo(mapping, &n, &bprocs, &bnumprocs, &bindices));
1292268a049cSStefano Zampini   if (bs > 1) { /* we need to expand the cached info */
1293*633354d9SStefano Zampini     if (indices) PetscCall(PetscCalloc1(n, indices));
1294*633354d9SStefano Zampini     if (numprocs) PetscCall(PetscCalloc1(n, numprocs));
1295*633354d9SStefano Zampini     if (indices || numprocs) {
1296*633354d9SStefano Zampini       for (i = 0; i < n; i++) {
1297*633354d9SStefano Zampini         if (indices) {
12989566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(bs * bnumprocs[i], &(*indices)[i]));
1299268a049cSStefano Zampini           for (j = 0; j < bnumprocs[i]; j++) {
1300ad540459SPierre Jolivet             for (k = 0; k < bs; k++) (*indices)[i][j * bs + k] = bs * bindices[i][j] + k;
13016a818285SBarry Smith           }
13026a818285SBarry Smith         }
1303*633354d9SStefano Zampini         if (numprocs) (*numprocs)[i] = bnumprocs[i] * bs;
1304*633354d9SStefano Zampini       }
1305*633354d9SStefano Zampini     }
1306268a049cSStefano Zampini   } else {
1307*633354d9SStefano Zampini     if (numprocs) *numprocs = bnumprocs;
1308*633354d9SStefano Zampini     if (indices) *indices = bindices;
13096a818285SBarry Smith   }
1310*633354d9SStefano Zampini   if (nproc) *nproc = n;
1311*633354d9SStefano Zampini   if (procs) *procs = bprocs;
13123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13136a818285SBarry Smith }
13146a818285SBarry Smith 
131507b52d57SBarry Smith /*@C
1316cab54364SBarry Smith   ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetInfo()`
131789d82c54SBarry Smith 
1318*633354d9SStefano Zampini   Not Collective
131907b52d57SBarry Smith 
1320*633354d9SStefano Zampini   Input Parameters:
1321*633354d9SStefano Zampini + mapping  - the mapping from local to global indexing
1322*633354d9SStefano Zampini . nproc    - number of processes that are connected to the calling process
1323*633354d9SStefano Zampini . procs    - neighboring processes
1324*633354d9SStefano Zampini . numprocs - number of indices for each process
1325*633354d9SStefano Zampini - indices  - indices (in local numbering) shared with neighbors (sorted by global numbering)
132607b52d57SBarry Smith 
132707b52d57SBarry Smith   Level: advanced
132807b52d57SBarry Smith 
1329cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1330db781477SPatrick Sanan           `ISLocalToGlobalMappingGetInfo()`
133107b52d57SBarry Smith @*/
1332d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[])
1333d71ae5a4SJacob Faibussowitsch {
133407b52d57SBarry Smith   PetscFunctionBegin;
1335*633354d9SStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1336*633354d9SStefano Zampini   if (mapping->bs > 1) {
1337*633354d9SStefano Zampini     if (numprocs) PetscCall(PetscFree(*numprocs));
1338*633354d9SStefano Zampini     if (indices) {
1339*633354d9SStefano Zampini       if (*indices)
1340*633354d9SStefano Zampini         for (PetscInt i = 0; i < *nproc; i++) PetscCall(PetscFree((*indices)[i]));
1341*633354d9SStefano Zampini       PetscCall(PetscFree(*indices));
1342*633354d9SStefano Zampini     }
1343*633354d9SStefano Zampini   }
13443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
134507b52d57SBarry Smith }
134686994e45SJed Brown 
134786994e45SJed Brown /*@C
1348*633354d9SStefano Zampini   ISLocalToGlobalMappingGetNodeInfo - Gets the neighbor information of local nodes
13491bd0b88eSStefano Zampini 
1350*633354d9SStefano Zampini   Collective the first time it is called
13511bd0b88eSStefano Zampini 
1352f899ff85SJose E. Roman   Input Parameter:
13531bd0b88eSStefano Zampini . mapping - the mapping from local to global indexing
13541bd0b88eSStefano Zampini 
1355d8d19677SJose E. Roman   Output Parameters:
1356*633354d9SStefano Zampini + n       - number of local nodes
1357*633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local node (including self)
1358*633354d9SStefano Zampini - procs   - the processes' rank for each local node (sorted, self is first)
13591bd0b88eSStefano Zampini 
13601bd0b88eSStefano Zampini   Level: advanced
13611bd0b88eSStefano Zampini 
1362cab54364SBarry Smith   Note:
1363*633354d9SStefano Zampini   The user needs to call `ISLocalToGlobalMappingRestoreNodeInfo()` when the data is no longer needed.
13641bd0b88eSStefano Zampini 
1365cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1366*633354d9SStefano Zampini           `ISLocalToGlobalMappingGetInfo()`, `ISLocalToGlobalMappingRestoreNodeInfo()`, `ISLocalToGlobalMappingGetBlockNodeInfo()`
13671bd0b88eSStefano Zampini @*/
1368*633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingGetNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[])
1369d71ae5a4SJacob Faibussowitsch {
1370*633354d9SStefano Zampini   PetscInt **bprocs = NULL, *bn_procs = NULL, bs, i, j, k, bn;
13711bd0b88eSStefano Zampini 
13721bd0b88eSStefano Zampini   PetscFunctionBegin;
13731bd0b88eSStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1374*633354d9SStefano Zampini   bs = mapping->bs;
1375*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingGetBlockNodeInfo(mapping, &bn, &bn_procs, &bprocs));
1376*633354d9SStefano Zampini   if (bs > 1) { /* we need to expand the cached info */
1377*633354d9SStefano Zampini     PetscInt *tn_procs;
1378*633354d9SStefano Zampini     PetscInt  c;
13791bd0b88eSStefano Zampini 
1380*633354d9SStefano Zampini     PetscCall(PetscMalloc1(bn * bs, &tn_procs));
1381*633354d9SStefano Zampini     for (i = 0, c = 0; i < bn; i++) {
1382*633354d9SStefano Zampini       for (k = 0; k < bs; k++) tn_procs[i * bs + k] = bn_procs[i];
1383*633354d9SStefano Zampini       c += bs * bn_procs[i];
1384*633354d9SStefano Zampini     }
1385*633354d9SStefano Zampini     if (n) *n = bn * bs;
1386*633354d9SStefano Zampini     if (procs) {
1387*633354d9SStefano Zampini       PetscInt **tprocs;
1388*633354d9SStefano Zampini       PetscInt   tn = bn * bs;
13891bd0b88eSStefano Zampini 
1390*633354d9SStefano Zampini       PetscCall(PetscMalloc1(tn, &tprocs));
1391*633354d9SStefano Zampini       if (tn) PetscCall(PetscMalloc1(c, &tprocs[0]));
1392*633354d9SStefano Zampini       for (i = 0; i < tn - 1; i++) tprocs[i + 1] = tprocs[i] + tn_procs[i];
1393*633354d9SStefano Zampini       for (i = 0; i < bn; i++) {
1394*633354d9SStefano Zampini         for (k = 0; k < bs; k++) {
1395*633354d9SStefano Zampini           for (j = 0; j < bn_procs[i]; j++) tprocs[i * bs + k][j] = bprocs[i][j];
13961bd0b88eSStefano Zampini         }
13971bd0b88eSStefano Zampini       }
1398*633354d9SStefano Zampini       *procs = tprocs;
13991bd0b88eSStefano Zampini     }
1400*633354d9SStefano Zampini     if (n_procs) *n_procs = tn_procs;
1401*633354d9SStefano Zampini     else PetscCall(PetscFree(tn_procs));
1402*633354d9SStefano Zampini   } else {
1403*633354d9SStefano Zampini     if (n) *n = bn;
1404*633354d9SStefano Zampini     if (n_procs) *n_procs = bn_procs;
1405*633354d9SStefano Zampini     if (procs) *procs = bprocs;
1406*633354d9SStefano Zampini   }
14073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14081bd0b88eSStefano Zampini }
14091bd0b88eSStefano Zampini 
14101bd0b88eSStefano Zampini /*@C
1411cab54364SBarry Smith   ISLocalToGlobalMappingRestoreNodeInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetNodeInfo()`
14121bd0b88eSStefano Zampini 
1413*633354d9SStefano Zampini   Not Collective
14141bd0b88eSStefano Zampini 
1415*633354d9SStefano Zampini   Input Parameters:
1416*633354d9SStefano Zampini + mapping - the mapping from local to global indexing
1417*633354d9SStefano Zampini . n       - number of local nodes
1418*633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local node (including self)
1419*633354d9SStefano Zampini - procs   - the processes' rank for each local node (sorted, self is first)
14201bd0b88eSStefano Zampini 
14211bd0b88eSStefano Zampini   Level: advanced
14221bd0b88eSStefano Zampini 
1423cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1424db781477SPatrick Sanan           `ISLocalToGlobalMappingGetInfo()`
14251bd0b88eSStefano Zampini @*/
1426*633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingRestoreNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[])
1427d71ae5a4SJacob Faibussowitsch {
14281bd0b88eSStefano Zampini   PetscFunctionBegin;
14291bd0b88eSStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1430*633354d9SStefano Zampini   if (mapping->bs > 1) {
1431*633354d9SStefano Zampini     if (n_procs) PetscCall(PetscFree(*n_procs));
1432*633354d9SStefano Zampini     if (procs) {
1433*633354d9SStefano Zampini       if (*procs) PetscCall(PetscFree((*procs)[0]));
1434*633354d9SStefano Zampini       PetscCall(PetscFree(*procs));
1435*633354d9SStefano Zampini     }
1436*633354d9SStefano Zampini   }
1437*633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingRestoreBlockNodeInfo(mapping, n, n_procs, procs));
14383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14391bd0b88eSStefano Zampini }
14401bd0b88eSStefano Zampini 
14416ce40d10SBarry Smith /*MC
14426ce40d10SBarry Smith     ISLocalToGlobalMappingGetIndicesF90 - Get global indices for every local point that is mapped
14436ce40d10SBarry Smith 
14446ce40d10SBarry Smith     Synopsis:
14456ce40d10SBarry Smith     ISLocalToGlobalMappingGetIndicesF90(ISLocalToGlobalMapping ltog, PetscInt, pointer :: array(:)}, integer ierr)
14466ce40d10SBarry Smith 
14476ce40d10SBarry Smith     Not Collective
14486ce40d10SBarry Smith 
14496ce40d10SBarry Smith     Input Parameter:
14506ce40d10SBarry Smith .   A - the matrix
14516ce40d10SBarry Smith 
14522fe279fdSBarry Smith     Output Parameter:
14536ce40d10SBarry Smith .   array - array of indices, the length of this array may be obtained with `ISLocalToGlobalMappingGetSize()`
14546ce40d10SBarry Smith 
14556ce40d10SBarry Smith     Level: advanced
14566ce40d10SBarry Smith 
14576ce40d10SBarry Smith     Note:
14586ce40d10SBarry Smith     Use  `ISLocalToGlobalMappingGetIndicesF90()` when you no longer need access to the data
14596ce40d10SBarry Smith 
146020662ed9SBarry Smith .seealso: [](sec_fortranarrays), [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingGetIndices()`, `ISLocalToGlobalMappingRestoreIndices()`,
146120662ed9SBarry Smith           `ISLocalToGlobalMappingRestoreIndicesF90()`
14626ce40d10SBarry Smith M*/
14636ce40d10SBarry Smith 
14646ce40d10SBarry Smith /*MC
14656ce40d10SBarry Smith     ISLocalToGlobalMappingRestoreIndicesF90 - restores the global indices for every local point that is mapped obtained with `ISLocalToGlobalMappingGetIndicesF90()`
14666ce40d10SBarry Smith 
14676ce40d10SBarry Smith     Synopsis:
14686ce40d10SBarry Smith     ISLocalToGlobalMappingRestoreIndicesF90(ISLocalToGlobalMapping ltog, PetscInt, pointer :: array(:)}, integer ierr)
14696ce40d10SBarry Smith 
14706ce40d10SBarry Smith     Not Collective
14716ce40d10SBarry Smith 
14726ce40d10SBarry Smith     Input Parameters:
14736ce40d10SBarry Smith +   A - the matrix
14746ce40d10SBarry Smith -   array - array of indices, the length of this array may be obtained with `ISLocalToGlobalMappingGetSize()`
14756ce40d10SBarry Smith 
14766ce40d10SBarry Smith     Level: advanced
14776ce40d10SBarry Smith 
147820662ed9SBarry Smith .seealso: [](sec_fortranarrays), [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingGetIndices()`, `ISLocalToGlobalMappingRestoreIndices()`,
147920662ed9SBarry Smith           `ISLocalToGlobalMappingGetIndicesF90()`
14806ce40d10SBarry Smith M*/
14816ce40d10SBarry Smith 
14821bd0b88eSStefano Zampini /*@C
1483107e9a97SBarry Smith   ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped
148486994e45SJed Brown 
148586994e45SJed Brown   Not Collective
148686994e45SJed Brown 
14874165533cSJose E. Roman   Input Parameter:
148886994e45SJed Brown . ltog - local to global mapping
148986994e45SJed Brown 
14904165533cSJose E. Roman   Output Parameter:
1491cab54364SBarry Smith . array - array of indices, the length of this array may be obtained with `ISLocalToGlobalMappingGetSize()`
149286994e45SJed Brown 
149386994e45SJed Brown   Level: advanced
149486994e45SJed Brown 
1495cab54364SBarry Smith   Note:
1496cab54364SBarry Smith   `ISLocalToGlobalMappingGetSize()` returns the length the this array
1497107e9a97SBarry Smith 
149820662ed9SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingRestoreIndices()`,
149920662ed9SBarry Smith           `ISLocalToGlobalMappingGetBlockIndices()`, `ISLocalToGlobalMappingRestoreBlockIndices()`
150086994e45SJed Brown @*/
1501d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog, const PetscInt **array)
1502d71ae5a4SJacob Faibussowitsch {
150386994e45SJed Brown   PetscFunctionBegin;
150486994e45SJed Brown   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
15054f572ea9SToby Isaac   PetscAssertPointer(array, 2);
150645b6f7e9SBarry Smith   if (ltog->bs == 1) {
150786994e45SJed Brown     *array = ltog->indices;
150845b6f7e9SBarry Smith   } else {
150945b6f7e9SBarry Smith     PetscInt       *jj, k, i, j, n = ltog->n, bs = ltog->bs;
151045b6f7e9SBarry Smith     const PetscInt *ii;
151145b6f7e9SBarry Smith 
15129566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(bs * n, &jj));
151345b6f7e9SBarry Smith     *array = jj;
151445b6f7e9SBarry Smith     k      = 0;
151545b6f7e9SBarry Smith     ii     = ltog->indices;
151645b6f7e9SBarry Smith     for (i = 0; i < n; i++)
15179371c9d4SSatish Balay       for (j = 0; j < bs; j++) jj[k++] = bs * ii[i] + j;
151845b6f7e9SBarry Smith   }
15193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
152086994e45SJed Brown }
152186994e45SJed Brown 
152286994e45SJed Brown /*@C
1523cab54364SBarry Smith   ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with `ISLocalToGlobalMappingGetIndices()`
152486994e45SJed Brown 
152586994e45SJed Brown   Not Collective
152686994e45SJed Brown 
15274165533cSJose E. Roman   Input Parameters:
152886994e45SJed Brown + ltog  - local to global mapping
152986994e45SJed Brown - array - array of indices
153086994e45SJed Brown 
153186994e45SJed Brown   Level: advanced
153286994e45SJed Brown 
1533cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingGetIndices()`
153486994e45SJed Brown @*/
1535d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog, const PetscInt **array)
1536d71ae5a4SJacob Faibussowitsch {
153786994e45SJed Brown   PetscFunctionBegin;
153886994e45SJed Brown   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
15394f572ea9SToby Isaac   PetscAssertPointer(array, 2);
1540c9cc58a2SBarry Smith   PetscCheck(ltog->bs != 1 || *array == ltog->indices, PETSC_COMM_SELF, PETSC_ERR_ARG_BADPTR, "Trying to return mismatched pointer");
154148a46eb9SPierre Jolivet   if (ltog->bs > 1) PetscCall(PetscFree(*(void **)array));
15423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
154345b6f7e9SBarry Smith }
154445b6f7e9SBarry Smith 
154545b6f7e9SBarry Smith /*@C
154645b6f7e9SBarry Smith   ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block
154745b6f7e9SBarry Smith 
154845b6f7e9SBarry Smith   Not Collective
154945b6f7e9SBarry Smith 
15504165533cSJose E. Roman   Input Parameter:
155145b6f7e9SBarry Smith . ltog - local to global mapping
155245b6f7e9SBarry Smith 
15534165533cSJose E. Roman   Output Parameter:
155445b6f7e9SBarry Smith . array - array of indices
155545b6f7e9SBarry Smith 
155645b6f7e9SBarry Smith   Level: advanced
155745b6f7e9SBarry Smith 
1558cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingRestoreBlockIndices()`
155945b6f7e9SBarry Smith @*/
1560d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog, const PetscInt **array)
1561d71ae5a4SJacob Faibussowitsch {
156245b6f7e9SBarry Smith   PetscFunctionBegin;
156345b6f7e9SBarry Smith   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
15644f572ea9SToby Isaac   PetscAssertPointer(array, 2);
156545b6f7e9SBarry Smith   *array = ltog->indices;
15663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
156745b6f7e9SBarry Smith }
156845b6f7e9SBarry Smith 
156945b6f7e9SBarry Smith /*@C
1570cab54364SBarry Smith   ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with `ISLocalToGlobalMappingGetBlockIndices()`
157145b6f7e9SBarry Smith 
157245b6f7e9SBarry Smith   Not Collective
157345b6f7e9SBarry Smith 
15744165533cSJose E. Roman   Input Parameters:
157545b6f7e9SBarry Smith + ltog  - local to global mapping
157645b6f7e9SBarry Smith - array - array of indices
157745b6f7e9SBarry Smith 
157845b6f7e9SBarry Smith   Level: advanced
157945b6f7e9SBarry Smith 
1580cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingGetIndices()`
158145b6f7e9SBarry Smith @*/
1582d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog, const PetscInt **array)
1583d71ae5a4SJacob Faibussowitsch {
158445b6f7e9SBarry Smith   PetscFunctionBegin;
158545b6f7e9SBarry Smith   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
15864f572ea9SToby Isaac   PetscAssertPointer(array, 2);
158708401ef6SPierre Jolivet   PetscCheck(*array == ltog->indices, PETSC_COMM_SELF, PETSC_ERR_ARG_BADPTR, "Trying to return mismatched pointer");
15880298fd71SBarry Smith   *array = NULL;
15893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
159086994e45SJed Brown }
1591f7efa3c7SJed Brown 
1592f7efa3c7SJed Brown /*@C
1593f7efa3c7SJed Brown   ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings
1594f7efa3c7SJed Brown 
1595f7efa3c7SJed Brown   Not Collective
1596f7efa3c7SJed Brown 
15974165533cSJose E. Roman   Input Parameters:
1598f7efa3c7SJed Brown + comm  - communicator for the new mapping, must contain the communicator of every mapping to concatenate
1599f7efa3c7SJed Brown . n     - number of mappings to concatenate
1600f7efa3c7SJed Brown - ltogs - local to global mappings
1601f7efa3c7SJed Brown 
16024165533cSJose E. Roman   Output Parameter:
1603f7efa3c7SJed Brown . ltogcat - new mapping
1604f7efa3c7SJed Brown 
1605f7efa3c7SJed Brown   Level: advanced
1606f7efa3c7SJed Brown 
1607cab54364SBarry Smith   Note:
1608cab54364SBarry Smith   This currently always returns a mapping with block size of 1
1609cab54364SBarry Smith 
161038b5cf2dSJacob Faibussowitsch   Developer Notes:
1611cab54364SBarry Smith   If all the input mapping have the same block size we could easily handle that as a special case
1612cab54364SBarry Smith 
1613cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingCreate()`
1614f7efa3c7SJed Brown @*/
1615d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm, PetscInt n, const ISLocalToGlobalMapping ltogs[], ISLocalToGlobalMapping *ltogcat)
1616d71ae5a4SJacob Faibussowitsch {
1617f7efa3c7SJed Brown   PetscInt i, cnt, m, *idx;
1618f7efa3c7SJed Brown 
1619f7efa3c7SJed Brown   PetscFunctionBegin;
162008401ef6SPierre Jolivet   PetscCheck(n >= 0, comm, PETSC_ERR_ARG_OUTOFRANGE, "Must have a non-negative number of mappings, given %" PetscInt_FMT, n);
16214f572ea9SToby Isaac   if (n > 0) PetscAssertPointer(ltogs, 3);
1622f7efa3c7SJed Brown   for (i = 0; i < n; i++) PetscValidHeaderSpecific(ltogs[i], IS_LTOGM_CLASSID, 3);
16234f572ea9SToby Isaac   PetscAssertPointer(ltogcat, 4);
1624f7efa3c7SJed Brown   for (cnt = 0, i = 0; i < n; i++) {
16259566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetSize(ltogs[i], &m));
1626f7efa3c7SJed Brown     cnt += m;
1627f7efa3c7SJed Brown   }
16289566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(cnt, &idx));
1629f7efa3c7SJed Brown   for (cnt = 0, i = 0; i < n; i++) {
1630f7efa3c7SJed Brown     const PetscInt *subidx;
16319566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetSize(ltogs[i], &m));
16329566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetIndices(ltogs[i], &subidx));
16339566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(&idx[cnt], subidx, m));
16349566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingRestoreIndices(ltogs[i], &subidx));
1635f7efa3c7SJed Brown     cnt += m;
1636f7efa3c7SJed Brown   }
16379566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingCreate(comm, 1, cnt, idx, PETSC_OWN_POINTER, ltogcat));
16383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1639f7efa3c7SJed Brown }
164004a59952SBarry Smith 
1641413f72f0SBarry Smith /*MC
1642cab54364SBarry Smith       ISLOCALTOGLOBALMAPPINGBASIC - basic implementation of the `ISLocalToGlobalMapping` object. When `ISGlobalToLocalMappingApply()` is
1643413f72f0SBarry Smith                                     used this is good for only small and moderate size problems.
1644413f72f0SBarry Smith 
164520662ed9SBarry Smith    Options Database Key:
1646a2b725a8SWilliam Gropp .   -islocaltoglobalmapping_type basic - select this method
1647413f72f0SBarry Smith 
1648413f72f0SBarry Smith    Level: beginner
1649413f72f0SBarry Smith 
1650cab54364SBarry Smith    Developer Note:
1651cab54364SBarry Smith    This stores all the mapping information on each MPI rank.
1652cab54364SBarry Smith 
1653cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetType()`, `ISLOCALTOGLOBALMAPPINGHASH`
1654413f72f0SBarry Smith M*/
1655d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreate_Basic(ISLocalToGlobalMapping ltog)
1656d71ae5a4SJacob Faibussowitsch {
1657413f72f0SBarry Smith   PetscFunctionBegin;
1658413f72f0SBarry Smith   ltog->ops->globaltolocalmappingapply      = ISGlobalToLocalMappingApply_Basic;
1659413f72f0SBarry Smith   ltog->ops->globaltolocalmappingsetup      = ISGlobalToLocalMappingSetUp_Basic;
1660413f72f0SBarry Smith   ltog->ops->globaltolocalmappingapplyblock = ISGlobalToLocalMappingApplyBlock_Basic;
1661413f72f0SBarry Smith   ltog->ops->destroy                        = ISLocalToGlobalMappingDestroy_Basic;
16623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1663413f72f0SBarry Smith }
1664413f72f0SBarry Smith 
1665413f72f0SBarry Smith /*MC
1666cab54364SBarry Smith       ISLOCALTOGLOBALMAPPINGHASH - hash implementation of the `ISLocalToGlobalMapping` object. When `ISGlobalToLocalMappingApply()` is
1667ed56e8eaSBarry Smith                                     used this is good for large memory problems.
1668413f72f0SBarry Smith 
166920662ed9SBarry Smith    Options Database Key:
1670a2b725a8SWilliam Gropp .   -islocaltoglobalmapping_type hash - select this method
1671413f72f0SBarry Smith 
1672413f72f0SBarry Smith    Level: beginner
1673413f72f0SBarry Smith 
1674cab54364SBarry Smith    Note:
1675cab54364SBarry Smith     This is selected automatically for large problems if the user does not set the type.
1676cab54364SBarry Smith 
1677cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetType()`, `ISLOCALTOGLOBALMAPPINGBASIC`
1678413f72f0SBarry Smith M*/
1679d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreate_Hash(ISLocalToGlobalMapping ltog)
1680d71ae5a4SJacob Faibussowitsch {
1681413f72f0SBarry Smith   PetscFunctionBegin;
1682413f72f0SBarry Smith   ltog->ops->globaltolocalmappingapply      = ISGlobalToLocalMappingApply_Hash;
1683413f72f0SBarry Smith   ltog->ops->globaltolocalmappingsetup      = ISGlobalToLocalMappingSetUp_Hash;
1684413f72f0SBarry Smith   ltog->ops->globaltolocalmappingapplyblock = ISGlobalToLocalMappingApplyBlock_Hash;
1685413f72f0SBarry Smith   ltog->ops->destroy                        = ISLocalToGlobalMappingDestroy_Hash;
16863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1687413f72f0SBarry Smith }
1688413f72f0SBarry Smith 
1689413f72f0SBarry Smith /*@C
1690cab54364SBarry Smith   ISLocalToGlobalMappingRegister -  Registers a method for applying a global to local mapping with an `ISLocalToGlobalMapping`
1691413f72f0SBarry Smith 
1692413f72f0SBarry Smith   Not Collective
1693413f72f0SBarry Smith 
1694413f72f0SBarry Smith   Input Parameters:
1695413f72f0SBarry Smith + sname    - name of a new method
16962fe279fdSBarry Smith - function - routine to create method context
1697413f72f0SBarry Smith 
169838b5cf2dSJacob Faibussowitsch   Example Usage:
1699413f72f0SBarry Smith .vb
1700413f72f0SBarry Smith    ISLocalToGlobalMappingRegister("my_mapper", MyCreate);
1701413f72f0SBarry Smith .ve
1702413f72f0SBarry Smith 
1703ed56e8eaSBarry Smith   Then, your mapping can be chosen with the procedural interface via
1704413f72f0SBarry Smith $     ISLocalToGlobalMappingSetType(ltog, "my_mapper")
1705413f72f0SBarry Smith   or at runtime via the option
1706ed56e8eaSBarry Smith $     -islocaltoglobalmapping_type my_mapper
1707413f72f0SBarry Smith 
1708413f72f0SBarry Smith   Level: advanced
1709413f72f0SBarry Smith 
1710cab54364SBarry Smith   Note:
1711cab54364SBarry Smith   `ISLocalToGlobalMappingRegister()` may be called multiple times to add several user-defined mappings.
1712413f72f0SBarry Smith 
1713cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingRegisterAll()`, `ISLocalToGlobalMappingRegisterDestroy()`, `ISLOCALTOGLOBALMAPPINGBASIC`,
1714cab54364SBarry Smith           `ISLOCALTOGLOBALMAPPINGHASH`, `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApply()`
1715413f72f0SBarry Smith @*/
1716d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRegister(const char sname[], PetscErrorCode (*function)(ISLocalToGlobalMapping))
1717d71ae5a4SJacob Faibussowitsch {
1718413f72f0SBarry Smith   PetscFunctionBegin;
17199566063dSJacob Faibussowitsch   PetscCall(ISInitializePackage());
17209566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&ISLocalToGlobalMappingList, sname, function));
17213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1722413f72f0SBarry Smith }
1723413f72f0SBarry Smith 
1724413f72f0SBarry Smith /*@C
1725cab54364SBarry Smith   ISLocalToGlobalMappingSetType - Sets the implementation type `ISLocalToGlobalMapping` will use
1726413f72f0SBarry Smith 
1727c3339decSBarry Smith   Logically Collective
1728413f72f0SBarry Smith 
1729413f72f0SBarry Smith   Input Parameters:
1730cab54364SBarry Smith + ltog - the `ISLocalToGlobalMapping` object
1731413f72f0SBarry Smith - type - a known method
1732413f72f0SBarry Smith 
1733413f72f0SBarry Smith   Options Database Key:
1734cab54364SBarry Smith . -islocaltoglobalmapping_type  <method> - Sets the method; use -help for a list of available methods (for instance, basic or hash)
1735cab54364SBarry Smith 
1736cab54364SBarry Smith   Level: intermediate
1737413f72f0SBarry Smith 
1738413f72f0SBarry Smith   Notes:
173920662ed9SBarry Smith   See `ISLocalToGlobalMappingType` for available methods
1740413f72f0SBarry Smith 
1741cab54364SBarry Smith   Normally, it is best to use the `ISLocalToGlobalMappingSetFromOptions()` command and
1742cab54364SBarry Smith   then set the `ISLocalToGlobalMappingType` from the options database rather than by using
1743413f72f0SBarry Smith   this routine.
1744413f72f0SBarry Smith 
174538b5cf2dSJacob Faibussowitsch   Developer Notes:
1746cab54364SBarry Smith   `ISLocalToGlobalMappingRegister()` is used to add new types to `ISLocalToGlobalMappingList` from which they
1747cab54364SBarry Smith   are accessed by `ISLocalToGlobalMappingSetType()`.
1748413f72f0SBarry Smith 
174938b5cf2dSJacob Faibussowitsch .seealso: [](sec_scatter), `ISLocalToGlobalMappingType`, `ISLocalToGlobalMappingRegister()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingGetType()`
1750413f72f0SBarry Smith @*/
1751d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingSetType(ISLocalToGlobalMapping ltog, ISLocalToGlobalMappingType type)
1752d71ae5a4SJacob Faibussowitsch {
1753413f72f0SBarry Smith   PetscBool match;
17545f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(ISLocalToGlobalMapping) = NULL;
1755413f72f0SBarry Smith 
1756413f72f0SBarry Smith   PetscFunctionBegin;
1757413f72f0SBarry Smith   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
17584f572ea9SToby Isaac   if (type) PetscAssertPointer(type, 2);
1759413f72f0SBarry Smith 
17609566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)ltog, type, &match));
17613ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
1762413f72f0SBarry Smith 
1763a0d79125SStefano Zampini   /* L2G maps defer type setup at globaltolocal calls, allow passing NULL here */
1764a0d79125SStefano Zampini   if (type) {
17659566063dSJacob Faibussowitsch     PetscCall(PetscFunctionListFind(ISLocalToGlobalMappingList, type, &r));
1766a0d79125SStefano Zampini     PetscCheck(r, PetscObjectComm((PetscObject)ltog), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested ISLocalToGlobalMapping type %s", type);
1767a0d79125SStefano Zampini   }
1768413f72f0SBarry Smith   /* Destroy the previous private LTOG context */
1769dbbe0bcdSBarry Smith   PetscTryTypeMethod(ltog, destroy);
1770413f72f0SBarry Smith   ltog->ops->destroy = NULL;
1771dbbe0bcdSBarry Smith 
17729566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)ltog, type));
17739566063dSJacob Faibussowitsch   if (r) PetscCall((*r)(ltog));
17743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1775a0d79125SStefano Zampini }
1776a0d79125SStefano Zampini 
1777a0d79125SStefano Zampini /*@C
1778cab54364SBarry Smith   ISLocalToGlobalMappingGetType - Get the type of the `ISLocalToGlobalMapping`
1779a0d79125SStefano Zampini 
1780a0d79125SStefano Zampini   Not Collective
1781a0d79125SStefano Zampini 
1782a0d79125SStefano Zampini   Input Parameter:
1783cab54364SBarry Smith . ltog - the `ISLocalToGlobalMapping` object
1784a0d79125SStefano Zampini 
1785a0d79125SStefano Zampini   Output Parameter:
1786a0d79125SStefano Zampini . type - the type
1787a0d79125SStefano Zampini 
178849762cbcSSatish Balay   Level: intermediate
178949762cbcSSatish Balay 
179038b5cf2dSJacob Faibussowitsch .seealso: [](sec_scatter), `ISLocalToGlobalMappingType`, `ISLocalToGlobalMappingRegister()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetType()`
1791a0d79125SStefano Zampini @*/
1792d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetType(ISLocalToGlobalMapping ltog, ISLocalToGlobalMappingType *type)
1793d71ae5a4SJacob Faibussowitsch {
1794a0d79125SStefano Zampini   PetscFunctionBegin;
1795a0d79125SStefano Zampini   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
17964f572ea9SToby Isaac   PetscAssertPointer(type, 2);
1797a0d79125SStefano Zampini   *type = ((PetscObject)ltog)->type_name;
17983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1799413f72f0SBarry Smith }
1800413f72f0SBarry Smith 
1801413f72f0SBarry Smith PetscBool ISLocalToGlobalMappingRegisterAllCalled = PETSC_FALSE;
1802413f72f0SBarry Smith 
1803413f72f0SBarry Smith /*@C
1804cab54364SBarry Smith   ISLocalToGlobalMappingRegisterAll - Registers all of the local to global mapping components in the `IS` package.
1805413f72f0SBarry Smith 
1806413f72f0SBarry Smith   Not Collective
1807413f72f0SBarry Smith 
1808413f72f0SBarry Smith   Level: advanced
1809413f72f0SBarry Smith 
1810cab54364SBarry Smith .seealso: [](sec_scatter), `ISRegister()`, `ISLocalToGlobalRegister()`
1811413f72f0SBarry Smith @*/
1812d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRegisterAll(void)
1813d71ae5a4SJacob Faibussowitsch {
1814413f72f0SBarry Smith   PetscFunctionBegin;
18153ba16761SJacob Faibussowitsch   if (ISLocalToGlobalMappingRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
1816413f72f0SBarry Smith   ISLocalToGlobalMappingRegisterAllCalled = PETSC_TRUE;
18179566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingRegister(ISLOCALTOGLOBALMAPPINGBASIC, ISLocalToGlobalMappingCreate_Basic));
18189566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingRegister(ISLOCALTOGLOBALMAPPINGHASH, ISLocalToGlobalMappingCreate_Hash));
18193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1820413f72f0SBarry Smith }
1821