xref: /petsc/src/vec/is/utils/isltog.c (revision 03047865b8d8757cf1cf9cda45785c1537b01dc1)
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>
5633354d9SStefano Zampini #include <petscbt.h>
62362add9SBarry Smith 
77087cfbeSBarry Smith PetscClassId          IS_LTOGM_CLASSID;
8633354d9SStefano 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 @*/
ISGetPointRange(IS pointIS,PetscInt * pStart,PetscInt * pEnd,const PetscInt * points[])48cc4c1da9SBarry Smith 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 @*/
ISRestorePointRange(IS pointIS,PetscInt * pStart,PetscInt * pEnd,const PetscInt * points[])79cc4c1da9SBarry Smith 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 
91cc4c1da9SBarry Smith /*@
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 @*/
ISGetPointSubrange(IS subpointIS,PetscInt pStart,PetscInt pEnd,const PetscInt points[])112cc4c1da9SBarry Smith 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     Creates the global mapping information in the ISLocalToGlobalMapping structure
127413f72f0SBarry Smith 
128413f72f0SBarry Smith     If the user has not selected how to handle the global to local mapping then use HASH for "large" problems
129413f72f0SBarry Smith */
ISGlobalToLocalMappingSetUp(ISLocalToGlobalMapping mapping)130d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISGlobalToLocalMappingSetUp(ISLocalToGlobalMapping mapping)
131d71ae5a4SJacob Faibussowitsch {
132413f72f0SBarry Smith   PetscInt i, *idx = mapping->indices, n = mapping->n, end, start;
133413f72f0SBarry Smith 
134413f72f0SBarry Smith   PetscFunctionBegin;
1353ba16761SJacob Faibussowitsch   if (mapping->data) PetscFunctionReturn(PETSC_SUCCESS);
136413f72f0SBarry Smith   end   = 0;
1371690c2aeSBarry Smith   start = PETSC_INT_MAX;
138413f72f0SBarry Smith 
139413f72f0SBarry Smith   for (i = 0; i < n; i++) {
140413f72f0SBarry Smith     if (idx[i] < 0) continue;
141413f72f0SBarry Smith     if (idx[i] < start) start = idx[i];
142413f72f0SBarry Smith     if (idx[i] > end) end = idx[i];
143413f72f0SBarry Smith   }
1449371c9d4SSatish Balay   if (start > end) {
1459371c9d4SSatish Balay     start = 0;
1469371c9d4SSatish Balay     end   = -1;
1479371c9d4SSatish Balay   }
148413f72f0SBarry Smith   mapping->globalstart = start;
149413f72f0SBarry Smith   mapping->globalend   = end;
150413f72f0SBarry Smith   if (!((PetscObject)mapping)->type_name) {
151413f72f0SBarry Smith     if ((end - start) > PetscMax(4 * n, 1000000)) {
1529566063dSJacob Faibussowitsch       PetscCall(ISLocalToGlobalMappingSetType(mapping, ISLOCALTOGLOBALMAPPINGHASH));
153413f72f0SBarry Smith     } else {
1549566063dSJacob Faibussowitsch       PetscCall(ISLocalToGlobalMappingSetType(mapping, ISLOCALTOGLOBALMAPPINGBASIC));
155413f72f0SBarry Smith     }
156413f72f0SBarry Smith   }
157dbbe0bcdSBarry Smith   PetscTryTypeMethod(mapping, globaltolocalmappingsetup);
1583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
159413f72f0SBarry Smith }
160413f72f0SBarry Smith 
ISGlobalToLocalMappingSetUp_Basic(ISLocalToGlobalMapping mapping)161d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISGlobalToLocalMappingSetUp_Basic(ISLocalToGlobalMapping mapping)
162d71ae5a4SJacob Faibussowitsch {
163413f72f0SBarry Smith   PetscInt                      i, *idx = mapping->indices, n = mapping->n, end, start, *globals;
164413f72f0SBarry Smith   ISLocalToGlobalMapping_Basic *map;
165413f72f0SBarry Smith 
166413f72f0SBarry Smith   PetscFunctionBegin;
167413f72f0SBarry Smith   start = mapping->globalstart;
168413f72f0SBarry Smith   end   = mapping->globalend;
1699566063dSJacob Faibussowitsch   PetscCall(PetscNew(&map));
1709566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(end - start + 2, &globals));
171413f72f0SBarry Smith   map->globals = globals;
172413f72f0SBarry Smith   for (i = 0; i < end - start + 1; i++) globals[i] = -1;
173413f72f0SBarry Smith   for (i = 0; i < n; i++) {
174413f72f0SBarry Smith     if (idx[i] < 0) continue;
175413f72f0SBarry Smith     globals[idx[i] - start] = i;
176413f72f0SBarry Smith   }
177413f72f0SBarry Smith   mapping->data = (void *)map;
1783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
179413f72f0SBarry Smith }
180413f72f0SBarry Smith 
ISGlobalToLocalMappingSetUp_Hash(ISLocalToGlobalMapping mapping)181d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISGlobalToLocalMappingSetUp_Hash(ISLocalToGlobalMapping mapping)
182d71ae5a4SJacob Faibussowitsch {
183413f72f0SBarry Smith   PetscInt                     i, *idx = mapping->indices, n = mapping->n;
184413f72f0SBarry Smith   ISLocalToGlobalMapping_Hash *map;
185413f72f0SBarry Smith 
186413f72f0SBarry Smith   PetscFunctionBegin;
1879566063dSJacob Faibussowitsch   PetscCall(PetscNew(&map));
1889566063dSJacob Faibussowitsch   PetscCall(PetscHMapICreate(&map->globalht));
189413f72f0SBarry Smith   for (i = 0; i < n; i++) {
190413f72f0SBarry Smith     if (idx[i] < 0) continue;
1919566063dSJacob Faibussowitsch     PetscCall(PetscHMapISet(map->globalht, idx[i], i));
192413f72f0SBarry Smith   }
193413f72f0SBarry Smith   mapping->data = (void *)map;
1943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
195413f72f0SBarry Smith }
196413f72f0SBarry Smith 
ISLocalToGlobalMappingDestroy_Basic(ISLocalToGlobalMapping mapping)197d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISLocalToGlobalMappingDestroy_Basic(ISLocalToGlobalMapping mapping)
198d71ae5a4SJacob Faibussowitsch {
199413f72f0SBarry Smith   ISLocalToGlobalMapping_Basic *map = (ISLocalToGlobalMapping_Basic *)mapping->data;
200413f72f0SBarry Smith 
201413f72f0SBarry Smith   PetscFunctionBegin;
2023ba16761SJacob Faibussowitsch   if (!map) PetscFunctionReturn(PETSC_SUCCESS);
2039566063dSJacob Faibussowitsch   PetscCall(PetscFree(map->globals));
2049566063dSJacob Faibussowitsch   PetscCall(PetscFree(mapping->data));
2053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
206413f72f0SBarry Smith }
207413f72f0SBarry Smith 
ISLocalToGlobalMappingDestroy_Hash(ISLocalToGlobalMapping mapping)208d71ae5a4SJacob Faibussowitsch static PetscErrorCode ISLocalToGlobalMappingDestroy_Hash(ISLocalToGlobalMapping mapping)
209d71ae5a4SJacob Faibussowitsch {
210413f72f0SBarry Smith   ISLocalToGlobalMapping_Hash *map = (ISLocalToGlobalMapping_Hash *)mapping->data;
211413f72f0SBarry Smith 
212413f72f0SBarry Smith   PetscFunctionBegin;
2133ba16761SJacob Faibussowitsch   if (!map) PetscFunctionReturn(PETSC_SUCCESS);
2149566063dSJacob Faibussowitsch   PetscCall(PetscHMapIDestroy(&map->globalht));
2159566063dSJacob Faibussowitsch   PetscCall(PetscFree(mapping->data));
2163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
217413f72f0SBarry Smith }
218413f72f0SBarry Smith 
ISLocalToGlobalMappingResetBlockInfo_Private(ISLocalToGlobalMapping mapping)2197de13914SStefano Zampini static PetscErrorCode ISLocalToGlobalMappingResetBlockInfo_Private(ISLocalToGlobalMapping mapping)
2207de13914SStefano Zampini {
2217de13914SStefano Zampini   PetscFunctionBegin;
2227de13914SStefano Zampini   PetscCall(PetscFree(mapping->info_procs));
2237de13914SStefano Zampini   PetscCall(PetscFree(mapping->info_numprocs));
2247de13914SStefano Zampini   if (mapping->info_indices) {
2257de13914SStefano Zampini     for (PetscInt i = 0; i < mapping->info_nproc; i++) PetscCall(PetscFree(mapping->info_indices[i]));
2267de13914SStefano Zampini     PetscCall(PetscFree(mapping->info_indices));
2277de13914SStefano Zampini   }
2287de13914SStefano Zampini   if (mapping->info_nodei) PetscCall(PetscFree(mapping->info_nodei[0]));
2297de13914SStefano Zampini   PetscCall(PetscFree2(mapping->info_nodec, mapping->info_nodei));
230d4df40f3SStefano Zampini   PetscCall(PetscSFDestroy(&mapping->multileaves_sf));
2317de13914SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
2327de13914SStefano Zampini }
2337de13914SStefano Zampini 
234413f72f0SBarry Smith #define GTOLTYPE _Basic
235413f72f0SBarry Smith #define GTOLNAME _Basic
236541bf97eSAdrian Croucher #define GTOLBS   mapping->bs
2379371c9d4SSatish Balay #define GTOL(g, local) \
2389371c9d4SSatish Balay   do { \
239413f72f0SBarry Smith     local = map->globals[g / bs - start]; \
2400040bde1SJunchao Zhang     if (local >= 0) local = bs * local + (g % bs); \
241413f72f0SBarry Smith   } while (0)
242541bf97eSAdrian Croucher 
243413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h>
244413f72f0SBarry Smith 
245413f72f0SBarry Smith #define GTOLTYPE _Basic
246413f72f0SBarry Smith #define GTOLNAME Block_Basic
247541bf97eSAdrian Croucher #define GTOLBS   1
2489371c9d4SSatish Balay #define GTOL(g, local) \
249d71ae5a4SJacob Faibussowitsch   do { \
250d71ae5a4SJacob Faibussowitsch     local = map->globals[g - start]; \
251d71ae5a4SJacob Faibussowitsch   } while (0)
252413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h>
253413f72f0SBarry Smith 
254413f72f0SBarry Smith #define GTOLTYPE _Hash
255413f72f0SBarry Smith #define GTOLNAME _Hash
256541bf97eSAdrian Croucher #define GTOLBS   mapping->bs
2579371c9d4SSatish Balay #define GTOL(g, local) \
2589371c9d4SSatish Balay   do { \
259e8f14785SLisandro Dalcin     (void)PetscHMapIGet(map->globalht, g / bs, &local); \
2600040bde1SJunchao Zhang     if (local >= 0) local = bs * local + (g % bs); \
261413f72f0SBarry Smith   } while (0)
262413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h>
263413f72f0SBarry Smith 
264413f72f0SBarry Smith #define GTOLTYPE _Hash
265413f72f0SBarry Smith #define GTOLNAME Block_Hash
266541bf97eSAdrian Croucher #define GTOLBS   1
2679371c9d4SSatish Balay #define GTOL(g, local) \
268d71ae5a4SJacob Faibussowitsch   do { \
269d71ae5a4SJacob Faibussowitsch     (void)PetscHMapIGet(map->globalht, g, &local); \
270d71ae5a4SJacob Faibussowitsch   } while (0)
271413f72f0SBarry Smith #include <../src/vec/is/utils/isltog.h>
272413f72f0SBarry Smith 
2736658fb44Sstefano_zampini /*@
2746658fb44Sstefano_zampini   ISLocalToGlobalMappingDuplicate - Duplicates the local to global mapping object
2756658fb44Sstefano_zampini 
2766658fb44Sstefano_zampini   Not Collective
2776658fb44Sstefano_zampini 
2786658fb44Sstefano_zampini   Input Parameter:
2796658fb44Sstefano_zampini . ltog - local to global mapping
2806658fb44Sstefano_zampini 
2816658fb44Sstefano_zampini   Output Parameter:
2826658fb44Sstefano_zampini . nltog - the duplicated local to global mapping
2836658fb44Sstefano_zampini 
2846658fb44Sstefano_zampini   Level: advanced
2856658fb44Sstefano_zampini 
286cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`
2876658fb44Sstefano_zampini @*/
ISLocalToGlobalMappingDuplicate(ISLocalToGlobalMapping ltog,ISLocalToGlobalMapping * nltog)288d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingDuplicate(ISLocalToGlobalMapping ltog, ISLocalToGlobalMapping *nltog)
289d71ae5a4SJacob Faibussowitsch {
290a0d79125SStefano Zampini   ISLocalToGlobalMappingType l2gtype;
2916658fb44Sstefano_zampini 
2926658fb44Sstefano_zampini   PetscFunctionBegin;
2936658fb44Sstefano_zampini   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
2949566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingCreate(PetscObjectComm((PetscObject)ltog), ltog->bs, ltog->n, ltog->indices, PETSC_COPY_VALUES, nltog));
2959566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingGetType(ltog, &l2gtype));
2969566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingSetType(*nltog, l2gtype));
2973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2986658fb44Sstefano_zampini }
2996658fb44Sstefano_zampini 
300565245c5SBarry Smith /*@
301107e9a97SBarry Smith   ISLocalToGlobalMappingGetSize - Gets the local size of a local to global mapping
3023b9aefa3SBarry Smith 
3033b9aefa3SBarry Smith   Not Collective
3043b9aefa3SBarry Smith 
3053b9aefa3SBarry Smith   Input Parameter:
30638b5cf2dSJacob Faibussowitsch . mapping - local to global mapping
3073b9aefa3SBarry Smith 
3083b9aefa3SBarry Smith   Output Parameter:
309cab54364SBarry Smith . n - the number of entries in the local mapping, `ISLocalToGlobalMappingGetIndices()` returns an array of this length
3103b9aefa3SBarry Smith 
3113b9aefa3SBarry Smith   Level: advanced
3123b9aefa3SBarry Smith 
313cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`
3143b9aefa3SBarry Smith @*/
ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping,PetscInt * n)315d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping mapping, PetscInt *n)
316d71ae5a4SJacob Faibussowitsch {
3173b9aefa3SBarry Smith   PetscFunctionBegin;
3180700a824SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
3194f572ea9SToby Isaac   PetscAssertPointer(n, 2);
320107e9a97SBarry Smith   *n = mapping->bs * mapping->n;
3213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3223b9aefa3SBarry Smith }
3233b9aefa3SBarry Smith 
324ffeef943SBarry Smith /*@
325cab54364SBarry Smith   ISLocalToGlobalMappingViewFromOptions - View an `ISLocalToGlobalMapping` based on values in the options database
326fe2efc57SMark 
327c3339decSBarry Smith   Collective
328fe2efc57SMark 
329fe2efc57SMark   Input Parameters:
330fe2efc57SMark + A    - the local to global mapping object
33120662ed9SBarry Smith . obj  - Optional object that provides the options prefix used for the options database query
332736c3998SJose E. Roman - name - command line option
333fe2efc57SMark 
334fe2efc57SMark   Level: intermediate
335cab54364SBarry Smith 
33620662ed9SBarry Smith   Note:
33720662ed9SBarry Smith   See `PetscObjectViewFromOptions()` for the available `PetscViewer` and `PetscViewerFormat`
33820662ed9SBarry Smith 
339a94f484eSPierre Jolivet .seealso: [](sec_scatter), `PetscViewer`, `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingView`, `PetscObjectViewFromOptions()`, `ISLocalToGlobalMappingCreate()`
340fe2efc57SMark @*/
ISLocalToGlobalMappingViewFromOptions(ISLocalToGlobalMapping A,PetscObject obj,const char name[])341d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingViewFromOptions(ISLocalToGlobalMapping A, PetscObject obj, const char name[])
342d71ae5a4SJacob Faibussowitsch {
343fe2efc57SMark   PetscFunctionBegin;
344fe2efc57SMark   PetscValidHeaderSpecific(A, IS_LTOGM_CLASSID, 1);
3459566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
3463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
347fe2efc57SMark }
348fe2efc57SMark 
349ffeef943SBarry Smith /*@
3505a5d4f66SBarry Smith   ISLocalToGlobalMappingView - View a local to global mapping
3515a5d4f66SBarry Smith 
3527de13914SStefano Zampini   Collective on viewer
353b9cd556bSLois Curfman McInnes 
3545a5d4f66SBarry Smith   Input Parameters:
35538b5cf2dSJacob Faibussowitsch + mapping - local to global mapping
3563b9aefa3SBarry Smith - viewer  - viewer
3575a5d4f66SBarry Smith 
3587de13914SStefano Zampini   Level: intermediate
359a997ad1aSLois Curfman McInnes 
36020662ed9SBarry Smith .seealso: [](sec_scatter), `PetscViewer`, `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`
3615a5d4f66SBarry Smith @*/
ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping,PetscViewer viewer)362d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping mapping, PetscViewer viewer)
363d71ae5a4SJacob Faibussowitsch {
3649f196a02SMartin Diehl   PetscBool         isascii, isbinary;
3657de13914SStefano Zampini   PetscViewerFormat format;
3665a5d4f66SBarry Smith 
3675a5d4f66SBarry Smith   PetscFunctionBegin;
3680700a824SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
36948a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mapping), &viewer));
3700700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
3715a5d4f66SBarry Smith 
3729f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
3737de13914SStefano Zampini   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
3747de13914SStefano Zampini   PetscCall(PetscViewerGetFormat(viewer, &format));
3759f196a02SMartin Diehl   if (isascii) {
3767de13914SStefano Zampini     if (format == PETSC_VIEWER_ASCII_MATLAB) {
3777de13914SStefano Zampini       const PetscInt *idxs;
3787de13914SStefano Zampini       IS              is;
3797de13914SStefano Zampini       const char     *name = ((PetscObject)mapping)->name;
3807de13914SStefano Zampini       char            iname[PETSC_MAX_PATH_LEN];
3817de13914SStefano Zampini 
3827de13914SStefano Zampini       PetscCall(PetscSNPrintf(iname, sizeof(iname), "%sl2g", name ? name : ""));
3837de13914SStefano Zampini       PetscCall(ISLocalToGlobalMappingGetIndices(mapping, &idxs));
3847de13914SStefano Zampini       PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)viewer), mapping->n * mapping->bs, idxs, PETSC_USE_POINTER, &is));
3857de13914SStefano Zampini       PetscCall(PetscObjectSetName((PetscObject)is, iname));
3867de13914SStefano Zampini       PetscCall(ISView(is, viewer));
3877de13914SStefano Zampini       PetscCall(ISLocalToGlobalMappingRestoreIndices(mapping, &idxs));
3887de13914SStefano Zampini       PetscCall(ISDestroy(&is));
3897de13914SStefano Zampini     } else {
3907de13914SStefano Zampini       PetscMPIInt rank;
3917de13914SStefano Zampini 
3927de13914SStefano Zampini       PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)mapping), &rank));
3939566063dSJacob Faibussowitsch       PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mapping, viewer));
3949566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushSynchronized(viewer));
3957de13914SStefano Zampini       for (PetscInt i = 0; i < mapping->n; i++) {
396f2c6b1a2SJed Brown         PetscInt bs = mapping->bs, g = mapping->indices[i];
397f2c6b1a2SJed Brown         if (bs == 1) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT " %" PetscInt_FMT "\n", rank, i, g));
398f2c6b1a2SJed 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));
399f2c6b1a2SJed Brown       }
4009566063dSJacob Faibussowitsch       PetscCall(PetscViewerFlush(viewer));
4019566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopSynchronized(viewer));
4021575c14dSBarry Smith     }
4037de13914SStefano Zampini   } else if (isbinary) {
4047de13914SStefano Zampini     PetscBool skipHeader;
4057de13914SStefano Zampini 
4067de13914SStefano Zampini     PetscCall(PetscViewerSetUp(viewer));
4077de13914SStefano Zampini     PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
4087de13914SStefano Zampini     if (!skipHeader) {
4097de13914SStefano Zampini       PetscMPIInt size;
4107de13914SStefano Zampini       PetscInt    tr[3];
4117de13914SStefano Zampini 
4127de13914SStefano Zampini       PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)viewer), &size));
4137de13914SStefano Zampini       tr[0] = IS_LTOGM_FILE_CLASSID;
4147de13914SStefano Zampini       tr[1] = mapping->bs;
4157de13914SStefano Zampini       tr[2] = size;
4167de13914SStefano Zampini       PetscCall(PetscViewerBinaryWrite(viewer, tr, 3, PETSC_INT));
4177de13914SStefano Zampini       PetscCall(PetscViewerBinaryWriteAll(viewer, &mapping->n, 1, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
4187de13914SStefano Zampini     }
4197de13914SStefano Zampini     /* write block indices */
4207de13914SStefano Zampini     PetscCall(PetscViewerBinaryWriteAll(viewer, mapping->indices, mapping->n, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
4217de13914SStefano Zampini   }
4227de13914SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
4237de13914SStefano Zampini }
4247de13914SStefano Zampini 
4257de13914SStefano Zampini /*@
4267de13914SStefano Zampini   ISLocalToGlobalMappingLoad - Loads a local-to-global mapping that has been stored in binary format.
4277de13914SStefano Zampini 
4287de13914SStefano Zampini   Collective on viewer
4297de13914SStefano Zampini 
4307de13914SStefano Zampini   Input Parameters:
4317de13914SStefano Zampini + mapping - the newly loaded map, this needs to have been created with `ISLocalToGlobalMappingCreate()` or some related function before a call to `ISLocalToGlobalMappingLoad()`
4327de13914SStefano Zampini - viewer  - binary file viewer, obtained from `PetscViewerBinaryOpen()`
4337de13914SStefano Zampini 
4347de13914SStefano Zampini   Level: intermediate
4357de13914SStefano Zampini 
4367de13914SStefano Zampini .seealso: [](sec_scatter), `PetscViewer`, `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingView()`, `ISLocalToGlobalMappingCreate()`
4377de13914SStefano Zampini @*/
ISLocalToGlobalMappingLoad(ISLocalToGlobalMapping mapping,PetscViewer viewer)4387de13914SStefano Zampini PetscErrorCode ISLocalToGlobalMappingLoad(ISLocalToGlobalMapping mapping, PetscViewer viewer)
4397de13914SStefano Zampini {
4407de13914SStefano Zampini   PetscBool isbinary, skipHeader;
4417de13914SStefano Zampini 
4427de13914SStefano Zampini   PetscFunctionBegin;
4437de13914SStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
4447de13914SStefano Zampini   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
4457de13914SStefano Zampini   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
4467de13914SStefano Zampini   PetscCheck(isbinary, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Invalid viewer of type %s", ((PetscObject)viewer)->type_name);
4477de13914SStefano Zampini 
4487de13914SStefano Zampini   /* reset previous data */
4497de13914SStefano Zampini   PetscCall(ISLocalToGlobalMappingResetBlockInfo_Private(mapping));
4507de13914SStefano Zampini 
4517de13914SStefano Zampini   PetscCall(PetscViewerSetUp(viewer));
4527de13914SStefano Zampini   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
4537de13914SStefano Zampini 
4547de13914SStefano Zampini   /* When skipping header, it assumes bs and n have been already set */
4557de13914SStefano Zampini   if (!skipHeader) {
4567de13914SStefano Zampini     MPI_Comm comm = PetscObjectComm((PetscObject)viewer);
4577de13914SStefano Zampini     PetscInt tr[3], nold = mapping->n, *sizes, nmaps = PETSC_DECIDE, st = 0;
4587de13914SStefano Zampini 
4597de13914SStefano Zampini     PetscCall(PetscViewerBinaryRead(viewer, tr, 3, NULL, PETSC_INT));
4607de13914SStefano Zampini     PetscCheck(tr[0] == IS_LTOGM_FILE_CLASSID, PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED, "Not a local-to-global map next in file");
4617de13914SStefano Zampini 
4627de13914SStefano Zampini     mapping->bs = tr[1];
4637de13914SStefano Zampini     PetscCall(PetscMalloc1(tr[2], &sizes));
4647de13914SStefano Zampini     PetscCall(PetscViewerBinaryRead(viewer, sizes, tr[2], NULL, PETSC_INT));
4657de13914SStefano Zampini 
4667de13914SStefano Zampini     /* consume the input, read multiple maps per process if needed */
4677de13914SStefano Zampini     PetscCall(PetscSplitOwnership(comm, &nmaps, &tr[2]));
4687de13914SStefano Zampini     PetscCallMPI(MPI_Exscan(&nmaps, &st, 1, MPIU_INT, MPI_SUM, comm));
4697de13914SStefano Zampini     mapping->n = 0;
4707de13914SStefano Zampini     for (PetscInt i = st; i < st + nmaps; i++) mapping->n += sizes[i];
4717de13914SStefano Zampini     PetscCall(PetscFree(sizes));
4727de13914SStefano Zampini 
4737de13914SStefano Zampini     if (nold != mapping->n) {
4747de13914SStefano Zampini       if (mapping->dealloc_indices) PetscCall(PetscFree(mapping->indices));
4757de13914SStefano Zampini       mapping->indices = NULL;
4767de13914SStefano Zampini     }
4777de13914SStefano Zampini   }
4787de13914SStefano Zampini 
4797de13914SStefano Zampini   /* read indices */
4807de13914SStefano Zampini   if (mapping->n && !mapping->indices) {
4817de13914SStefano Zampini     PetscCall(PetscMalloc1(mapping->n, &mapping->indices));
4827de13914SStefano Zampini     mapping->dealloc_indices = PETSC_TRUE;
4837de13914SStefano Zampini   }
4847de13914SStefano Zampini   PetscCall(PetscViewerBinaryReadAll(viewer, mapping->indices, mapping->n, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
4853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4865a5d4f66SBarry Smith }
4875a5d4f66SBarry Smith 
4881f428162SBarry Smith /*@
4892bdab257SBarry Smith   ISLocalToGlobalMappingCreateIS - Creates a mapping between a local (0 to n)
4902bdab257SBarry Smith   ordering and a global parallel ordering.
4912bdab257SBarry Smith 
49220662ed9SBarry Smith   Not Collective
493b9cd556bSLois Curfman McInnes 
494a997ad1aSLois Curfman McInnes   Input Parameter:
4958c03b21aSDmitry Karpeev . is - index set containing the global numbers for each local number
4962bdab257SBarry Smith 
497a997ad1aSLois Curfman McInnes   Output Parameter:
4982bdab257SBarry Smith . mapping - new mapping data structure
4992bdab257SBarry Smith 
500a997ad1aSLois Curfman McInnes   Level: advanced
501a997ad1aSLois Curfman McInnes 
502cab54364SBarry Smith   Note:
503cab54364SBarry Smith   the block size of the `IS` determines the block size of the mapping
504cab54364SBarry Smith 
505cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetFromOptions()`
5062bdab257SBarry Smith @*/
ISLocalToGlobalMappingCreateIS(IS is,ISLocalToGlobalMapping * mapping)507d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingCreateIS(IS is, ISLocalToGlobalMapping *mapping)
508d71ae5a4SJacob Faibussowitsch {
5093bbf0e92SBarry Smith   PetscInt        n, bs;
5105d0c19d7SBarry Smith   const PetscInt *indices;
5112bdab257SBarry Smith   MPI_Comm        comm;
5123bbf0e92SBarry Smith   PetscBool       isblock;
5133a40ed3dSBarry Smith 
5143a40ed3dSBarry Smith   PetscFunctionBegin;
5150700a824SBarry Smith   PetscValidHeaderSpecific(is, IS_CLASSID, 1);
5164f572ea9SToby Isaac   PetscAssertPointer(mapping, 2);
5172bdab257SBarry Smith 
5189566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)is, &comm));
5199566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(is, &n));
5209566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)is, ISBLOCK, &isblock));
5216006e8d2SBarry Smith   if (!isblock) {
5229566063dSJacob Faibussowitsch     PetscCall(ISGetIndices(is, &indices));
5239566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingCreate(comm, 1, n, indices, PETSC_COPY_VALUES, mapping));
5249566063dSJacob Faibussowitsch     PetscCall(ISRestoreIndices(is, &indices));
5256006e8d2SBarry Smith   } else {
5269566063dSJacob Faibussowitsch     PetscCall(ISGetBlockSize(is, &bs));
5279566063dSJacob Faibussowitsch     PetscCall(ISBlockGetIndices(is, &indices));
5289566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingCreate(comm, bs, n / bs, indices, PETSC_COPY_VALUES, mapping));
5299566063dSJacob Faibussowitsch     PetscCall(ISBlockRestoreIndices(is, &indices));
5306006e8d2SBarry Smith   }
5313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5322bdab257SBarry Smith }
5335a5d4f66SBarry Smith 
534cc4c1da9SBarry Smith /*@
535d4df40f3SStefano Zampini   ISLocalToGlobalMappingCreateSF - Creates a mapping between a local (0 to n) ordering and a global parallel ordering induced by a star forest.
536a4d96a55SJed Brown 
537a4d96a55SJed Brown   Collective
538a4d96a55SJed Brown 
539d8d19677SJose E. Roman   Input Parameters:
540a4d96a55SJed Brown + sf    - star forest mapping contiguous local indices to (rank, offset)
541cab54364SBarry Smith - start - first global index on this process, or `PETSC_DECIDE` to compute contiguous global numbering automatically
542a4d96a55SJed Brown 
543a4d96a55SJed Brown   Output Parameter:
544a4d96a55SJed Brown . mapping - new mapping data structure
545a4d96a55SJed Brown 
546a4d96a55SJed Brown   Level: advanced
547a4d96a55SJed Brown 
54820662ed9SBarry Smith   Note:
549633354d9SStefano Zampini   If a process calls this function with `start` = `PETSC_DECIDE` then all processes must, otherwise the program will hang.
5509a535bafSVaclav Hapla 
551cab54364SBarry Smith .seealso: [](sec_scatter), `PetscSF`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingSetFromOptions()`
552a4d96a55SJed Brown @*/
ISLocalToGlobalMappingCreateSF(PetscSF sf,PetscInt start,ISLocalToGlobalMapping * mapping)553d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF sf, PetscInt start, ISLocalToGlobalMapping *mapping)
554d71ae5a4SJacob Faibussowitsch {
555a4d96a55SJed Brown   PetscInt i, maxlocal, nroots, nleaves, *globals, *ltog;
556a4d96a55SJed Brown   MPI_Comm comm;
557a4d96a55SJed Brown 
558a4d96a55SJed Brown   PetscFunctionBegin;
559a4d96a55SJed Brown   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1);
5604f572ea9SToby Isaac   PetscAssertPointer(mapping, 3);
5619566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)sf, &comm));
56241f4c31fSVaclav Hapla   PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL));
5639a535bafSVaclav Hapla   if (start == PETSC_DECIDE) {
5649a535bafSVaclav Hapla     start = 0;
5659566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Exscan(&nroots, &start, 1, MPIU_INT, MPI_SUM, comm));
56641f4c31fSVaclav Hapla   } else PetscCheck(start >= 0, comm, PETSC_ERR_ARG_OUTOFRANGE, "start must be nonnegative or PETSC_DECIDE");
56741f4c31fSVaclav Hapla   PetscCall(PetscSFGetLeafRange(sf, NULL, &maxlocal));
56841f4c31fSVaclav Hapla   ++maxlocal;
5699566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(nroots, &globals));
5709566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(maxlocal, &ltog));
571a4d96a55SJed Brown   for (i = 0; i < nroots; i++) globals[i] = start + i;
572a4d96a55SJed Brown   for (i = 0; i < maxlocal; i++) ltog[i] = -1;
5739566063dSJacob Faibussowitsch   PetscCall(PetscSFBcastBegin(sf, MPIU_INT, globals, ltog, MPI_REPLACE));
5749566063dSJacob Faibussowitsch   PetscCall(PetscSFBcastEnd(sf, MPIU_INT, globals, ltog, MPI_REPLACE));
5759566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingCreate(comm, 1, maxlocal, ltog, PETSC_OWN_POINTER, mapping));
5769566063dSJacob Faibussowitsch   PetscCall(PetscFree(globals));
5773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
578a4d96a55SJed Brown }
579b46b645bSBarry Smith 
58063fa5c83Sstefano_zampini /*@
58163fa5c83Sstefano_zampini   ISLocalToGlobalMappingSetBlockSize - Sets the blocksize of the mapping
58263fa5c83Sstefano_zampini 
58320662ed9SBarry Smith   Not Collective
58463fa5c83Sstefano_zampini 
58563fa5c83Sstefano_zampini   Input Parameters:
586a2b725a8SWilliam Gropp + mapping - mapping data structure
587a2b725a8SWilliam Gropp - bs      - the blocksize
58863fa5c83Sstefano_zampini 
58963fa5c83Sstefano_zampini   Level: advanced
59063fa5c83Sstefano_zampini 
591cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`
59263fa5c83Sstefano_zampini @*/
ISLocalToGlobalMappingSetBlockSize(ISLocalToGlobalMapping mapping,PetscInt bs)593d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingSetBlockSize(ISLocalToGlobalMapping mapping, PetscInt bs)
594d71ae5a4SJacob Faibussowitsch {
595a59f3c4dSstefano_zampini   PetscInt       *nid;
596a59f3c4dSstefano_zampini   const PetscInt *oid;
597a59f3c4dSstefano_zampini   PetscInt        i, cn, on, obs, nn;
59863fa5c83Sstefano_zampini 
59963fa5c83Sstefano_zampini   PetscFunctionBegin;
60063fa5c83Sstefano_zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
60108401ef6SPierre Jolivet   PetscCheck(bs >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid block size %" PetscInt_FMT, bs);
6023ba16761SJacob Faibussowitsch   if (bs == mapping->bs) PetscFunctionReturn(PETSC_SUCCESS);
60363fa5c83Sstefano_zampini   on  = mapping->n;
60463fa5c83Sstefano_zampini   obs = mapping->bs;
60563fa5c83Sstefano_zampini   oid = mapping->indices;
60663fa5c83Sstefano_zampini   nn  = (on * obs) / bs;
60708401ef6SPierre 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);
608a59f3c4dSstefano_zampini 
6099566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(nn, &nid));
6109566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingGetIndices(mapping, &oid));
611a59f3c4dSstefano_zampini   for (i = 0; i < nn; i++) {
612a59f3c4dSstefano_zampini     PetscInt j;
613a59f3c4dSstefano_zampini     for (j = 0, cn = 0; j < bs - 1; j++) {
6149371c9d4SSatish Balay       if (oid[i * bs + j] < 0) {
6159371c9d4SSatish Balay         cn++;
6169371c9d4SSatish Balay         continue;
6179371c9d4SSatish Balay       }
61808401ef6SPierre 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]);
619a59f3c4dSstefano_zampini     }
620a59f3c4dSstefano_zampini     if (oid[i * bs + j] < 0) cn++;
6218b7cb0e6Sstefano_zampini     if (cn) {
62208401ef6SPierre 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);
623a59f3c4dSstefano_zampini       nid[i] = -1;
6248b7cb0e6Sstefano_zampini     } else {
625a59f3c4dSstefano_zampini       nid[i] = oid[i * bs] / bs;
62663fa5c83Sstefano_zampini     }
62763fa5c83Sstefano_zampini   }
6289566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingRestoreIndices(mapping, &oid));
629a59f3c4dSstefano_zampini 
63063fa5c83Sstefano_zampini   mapping->n  = nn;
63163fa5c83Sstefano_zampini   mapping->bs = bs;
6329566063dSJacob Faibussowitsch   PetscCall(PetscFree(mapping->indices));
63363fa5c83Sstefano_zampini   mapping->indices     = nid;
634c9345713Sstefano_zampini   mapping->globalstart = 0;
635c9345713Sstefano_zampini   mapping->globalend   = 0;
6361bd0b88eSStefano Zampini 
6371bd0b88eSStefano Zampini   /* reset the cached information */
638633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingResetBlockInfo_Private(mapping));
639dbbe0bcdSBarry Smith   PetscTryTypeMethod(mapping, destroy);
6403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
64163fa5c83Sstefano_zampini }
64263fa5c83Sstefano_zampini 
64345b6f7e9SBarry Smith /*@
64445b6f7e9SBarry Smith   ISLocalToGlobalMappingGetBlockSize - Gets the blocksize of the mapping
64545b6f7e9SBarry Smith   ordering and a global parallel ordering.
64645b6f7e9SBarry Smith 
64745b6f7e9SBarry Smith   Not Collective
64845b6f7e9SBarry Smith 
6492fe279fdSBarry Smith   Input Parameter:
65045b6f7e9SBarry Smith . mapping - mapping data structure
65145b6f7e9SBarry Smith 
65245b6f7e9SBarry Smith   Output Parameter:
65345b6f7e9SBarry Smith . bs - the blocksize
65445b6f7e9SBarry Smith 
65545b6f7e9SBarry Smith   Level: advanced
65645b6f7e9SBarry Smith 
657cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`
65845b6f7e9SBarry Smith @*/
ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping,PetscInt * bs)659d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping mapping, PetscInt *bs)
660d71ae5a4SJacob Faibussowitsch {
66145b6f7e9SBarry Smith   PetscFunctionBegin;
662cbc1caf0SMatthew G. Knepley   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
66345b6f7e9SBarry Smith   *bs = mapping->bs;
6643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
66545b6f7e9SBarry Smith }
66645b6f7e9SBarry Smith 
667ba5bb76aSSatish Balay /*@
66890f02eecSBarry Smith   ISLocalToGlobalMappingCreate - Creates a mapping between a local (0 to n)
66990f02eecSBarry Smith   ordering and a global parallel ordering.
6702362add9SBarry Smith 
67189d82c54SBarry Smith   Not Collective, but communicator may have more than one process
672b9cd556bSLois Curfman McInnes 
6732362add9SBarry Smith   Input Parameters:
67489d82c54SBarry Smith + comm    - MPI communicator
675f0413b6fSBarry Smith . bs      - the block size
67628bc9809SBarry Smith . n       - the number of local elements divided by the block size, or equivalently the number of block indices
67728bc9809SBarry 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
678d5ad8652SBarry Smith - mode    - see PetscCopyMode
6792362add9SBarry Smith 
680a997ad1aSLois Curfman McInnes   Output Parameter:
68190f02eecSBarry Smith . mapping - new mapping data structure
6822362add9SBarry Smith 
683cab54364SBarry Smith   Level: advanced
684cab54364SBarry Smith 
68595452b02SPatrick Sanan   Notes:
68695452b02SPatrick Sanan   There is one integer value in indices per block and it represents the actual indices bs*idx + j, where j=0,..,bs-1
687413f72f0SBarry Smith 
688cab54364SBarry Smith   For "small" problems when using `ISGlobalToLocalMappingApply()` and `ISGlobalToLocalMappingApplyBlock()`, the `ISLocalToGlobalMappingType`
689cab54364SBarry Smith   of `ISLOCALTOGLOBALMAPPINGBASIC` will be used; this uses more memory but is faster; this approach is not scalable for extremely large mappings.
690413f72f0SBarry Smith 
691cab54364SBarry Smith   For large problems `ISLOCALTOGLOBALMAPPINGHASH` is used, this is scalable.
69220662ed9SBarry Smith   Use `ISLocalToGlobalMappingSetType()` or call `ISLocalToGlobalMappingSetFromOptions()` with the option
69320662ed9SBarry Smith   `-islocaltoglobalmapping_type` <`basic`,`hash`> to control which is used.
694a997ad1aSLois Curfman McInnes 
69520662ed9SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingSetFromOptions()`,
69620662ed9SBarry Smith           `ISLOCALTOGLOBALMAPPINGBASIC`, `ISLOCALTOGLOBALMAPPINGHASH`
697db781477SPatrick Sanan           `ISLocalToGlobalMappingSetType()`, `ISLocalToGlobalMappingType`
6982362add9SBarry Smith @*/
ISLocalToGlobalMappingCreate(MPI_Comm comm,PetscInt bs,PetscInt n,const PetscInt indices[],PetscCopyMode mode,ISLocalToGlobalMapping * mapping)699d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm comm, PetscInt bs, PetscInt n, const PetscInt indices[], PetscCopyMode mode, ISLocalToGlobalMapping *mapping)
700d71ae5a4SJacob Faibussowitsch {
70132dcc486SBarry Smith   PetscInt *in;
702b46b645bSBarry Smith 
703b46b645bSBarry Smith   PetscFunctionBegin;
7044f572ea9SToby Isaac   if (n) PetscAssertPointer(indices, 4);
7054f572ea9SToby Isaac   PetscAssertPointer(mapping, 6);
706b46b645bSBarry Smith 
7070298fd71SBarry Smith   *mapping = NULL;
7089566063dSJacob Faibussowitsch   PetscCall(ISInitializePackage());
7092362add9SBarry Smith 
7109566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(*mapping, IS_LTOGM_CLASSID, "ISLocalToGlobalMapping", "Local to global mapping", "IS", comm, ISLocalToGlobalMappingDestroy, ISLocalToGlobalMappingView));
711d4bb536fSBarry Smith   (*mapping)->n  = n;
712f0413b6fSBarry Smith   (*mapping)->bs = bs;
713d5ad8652SBarry Smith   if (mode == PETSC_COPY_VALUES) {
7149566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &in));
7159566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(in, indices, n));
716d5ad8652SBarry Smith     (*mapping)->indices         = in;
71771910c26SVaclav Hapla     (*mapping)->dealloc_indices = PETSC_TRUE;
7186389a1a1SBarry Smith   } else if (mode == PETSC_OWN_POINTER) {
7196389a1a1SBarry Smith     (*mapping)->indices         = (PetscInt *)indices;
72071910c26SVaclav Hapla     (*mapping)->dealloc_indices = PETSC_TRUE;
72171910c26SVaclav Hapla   } else if (mode == PETSC_USE_POINTER) {
72271910c26SVaclav Hapla     (*mapping)->indices = (PetscInt *)indices;
7239371c9d4SSatish Balay   } else SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Invalid mode %d", mode);
7243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7252362add9SBarry Smith }
7262362add9SBarry Smith 
727413f72f0SBarry Smith PetscFunctionList ISLocalToGlobalMappingList = NULL;
728413f72f0SBarry Smith 
72990f02eecSBarry Smith /*@
7307e99dc12SLawrence Mitchell   ISLocalToGlobalMappingSetFromOptions - Set mapping options from the options database.
7317e99dc12SLawrence Mitchell 
73220662ed9SBarry Smith   Not Collective
7337e99dc12SLawrence Mitchell 
7342fe279fdSBarry Smith   Input Parameter:
7357e99dc12SLawrence Mitchell . mapping - mapping data structure
7367e99dc12SLawrence Mitchell 
73720662ed9SBarry Smith   Options Database Key:
73820662ed9SBarry Smith . -islocaltoglobalmapping_type - <basic,hash> nonscalable and scalable versions
73920662ed9SBarry Smith 
7407e99dc12SLawrence Mitchell   Level: advanced
7417e99dc12SLawrence Mitchell 
74242747ad1SJacob Faibussowitsch .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingDestroy()`,
74342747ad1SJacob Faibussowitsch `ISLocalToGlobalMappingCreateIS()`, `ISLOCALTOGLOBALMAPPINGBASIC`,
74442747ad1SJacob Faibussowitsch `ISLOCALTOGLOBALMAPPINGHASH`, `ISLocalToGlobalMappingSetType()`, `ISLocalToGlobalMappingType`
7457e99dc12SLawrence Mitchell @*/
ISLocalToGlobalMappingSetFromOptions(ISLocalToGlobalMapping mapping)746d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingSetFromOptions(ISLocalToGlobalMapping mapping)
747d71ae5a4SJacob Faibussowitsch {
748413f72f0SBarry Smith   char                       type[256];
749413f72f0SBarry Smith   ISLocalToGlobalMappingType defaulttype = "Not set";
7507e99dc12SLawrence Mitchell   PetscBool                  flg;
7517e99dc12SLawrence Mitchell 
7527e99dc12SLawrence Mitchell   PetscFunctionBegin;
7537e99dc12SLawrence Mitchell   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
7549566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingRegisterAll());
755d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)mapping);
75657508eceSPierre Jolivet   PetscCall(PetscOptionsFList("-islocaltoglobalmapping_type", "ISLocalToGlobalMapping method", "ISLocalToGlobalMappingSetType", ISLocalToGlobalMappingList, ((PetscObject)mapping)->type_name ? ((PetscObject)mapping)->type_name : defaulttype, type, 256, &flg));
7571baa6e33SBarry Smith   if (flg) PetscCall(ISLocalToGlobalMappingSetType(mapping, type));
758d0609cedSBarry Smith   PetscOptionsEnd();
7593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7607e99dc12SLawrence Mitchell }
7617e99dc12SLawrence Mitchell 
7627e99dc12SLawrence Mitchell /*@
76390f02eecSBarry Smith   ISLocalToGlobalMappingDestroy - Destroys a mapping between a local (0 to n)
76490f02eecSBarry Smith   ordering and a global parallel ordering.
76590f02eecSBarry Smith 
76620662ed9SBarry Smith   Not Collective
767b9cd556bSLois Curfman McInnes 
7682fe279fdSBarry Smith   Input Parameter:
76990f02eecSBarry Smith . mapping - mapping data structure
77090f02eecSBarry Smith 
771a997ad1aSLois Curfman McInnes   Level: advanced
772a997ad1aSLois Curfman McInnes 
773cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingCreate()`
77490f02eecSBarry Smith @*/
ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping * mapping)775d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *mapping)
776d71ae5a4SJacob Faibussowitsch {
7773a40ed3dSBarry Smith   PetscFunctionBegin;
7783ba16761SJacob Faibussowitsch   if (!*mapping) PetscFunctionReturn(PETSC_SUCCESS);
779f4f49eeaSPierre Jolivet   PetscValidHeaderSpecific(*mapping, IS_LTOGM_CLASSID, 1);
780f4f49eeaSPierre Jolivet   if (--((PetscObject)*mapping)->refct > 0) {
7819371c9d4SSatish Balay     *mapping = NULL;
7823ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
78371910c26SVaclav Hapla   }
78448a46eb9SPierre Jolivet   if ((*mapping)->dealloc_indices) PetscCall(PetscFree((*mapping)->indices));
785633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingResetBlockInfo_Private(*mapping));
786213acdd3SPierre Jolivet   PetscTryTypeMethod(*mapping, destroy);
7879566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(mapping));
7883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
78990f02eecSBarry Smith }
79090f02eecSBarry Smith 
79190f02eecSBarry Smith /*@
792cab54364SBarry Smith   ISLocalToGlobalMappingApplyIS - Creates from an `IS` in the local numbering
793cab54364SBarry Smith   a new index set using the global numbering defined in an `ISLocalToGlobalMapping`
7943acfe500SLois Curfman McInnes   context.
79590f02eecSBarry Smith 
796c3339decSBarry Smith   Collective
797b9cd556bSLois Curfman McInnes 
79890f02eecSBarry Smith   Input Parameters:
799b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering
800b9cd556bSLois Curfman McInnes - is      - index set in local numbering
80190f02eecSBarry Smith 
802cab54364SBarry Smith   Output Parameter:
80390f02eecSBarry Smith . newis - index set in global numbering
80490f02eecSBarry Smith 
805a997ad1aSLois Curfman McInnes   Level: advanced
806a997ad1aSLois Curfman McInnes 
807cab54364SBarry Smith   Note:
808586b16e1SPierre Jolivet   The output `IS` will have the same communicator as the input `IS` as well as the same block size.
809cab54364SBarry Smith 
810cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingCreate()`,
811db781477SPatrick Sanan           `ISLocalToGlobalMappingDestroy()`, `ISGlobalToLocalMappingApply()`
81290f02eecSBarry Smith @*/
ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping,IS is,IS * newis)813d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping mapping, IS is, IS *newis)
814d71ae5a4SJacob Faibussowitsch {
815586b16e1SPierre Jolivet   PetscInt        n, *idxout, bs;
8165d0c19d7SBarry Smith   const PetscInt *idxin;
8173a40ed3dSBarry Smith 
8183a40ed3dSBarry Smith   PetscFunctionBegin;
8190700a824SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
8200700a824SBarry Smith   PetscValidHeaderSpecific(is, IS_CLASSID, 2);
8214f572ea9SToby Isaac   PetscAssertPointer(newis, 3);
82290f02eecSBarry Smith 
8239566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(is, &n));
824586b16e1SPierre Jolivet   PetscCall(ISGetBlockSize(is, &bs));
8259566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(is, &idxin));
8269566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &idxout));
8279566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingApply(mapping, n, idxin, idxout));
8289566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(is, &idxin));
8299566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)is), n, idxout, PETSC_OWN_POINTER, newis));
830586b16e1SPierre Jolivet   PetscCall(ISSetBlockSize(*newis, bs));
8313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
83290f02eecSBarry Smith }
83390f02eecSBarry Smith 
834b89cb25eSSatish Balay /*@
8353acfe500SLois Curfman McInnes   ISLocalToGlobalMappingApply - Takes a list of integers in a local numbering
8363acfe500SLois Curfman McInnes   and converts them to the global numbering.
83790f02eecSBarry Smith 
83820662ed9SBarry Smith   Not Collective
839b9cd556bSLois Curfman McInnes 
840bb25748dSBarry Smith   Input Parameters:
841b9cd556bSLois Curfman McInnes + mapping - the local to global mapping context
842bb25748dSBarry Smith . N       - number of integers
843b9cd556bSLois Curfman McInnes - in      - input indices in local numbering
844bb25748dSBarry Smith 
845bb25748dSBarry Smith   Output Parameter:
846bb25748dSBarry Smith . out - indices in global numbering
847bb25748dSBarry Smith 
848a997ad1aSLois Curfman McInnes   Level: advanced
849a997ad1aSLois Curfman McInnes 
850cab54364SBarry Smith   Note:
85120662ed9SBarry Smith   The `in` and `out` array parameters may be identical.
852cab54364SBarry Smith 
853cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApplyBlock()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingDestroy()`,
854c2e3fba1SPatrick Sanan           `ISLocalToGlobalMappingApplyIS()`, `AOCreateBasic()`, `AOApplicationToPetsc()`,
855db781477SPatrick Sanan           `AOPetscToApplication()`, `ISGlobalToLocalMappingApply()`
856afcb2eb5SJed Brown @*/
ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[])857d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping mapping, PetscInt N, const PetscInt in[], PetscInt out[])
858d71ae5a4SJacob Faibussowitsch {
859cbc1caf0SMatthew G. Knepley   PetscInt i, bs, Nmax;
86045b6f7e9SBarry Smith 
86145b6f7e9SBarry Smith   PetscFunctionBegin;
862cbc1caf0SMatthew G. Knepley   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
863cbc1caf0SMatthew G. Knepley   bs   = mapping->bs;
864cbc1caf0SMatthew G. Knepley   Nmax = bs * mapping->n;
86545b6f7e9SBarry Smith   if (bs == 1) {
866cbc1caf0SMatthew G. Knepley     const PetscInt *idx = mapping->indices;
86745b6f7e9SBarry Smith     for (i = 0; i < N; i++) {
86845b6f7e9SBarry Smith       if (in[i] < 0) {
86945b6f7e9SBarry Smith         out[i] = in[i];
87045b6f7e9SBarry Smith         continue;
87145b6f7e9SBarry Smith       }
87208401ef6SPierre 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);
87345b6f7e9SBarry Smith       out[i] = idx[in[i]];
87445b6f7e9SBarry Smith     }
87545b6f7e9SBarry Smith   } else {
876cbc1caf0SMatthew G. Knepley     const PetscInt *idx = mapping->indices;
87745b6f7e9SBarry Smith     for (i = 0; i < N; i++) {
87845b6f7e9SBarry Smith       if (in[i] < 0) {
87945b6f7e9SBarry Smith         out[i] = in[i];
88045b6f7e9SBarry Smith         continue;
88145b6f7e9SBarry Smith       }
88208401ef6SPierre 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);
88345b6f7e9SBarry Smith       out[i] = idx[in[i] / bs] * bs + (in[i] % bs);
88445b6f7e9SBarry Smith     }
88545b6f7e9SBarry Smith   }
8863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
88745b6f7e9SBarry Smith }
88845b6f7e9SBarry Smith 
88945b6f7e9SBarry Smith /*@
8906006e8d2SBarry Smith   ISLocalToGlobalMappingApplyBlock - Takes a list of integers in a local block numbering and converts them to the global block numbering
89145b6f7e9SBarry Smith 
89220662ed9SBarry Smith   Not Collective
89345b6f7e9SBarry Smith 
89445b6f7e9SBarry Smith   Input Parameters:
89545b6f7e9SBarry Smith + mapping - the local to global mapping context
89645b6f7e9SBarry Smith . N       - number of integers
8976006e8d2SBarry Smith - in      - input indices in local block numbering
89845b6f7e9SBarry Smith 
89945b6f7e9SBarry Smith   Output Parameter:
9006006e8d2SBarry Smith . out - indices in global block numbering
90145b6f7e9SBarry Smith 
9026006e8d2SBarry Smith   Example:
903cab54364SBarry 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
9046006e8d2SBarry Smith   (the first block) would produce 0 and the mapping applied to 1 (the second block) would produce 3.
9056006e8d2SBarry Smith 
90620662ed9SBarry Smith   Level: advanced
90720662ed9SBarry Smith 
90820662ed9SBarry Smith   Note:
90920662ed9SBarry Smith   The `in` and `out` array parameters may be identical.
91020662ed9SBarry Smith 
911cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingDestroy()`,
912c2e3fba1SPatrick Sanan           `ISLocalToGlobalMappingApplyIS()`, `AOCreateBasic()`, `AOApplicationToPetsc()`,
913db781477SPatrick Sanan           `AOPetscToApplication()`, `ISGlobalToLocalMappingApply()`
91445b6f7e9SBarry Smith @*/
ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping,PetscInt N,const PetscInt in[],PetscInt out[])915d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping mapping, PetscInt N, const PetscInt in[], PetscInt out[])
916d71ae5a4SJacob Faibussowitsch {
9178a1f772fSStefano Zampini   PetscInt        i, Nmax;
9188a1f772fSStefano Zampini   const PetscInt *idx;
919d4bb536fSBarry Smith 
920a0d79125SStefano Zampini   PetscFunctionBegin;
921a0d79125SStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
9228a1f772fSStefano Zampini   Nmax = mapping->n;
9238a1f772fSStefano Zampini   idx  = mapping->indices;
924afcb2eb5SJed Brown   for (i = 0; i < N; i++) {
925afcb2eb5SJed Brown     if (in[i] < 0) {
926afcb2eb5SJed Brown       out[i] = in[i];
927afcb2eb5SJed Brown       continue;
928afcb2eb5SJed Brown     }
92908401ef6SPierre 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);
930afcb2eb5SJed Brown     out[i] = idx[in[i]];
931afcb2eb5SJed Brown   }
9323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
933afcb2eb5SJed Brown }
934d4bb536fSBarry Smith 
9357e99dc12SLawrence Mitchell /*@
936a997ad1aSLois Curfman McInnes   ISGlobalToLocalMappingApply - Provides the local numbering for a list of integers
937a997ad1aSLois Curfman McInnes   specified with a global numbering.
938d4bb536fSBarry Smith 
93920662ed9SBarry Smith   Not Collective
940b9cd556bSLois Curfman McInnes 
941d4bb536fSBarry Smith   Input Parameters:
942b9cd556bSLois Curfman McInnes + mapping - mapping between local and global numbering
943cab54364SBarry Smith . type    - `IS_GTOLM_MASK` - maps global indices with no local value to -1 in the output list (i.e., mask them)
944cab54364SBarry Smith            `IS_GTOLM_DROP` - drops the indices with no local value from the output list
945d4bb536fSBarry Smith . n       - number of global indices to map
946b9cd556bSLois Curfman McInnes - idx     - global indices to map
947d4bb536fSBarry Smith 
948d4bb536fSBarry Smith   Output Parameters:
949cab54364SBarry Smith + nout   - number of indices in output array (if type == `IS_GTOLM_MASK` then nout = n)
950b9cd556bSLois Curfman McInnes - idxout - local index of each global index, one must pass in an array long enough
951cab54364SBarry Smith              to hold all the indices. You can call `ISGlobalToLocalMappingApply()` with
9520298fd71SBarry Smith              idxout == NULL to determine the required length (returned in nout)
953cab54364SBarry Smith              and then allocate the required space and call `ISGlobalToLocalMappingApply()`
954e182c471SBarry Smith              a second time to set the values.
955d4bb536fSBarry Smith 
956cab54364SBarry Smith   Level: advanced
957cab54364SBarry Smith 
958b9cd556bSLois Curfman McInnes   Notes:
95920662ed9SBarry Smith   Either `nout` or `idxout` may be `NULL`. `idx` and `idxout` may be identical.
960d4bb536fSBarry Smith 
96120662ed9SBarry Smith   For "small" problems when using `ISGlobalToLocalMappingApply()` and `ISGlobalToLocalMappingApplyBlock()`, the `ISLocalToGlobalMappingType` of
96220662ed9SBarry Smith   `ISLOCALTOGLOBALMAPPINGBASIC` will be used;
963cab54364SBarry 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.
964cab54364SBarry Smith   Use `ISLocalToGlobalMappingSetType()` or call `ISLocalToGlobalMappingSetFromOptions()` with the option -islocaltoglobalmapping_type <basic,hash> to control which is used.
9650f5bd95cSBarry Smith 
96638b5cf2dSJacob Faibussowitsch   Developer Notes:
96720662ed9SBarry Smith   The manual page states that `idx` and `idxout` may be identical but the calling
96820662ed9SBarry Smith   sequence declares `idx` as const so it cannot be the same as `idxout`.
96932fd6b96SBarry Smith 
970cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApply()`, `ISGlobalToLocalMappingApplyBlock()`, `ISLocalToGlobalMappingCreate()`,
971db781477SPatrick Sanan           `ISLocalToGlobalMappingDestroy()`
972d4bb536fSBarry Smith @*/
ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingMode type,PetscInt n,const PetscInt idx[],PetscInt * nout,PetscInt idxout[])973d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingMode type, PetscInt n, const PetscInt idx[], PetscInt *nout, PetscInt idxout[])
974d71ae5a4SJacob Faibussowitsch {
9759d90f715SBarry Smith   PetscFunctionBegin;
9769d90f715SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
97748a46eb9SPierre Jolivet   if (!mapping->data) PetscCall(ISGlobalToLocalMappingSetUp(mapping));
978dbbe0bcdSBarry Smith   PetscUseTypeMethod(mapping, globaltolocalmappingapply, type, n, idx, nout, idxout);
9793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9809d90f715SBarry Smith }
9819d90f715SBarry Smith 
982d4fe737eSStefano Zampini /*@
983cab54364SBarry Smith   ISGlobalToLocalMappingApplyIS - Creates from an `IS` in the global numbering
984cab54364SBarry Smith   a new index set using the local numbering defined in an `ISLocalToGlobalMapping`
985d4fe737eSStefano Zampini   context.
986d4fe737eSStefano Zampini 
98720662ed9SBarry Smith   Not Collective
988d4fe737eSStefano Zampini 
989d4fe737eSStefano Zampini   Input Parameters:
990d4fe737eSStefano Zampini + mapping - mapping between local and global numbering
991cab54364SBarry Smith . type    - `IS_GTOLM_MASK` - maps global indices with no local value to -1 in the output list (i.e., mask them)
992cab54364SBarry Smith            `IS_GTOLM_DROP` - drops the indices with no local value from the output list
993d4fe737eSStefano Zampini - is      - index set in global numbering
994d4fe737eSStefano Zampini 
9952fe279fdSBarry Smith   Output Parameter:
996d4fe737eSStefano Zampini . newis - index set in local numbering
997d4fe737eSStefano Zampini 
998d4fe737eSStefano Zampini   Level: advanced
999d4fe737eSStefano Zampini 
1000586b16e1SPierre Jolivet   Notes:
1001cab54364SBarry Smith   The output `IS` will be sequential, as it encodes a purely local operation
1002cab54364SBarry Smith 
1003586b16e1SPierre Jolivet   If `type` is `IS_GTOLM_MASK`, `newis` will have the same block size as `is`
1004586b16e1SPierre Jolivet 
1005cab54364SBarry Smith .seealso: [](sec_scatter), `ISGlobalToLocalMapping`, `ISGlobalToLocalMappingApply()`, `ISLocalToGlobalMappingCreate()`,
1006db781477SPatrick Sanan           `ISLocalToGlobalMappingDestroy()`
1007d4fe737eSStefano Zampini @*/
ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingMode type,IS is,IS * newis)1008d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingMode type, IS is, IS *newis)
1009d71ae5a4SJacob Faibussowitsch {
1010586b16e1SPierre Jolivet   PetscInt        n, nout, *idxout, bs;
1011d4fe737eSStefano Zampini   const PetscInt *idxin;
1012d4fe737eSStefano Zampini 
1013d4fe737eSStefano Zampini   PetscFunctionBegin;
1014d4fe737eSStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1015d4fe737eSStefano Zampini   PetscValidHeaderSpecific(is, IS_CLASSID, 3);
10164f572ea9SToby Isaac   PetscAssertPointer(newis, 4);
1017d4fe737eSStefano Zampini 
10189566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(is, &n));
10199566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(is, &idxin));
1020d4fe737eSStefano Zampini   if (type == IS_GTOLM_MASK) {
10219566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &idxout));
1022d4fe737eSStefano Zampini   } else {
10239566063dSJacob Faibussowitsch     PetscCall(ISGlobalToLocalMappingApply(mapping, type, n, idxin, &nout, NULL));
10249566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nout, &idxout));
1025d4fe737eSStefano Zampini   }
10269566063dSJacob Faibussowitsch   PetscCall(ISGlobalToLocalMappingApply(mapping, type, n, idxin, &nout, idxout));
10279566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(is, &idxin));
10289566063dSJacob Faibussowitsch   PetscCall(ISCreateGeneral(PETSC_COMM_SELF, nout, idxout, PETSC_OWN_POINTER, newis));
1029586b16e1SPierre Jolivet   if (type == IS_GTOLM_MASK) {
1030586b16e1SPierre Jolivet     PetscCall(ISGetBlockSize(is, &bs));
1031586b16e1SPierre Jolivet     PetscCall(ISSetBlockSize(*newis, bs));
1032586b16e1SPierre Jolivet   }
10333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1034d4fe737eSStefano Zampini }
1035d4fe737eSStefano Zampini 
10369d90f715SBarry Smith /*@
10379d90f715SBarry Smith   ISGlobalToLocalMappingApplyBlock - Provides the local block numbering for a list of integers
10389d90f715SBarry Smith   specified with a block global numbering.
10399d90f715SBarry Smith 
104020662ed9SBarry Smith   Not Collective
10419d90f715SBarry Smith 
10429d90f715SBarry Smith   Input Parameters:
10439d90f715SBarry Smith + mapping - mapping between local and global numbering
1044cab54364SBarry Smith . type    - `IS_GTOLM_MASK` - maps global indices with no local value to -1 in the output list (i.e., mask them)
1045cab54364SBarry Smith            `IS_GTOLM_DROP` - drops the indices with no local value from the output list
10469d90f715SBarry Smith . n       - number of global indices to map
10479d90f715SBarry Smith - idx     - global indices to map
10489d90f715SBarry Smith 
10499d90f715SBarry Smith   Output Parameters:
1050cab54364SBarry Smith + nout   - number of indices in output array (if type == `IS_GTOLM_MASK` then nout = n)
10519d90f715SBarry Smith - idxout - local index of each global index, one must pass in an array long enough
1052cab54364SBarry Smith              to hold all the indices. You can call `ISGlobalToLocalMappingApplyBlock()` with
10539d90f715SBarry Smith              idxout == NULL to determine the required length (returned in nout)
1054cab54364SBarry Smith              and then allocate the required space and call `ISGlobalToLocalMappingApplyBlock()`
10559d90f715SBarry Smith              a second time to set the values.
10569d90f715SBarry Smith 
1057cab54364SBarry Smith   Level: advanced
1058cab54364SBarry Smith 
10599d90f715SBarry Smith   Notes:
106020662ed9SBarry Smith   Either `nout` or `idxout` may be `NULL`. `idx` and `idxout` may be identical.
10619d90f715SBarry Smith 
106220662ed9SBarry Smith   For "small" problems when using `ISGlobalToLocalMappingApply()` and `ISGlobalToLocalMappingApplyBlock()`, the `ISLocalToGlobalMappingType` of
106320662ed9SBarry Smith   `ISLOCALTOGLOBALMAPPINGBASIC` will be used;
1064cab54364SBarry 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.
1065cab54364SBarry Smith   Use `ISLocalToGlobalMappingSetType()` or call `ISLocalToGlobalMappingSetFromOptions()` with the option -islocaltoglobalmapping_type <basic,hash> to control which is used.
10669d90f715SBarry Smith 
106738b5cf2dSJacob Faibussowitsch   Developer Notes:
106820662ed9SBarry Smith   The manual page states that `idx` and `idxout` may be identical but the calling
106920662ed9SBarry Smith   sequence declares `idx` as const so it cannot be the same as `idxout`.
10709d90f715SBarry Smith 
1071cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApply()`, `ISGlobalToLocalMappingApply()`, `ISLocalToGlobalMappingCreate()`,
1072db781477SPatrick Sanan           `ISLocalToGlobalMappingDestroy()`
10739d90f715SBarry Smith @*/
ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping,ISGlobalToLocalMappingMode type,PetscInt n,const PetscInt idx[],PetscInt * nout,PetscInt idxout[])1074d71ae5a4SJacob Faibussowitsch PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping mapping, ISGlobalToLocalMappingMode type, PetscInt n, const PetscInt idx[], PetscInt *nout, PetscInt idxout[])
1075d71ae5a4SJacob Faibussowitsch {
10763a40ed3dSBarry Smith   PetscFunctionBegin;
10770700a824SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
107848a46eb9SPierre Jolivet   if (!mapping->data) PetscCall(ISGlobalToLocalMappingSetUp(mapping));
1079dbbe0bcdSBarry Smith   PetscUseTypeMethod(mapping, globaltolocalmappingapplyblock, type, n, idx, nout, idxout);
10803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1081d4bb536fSBarry Smith }
108290f02eecSBarry Smith 
108389d82c54SBarry Smith /*@C
1084633354d9SStefano Zampini   ISLocalToGlobalMappingGetBlockInfo - Gets the neighbor information
108589d82c54SBarry Smith 
1086633354d9SStefano Zampini   Collective the first time it is called
108789d82c54SBarry Smith 
1088f899ff85SJose E. Roman   Input Parameter:
108989d82c54SBarry Smith . mapping - the mapping from local to global indexing
109089d82c54SBarry Smith 
1091d8d19677SJose E. Roman   Output Parameters:
1092633354d9SStefano Zampini + nproc    - number of processes that are connected to the calling process
1093633354d9SStefano Zampini . procs    - neighboring processes
1094633354d9SStefano Zampini . numprocs - number of block indices for each process
1095633354d9SStefano Zampini - indices  - block indices (in local numbering) shared with neighbors (sorted by global numbering)
109689d82c54SBarry Smith 
109789d82c54SBarry Smith   Level: advanced
109889d82c54SBarry Smith 
1099cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1100d4df40f3SStefano Zampini           `ISLocalToGlobalMappingRestoreBlockInfo()`, `ISLocalToGlobalMappingGetBlockMultiLeavesSF()`
110189d82c54SBarry Smith @*/
ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping,PetscInt * nproc,PetscInt * procs[],PetscInt * numprocs[],PetscInt ** indices[])1102d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[])
1103d71ae5a4SJacob Faibussowitsch {
1104268a049cSStefano Zampini   PetscFunctionBegin;
1105268a049cSStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1106633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingSetUpBlockInfo_Private(mapping));
1107633354d9SStefano Zampini   if (nproc) *nproc = mapping->info_nproc;
1108633354d9SStefano Zampini   if (procs) *procs = mapping->info_procs;
1109633354d9SStefano Zampini   if (numprocs) *numprocs = mapping->info_numprocs;
1110633354d9SStefano Zampini   if (indices) *indices = mapping->info_indices;
11113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1112268a049cSStefano Zampini }
1113268a049cSStefano Zampini 
1114633354d9SStefano Zampini /*@C
1115633354d9SStefano Zampini   ISLocalToGlobalMappingGetBlockNodeInfo - Gets the neighbor information for each local block index
1116633354d9SStefano Zampini 
1117633354d9SStefano Zampini   Collective the first time it is called
1118633354d9SStefano Zampini 
1119633354d9SStefano Zampini   Input Parameter:
1120633354d9SStefano Zampini . mapping - the mapping from local to global indexing
1121633354d9SStefano Zampini 
11229cde84edSJose E. Roman   Output Parameters:
1123633354d9SStefano Zampini + n       - number of local block nodes
1124633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local block node (including self)
1125633354d9SStefano Zampini - procs   - the processes' rank for each local block node (sorted, self is first)
1126633354d9SStefano Zampini 
1127633354d9SStefano Zampini   Level: advanced
1128633354d9SStefano Zampini 
1129633354d9SStefano Zampini   Notes:
1130633354d9SStefano Zampini   The user needs to call `ISLocalToGlobalMappingRestoreBlockNodeInfo()` when the data is no longer needed.
1131633354d9SStefano Zampini   The information returned by this function complements that of `ISLocalToGlobalMappingGetBlockInfo()`.
1132633354d9SStefano Zampini   The latter only provides local information, and the neighboring information
1133633354d9SStefano Zampini   cannot be inferred in the general case, unless the mapping is locally one-to-one on each process.
1134633354d9SStefano Zampini 
1135633354d9SStefano Zampini .seealso: `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1136633354d9SStefano Zampini           `ISLocalToGlobalMappingGetBlockInfo()`, `ISLocalToGlobalMappingRestoreBlockNodeInfo()`, `ISLocalToGlobalMappingGetNodeInfo()`
1137633354d9SStefano Zampini @*/
ISLocalToGlobalMappingGetBlockNodeInfo(ISLocalToGlobalMapping mapping,PetscInt * n,PetscInt * n_procs[],PetscInt ** procs[])1138633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingGetBlockNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[])
1139d71ae5a4SJacob Faibussowitsch {
1140633354d9SStefano Zampini   PetscFunctionBegin;
1141633354d9SStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1142633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingSetUpBlockInfo_Private(mapping));
1143633354d9SStefano Zampini   if (n) *n = mapping->n;
1144633354d9SStefano Zampini   if (n_procs) *n_procs = mapping->info_nodec;
1145633354d9SStefano Zampini   if (procs) *procs = mapping->info_nodei;
1146633354d9SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
1147633354d9SStefano Zampini }
1148633354d9SStefano Zampini 
1149633354d9SStefano Zampini /*@C
1150633354d9SStefano Zampini   ISLocalToGlobalMappingRestoreBlockNodeInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetBlockNodeInfo()`
1151633354d9SStefano Zampini 
1152633354d9SStefano Zampini   Not Collective
1153633354d9SStefano Zampini 
1154633354d9SStefano Zampini   Input Parameters:
1155633354d9SStefano Zampini + mapping - the mapping from local to global indexing
1156633354d9SStefano Zampini . n       - number of local block nodes
1157633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local block nodes (including self)
1158633354d9SStefano Zampini - procs   - the processes' rank for each local block node (sorted, self is first)
1159633354d9SStefano Zampini 
1160633354d9SStefano Zampini   Level: advanced
1161633354d9SStefano Zampini 
1162633354d9SStefano Zampini .seealso: `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1163633354d9SStefano Zampini           `ISLocalToGlobalMappingGetBlockNodeInfo()`
1164633354d9SStefano Zampini @*/
ISLocalToGlobalMappingRestoreBlockNodeInfo(ISLocalToGlobalMapping mapping,PetscInt * n,PetscInt * n_procs[],PetscInt ** procs[])1165633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingRestoreBlockNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[])
1166633354d9SStefano Zampini {
1167633354d9SStefano Zampini   PetscFunctionBegin;
1168633354d9SStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1169633354d9SStefano Zampini   if (n) *n = 0;
1170633354d9SStefano Zampini   if (n_procs) *n_procs = NULL;
1171633354d9SStefano Zampini   if (procs) *procs = NULL;
1172633354d9SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
1173633354d9SStefano Zampini }
1174633354d9SStefano Zampini 
1175d4df40f3SStefano Zampini /*@C
1176d4df40f3SStefano Zampini   ISLocalToGlobalMappingGetBlockMultiLeavesSF - Get the star-forest to communicate multi-leaf block data
1177d4df40f3SStefano Zampini 
1178d4df40f3SStefano Zampini   Collective the first time it is called
1179d4df40f3SStefano Zampini 
1180d4df40f3SStefano Zampini   Input Parameter:
1181d4df40f3SStefano Zampini . mapping - the mapping from local to global indexing
1182d4df40f3SStefano Zampini 
1183d4df40f3SStefano Zampini   Output Parameter:
1184d4df40f3SStefano Zampini . mlsf - the `PetscSF`
1185d4df40f3SStefano Zampini 
1186d4df40f3SStefano Zampini   Level: advanced
1187d4df40f3SStefano Zampini 
1188d4df40f3SStefano Zampini   Notes:
1189d4df40f3SStefano Zampini   The returned star forest is suitable to exchange local information with other processes sharing the same global block index.
1190d4df40f3SStefano Zampini   For example, suppose a mapping with two processes has been created with
1191d4df40f3SStefano Zampini .vb
1192d4df40f3SStefano Zampini     rank 0 global block indices: [0, 1, 2]
1193d4df40f3SStefano Zampini     rank 1 global block indices: [2, 3, 4]
1194d4df40f3SStefano Zampini .ve
1195d4df40f3SStefano Zampini   and we want to share the local information
1196d4df40f3SStefano Zampini .vb
1197d4df40f3SStefano Zampini     rank 0 data: [-1, -2, -3]
1198d4df40f3SStefano Zampini     rank 1 data: [1, 2, 3]
1199d4df40f3SStefano Zampini .ve
1200d4df40f3SStefano Zampini   then, the broadcasting action of `mlsf` will allow to collect
1201d4df40f3SStefano Zampini .vb
1202d4df40f3SStefano Zampini     rank 0 mlleafdata: [-1, -2, -3, 3]
1203d4df40f3SStefano Zampini     rank 1 mlleafdata: [-3, 3, 1, 2]
1204d4df40f3SStefano Zampini .ve
1205d4df40f3SStefano Zampini   Use ``ISLocalToGlobalMappingGetBlockNodeInfo()`` to index into the multi-leaf data.
1206d4df40f3SStefano Zampini 
1207d4df40f3SStefano Zampini .seealso: [](sec_scatter), `ISLocalToGlobalMappingGetBlockNodeInfo()`, `PetscSF`
1208d4df40f3SStefano Zampini @*/
ISLocalToGlobalMappingGetBlockMultiLeavesSF(ISLocalToGlobalMapping mapping,PetscSF * mlsf)1209d4df40f3SStefano Zampini PetscErrorCode ISLocalToGlobalMappingGetBlockMultiLeavesSF(ISLocalToGlobalMapping mapping, PetscSF *mlsf)
1210d4df40f3SStefano Zampini {
1211d4df40f3SStefano Zampini   PetscFunctionBegin;
1212d4df40f3SStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1213d4df40f3SStefano Zampini   PetscAssertPointer(mlsf, 2);
1214d4df40f3SStefano Zampini   PetscCall(ISLocalToGlobalMappingSetUpBlockInfo_Private(mapping));
1215d4df40f3SStefano Zampini   *mlsf = mapping->multileaves_sf;
1216d4df40f3SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
1217d4df40f3SStefano Zampini }
1218d4df40f3SStefano Zampini 
ISLocalToGlobalMappingSetUpBlockInfo_Private(ISLocalToGlobalMapping mapping)1219633354d9SStefano Zampini static PetscErrorCode ISLocalToGlobalMappingSetUpBlockInfo_Private(ISLocalToGlobalMapping mapping)
1220633354d9SStefano Zampini {
1221d4df40f3SStefano Zampini   PetscSF            sf, sf2, imsf, msf;
1222ce94432eSBarry Smith   MPI_Comm           comm;
1223633354d9SStefano Zampini   const PetscSFNode *sfnode;
1224633354d9SStefano Zampini   PetscSFNode       *newsfnode;
1225633354d9SStefano Zampini   PetscLayout        layout;
1226633354d9SStefano Zampini   PetscHMapI         neighs;
1227633354d9SStefano Zampini   PetscHashIter      iter;
1228633354d9SStefano Zampini   PetscBool          missing;
1229633354d9SStefano Zampini   const PetscInt    *gidxs, *rootdegree;
1230633354d9SStefano Zampini   PetscInt          *mask, *mrootdata, *leafdata, *newleafdata, *leafrd, *tmpg;
1231633354d9SStefano Zampini   PetscInt           nroots, nleaves, newnleaves, bs, i, j, m, mnroots, p;
1232633354d9SStefano Zampini   PetscMPIInt        rank, size;
123389d82c54SBarry Smith 
123489d82c54SBarry Smith   PetscFunctionBegin;
1235d4df40f3SStefano Zampini   if (mapping->multileaves_sf) PetscFunctionReturn(PETSC_SUCCESS);
12369566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)mapping, &comm));
12379566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
12389566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
1239633354d9SStefano Zampini 
1240633354d9SStefano Zampini   /* Get mapping indices */
1241633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingGetBlockSize(mapping, &bs));
1242633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingGetBlockIndices(mapping, &gidxs));
1243633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingGetSize(mapping, &nleaves));
1244633354d9SStefano Zampini   nleaves /= bs;
1245633354d9SStefano Zampini 
1246633354d9SStefano Zampini   /* Create layout for global indices */
1247633354d9SStefano Zampini   for (i = 0, m = 0; i < nleaves; i++) m = PetscMax(m, gidxs[i]);
1248462c564dSBarry Smith   PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &m, 1, MPIU_INT, MPI_MAX, comm));
1249633354d9SStefano Zampini   PetscCall(PetscLayoutCreate(comm, &layout));
1250633354d9SStefano Zampini   PetscCall(PetscLayoutSetSize(layout, m + 1));
1251633354d9SStefano Zampini   PetscCall(PetscLayoutSetUp(layout));
1252633354d9SStefano Zampini 
1253633354d9SStefano Zampini   /* Create SF to share global indices */
1254633354d9SStefano Zampini   PetscCall(PetscSFCreate(comm, &sf));
1255633354d9SStefano Zampini   PetscCall(PetscSFSetGraphLayout(sf, layout, nleaves, NULL, PETSC_OWN_POINTER, gidxs));
1256633354d9SStefano Zampini   PetscCall(PetscSFSetUp(sf));
1257633354d9SStefano Zampini   PetscCall(PetscLayoutDestroy(&layout));
1258633354d9SStefano Zampini 
1259633354d9SStefano Zampini   /* communicate root degree to leaves */
1260633354d9SStefano Zampini   PetscCall(PetscSFGetGraph(sf, &nroots, NULL, NULL, &sfnode));
1261633354d9SStefano Zampini   PetscCall(PetscSFComputeDegreeBegin(sf, &rootdegree));
1262633354d9SStefano Zampini   PetscCall(PetscSFComputeDegreeEnd(sf, &rootdegree));
1263633354d9SStefano Zampini   for (i = 0, mnroots = 0; i < nroots; i++) mnroots += rootdegree[i];
1264633354d9SStefano Zampini   PetscCall(PetscMalloc3(2 * PetscMax(mnroots, nroots), &mrootdata, 2 * nleaves, &leafdata, nleaves, &leafrd));
1265633354d9SStefano Zampini   for (i = 0, m = 0; i < nroots; i++) {
1266633354d9SStefano Zampini     mrootdata[2 * i + 0] = rootdegree[i];
1267633354d9SStefano Zampini     mrootdata[2 * i + 1] = m;
1268633354d9SStefano Zampini     m += rootdegree[i];
1269633354d9SStefano Zampini   }
1270633354d9SStefano Zampini   PetscCall(PetscSFBcastBegin(sf, MPIU_2INT, mrootdata, leafdata, MPI_REPLACE));
1271633354d9SStefano Zampini   PetscCall(PetscSFBcastEnd(sf, MPIU_2INT, mrootdata, leafdata, MPI_REPLACE));
1272633354d9SStefano Zampini 
1273633354d9SStefano Zampini   /* allocate enough space to store ranks */
1274633354d9SStefano Zampini   for (i = 0, newnleaves = 0; i < nleaves; i++) {
1275633354d9SStefano Zampini     newnleaves += leafdata[2 * i];
1276633354d9SStefano Zampini     leafrd[i] = leafdata[2 * i];
127724cf384cSBarry Smith   }
127824cf384cSBarry Smith 
1279633354d9SStefano Zampini   /* create new SF nodes to collect multi-root data at leaves */
1280633354d9SStefano Zampini   PetscCall(PetscMalloc1(newnleaves, &newsfnode));
1281633354d9SStefano Zampini   for (i = 0, m = 0; i < nleaves; i++) {
1282633354d9SStefano Zampini     for (j = 0; j < leafrd[i]; j++) {
1283633354d9SStefano Zampini       newsfnode[m].rank  = sfnode[i].rank;
1284633354d9SStefano Zampini       newsfnode[m].index = leafdata[2 * i + 1] + j;
1285633354d9SStefano Zampini       m++;
1286bc8ff85bSBarry Smith     }
1287bc8ff85bSBarry Smith   }
1288bc8ff85bSBarry Smith 
1289633354d9SStefano Zampini   /* gather ranks at multi roots */
1290633354d9SStefano Zampini   for (i = 0; i < mnroots; i++) mrootdata[i] = -1;
1291835f2295SStefano Zampini   for (i = 0; i < nleaves; i++) leafdata[i] = rank;
129230dcb7c9SBarry Smith 
1293633354d9SStefano Zampini   PetscCall(PetscSFGatherBegin(sf, MPIU_INT, leafdata, mrootdata));
1294633354d9SStefano Zampini   PetscCall(PetscSFGatherEnd(sf, MPIU_INT, leafdata, mrootdata));
12953677ff5aSBarry Smith 
1296d4df40f3SStefano Zampini   /* from multi-roots to multi-leaves */
1297d4df40f3SStefano Zampini   PetscCall(PetscSFCreate(comm, &sf2));
1298d4df40f3SStefano Zampini   PetscCall(PetscSFSetGraph(sf2, mnroots, newnleaves, NULL, PETSC_OWN_POINTER, newsfnode, PETSC_OWN_POINTER));
1299d4df40f3SStefano Zampini   PetscCall(PetscSFSetUp(sf2));
1300f6e5521dSKarl Rupp 
1301633354d9SStefano Zampini   /* broadcast multi-root data to multi-leaves */
1302633354d9SStefano Zampini   PetscCall(PetscMalloc1(newnleaves, &newleafdata));
1303d4df40f3SStefano Zampini   PetscCall(PetscSFBcastBegin(sf2, MPIU_INT, mrootdata, newleafdata, MPI_REPLACE));
1304d4df40f3SStefano Zampini   PetscCall(PetscSFBcastEnd(sf2, MPIU_INT, mrootdata, newleafdata, MPI_REPLACE));
1305f6e5521dSKarl Rupp 
1306633354d9SStefano Zampini   /* sort sharing ranks */
1307633354d9SStefano Zampini   for (i = 0, m = 0; i < nleaves; i++) {
1308633354d9SStefano Zampini     PetscCall(PetscSortInt(leafrd[i], newleafdata + m));
1309633354d9SStefano Zampini     m += leafrd[i];
131030dcb7c9SBarry Smith   }
131130dcb7c9SBarry Smith 
1312633354d9SStefano Zampini   /* Number of neighbors and their ranks */
1313633354d9SStefano Zampini   PetscCall(PetscHMapICreate(&neighs));
1314633354d9SStefano Zampini   for (i = 0; i < newnleaves; i++) PetscCall(PetscHMapIPut(neighs, newleafdata[i], &iter, &missing));
1315633354d9SStefano Zampini   PetscCall(PetscHMapIGetSize(neighs, &mapping->info_nproc));
1316*f1957bc3SPierre Jolivet   PetscCall(PetscMalloc1(mapping->info_nproc, &mapping->info_procs));
1317633354d9SStefano Zampini   PetscCall(PetscHMapIGetKeys(neighs, (i = 0, &i), mapping->info_procs));
1318633354d9SStefano Zampini   for (i = 0; i < mapping->info_nproc; i++) { /* put info for self first */
1319633354d9SStefano Zampini     if (mapping->info_procs[i] == rank) {
1320633354d9SStefano Zampini       PetscInt newr = mapping->info_procs[0];
1321d44834fbSBarry Smith 
1322633354d9SStefano Zampini       mapping->info_procs[0] = rank;
1323633354d9SStefano Zampini       mapping->info_procs[i] = newr;
132424cf384cSBarry Smith       break;
132524cf384cSBarry Smith     }
132624cf384cSBarry Smith   }
1327633354d9SStefano Zampini   if (mapping->info_nproc) PetscCall(PetscSortInt(mapping->info_nproc - 1, mapping->info_procs + 1));
1328633354d9SStefano Zampini   PetscCall(PetscHMapIDestroy(&neighs));
1329268a049cSStefano Zampini 
1330633354d9SStefano Zampini   /* collect info data */
1331d4df40f3SStefano Zampini   PetscCall(PetscMalloc1(mapping->info_nproc, &mapping->info_numprocs));
1332d4df40f3SStefano Zampini   PetscCall(PetscMalloc1(mapping->info_nproc, &mapping->info_indices));
1333d4df40f3SStefano Zampini   for (i = 0; i < mapping->info_nproc; i++) mapping->info_indices[i] = NULL;
1334633354d9SStefano Zampini 
1335633354d9SStefano Zampini   PetscCall(PetscMalloc1(nleaves, &mask));
1336633354d9SStefano Zampini   PetscCall(PetscMalloc1(nleaves, &tmpg));
1337633354d9SStefano Zampini   for (p = 0; p < mapping->info_nproc; p++) {
1338633354d9SStefano Zampini     PetscInt *tmp, trank = mapping->info_procs[p];
1339633354d9SStefano Zampini 
1340633354d9SStefano Zampini     PetscCall(PetscMemzero(mask, nleaves * sizeof(*mask)));
1341633354d9SStefano Zampini     for (i = 0, m = 0; i < nleaves; i++) {
1342633354d9SStefano Zampini       for (j = 0; j < leafrd[i]; j++) {
1343633354d9SStefano Zampini         if (newleafdata[m] == trank) mask[i]++;
1344633354d9SStefano Zampini         if (!p && newleafdata[m] != rank) mask[i]++;
1345633354d9SStefano Zampini         m++;
1346633354d9SStefano Zampini       }
1347633354d9SStefano Zampini     }
1348633354d9SStefano Zampini     for (i = 0, m = 0; i < nleaves; i++)
1349633354d9SStefano Zampini       if (mask[i] > (!p ? 1 : 0)) m++;
1350633354d9SStefano Zampini 
1351633354d9SStefano Zampini     PetscCall(PetscMalloc1(m, &tmp));
1352633354d9SStefano Zampini     for (i = 0, m = 0; i < nleaves; i++)
1353633354d9SStefano Zampini       if (mask[i] > (!p ? 1 : 0)) {
1354633354d9SStefano Zampini         tmp[m]  = i;
1355633354d9SStefano Zampini         tmpg[m] = gidxs[i];
1356633354d9SStefano Zampini         m++;
1357633354d9SStefano Zampini       }
1358633354d9SStefano Zampini     PetscCall(PetscSortIntWithArray(m, tmpg, tmp));
1359633354d9SStefano Zampini     mapping->info_indices[p]  = tmp;
1360633354d9SStefano Zampini     mapping->info_numprocs[p] = m;
1361633354d9SStefano Zampini   }
1362633354d9SStefano Zampini 
1363633354d9SStefano Zampini   /* Node info */
1364633354d9SStefano Zampini   PetscCall(PetscMalloc2(nleaves, &mapping->info_nodec, nleaves + 1, &mapping->info_nodei));
1365633354d9SStefano Zampini   PetscCall(PetscArraycpy(mapping->info_nodec, leafrd, nleaves));
1366633354d9SStefano Zampini   PetscCall(PetscMalloc1(newnleaves, &mapping->info_nodei[0]));
1367633354d9SStefano Zampini   for (i = 0; i < nleaves - 1; i++) mapping->info_nodei[i + 1] = mapping->info_nodei[i] + mapping->info_nodec[i];
1368633354d9SStefano Zampini   PetscCall(PetscArraycpy(mapping->info_nodei[0], newleafdata, newnleaves));
1369633354d9SStefano Zampini 
1370d4df40f3SStefano Zampini   /* Create SF from leaves to multi-leaves */
1371d4df40f3SStefano Zampini   PetscCall(PetscSFGetMultiSF(sf, &msf));
1372d4df40f3SStefano Zampini   PetscCall(PetscSFCreateInverseSF(msf, &imsf));
1373d4df40f3SStefano Zampini   PetscCall(PetscSFCompose(imsf, sf2, &mapping->multileaves_sf));
1374d4df40f3SStefano Zampini   PetscCall(PetscSFDestroy(&imsf));
1375d4df40f3SStefano Zampini   PetscCall(PetscSFDestroy(&sf));
1376d4df40f3SStefano Zampini   PetscCall(PetscSFDestroy(&sf2));
1377d4df40f3SStefano Zampini 
1378633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingRestoreBlockIndices(mapping, &gidxs));
1379633354d9SStefano Zampini   PetscCall(PetscFree(tmpg));
1380633354d9SStefano Zampini   PetscCall(PetscFree(mask));
1381633354d9SStefano Zampini   PetscCall(PetscFree3(mrootdata, leafdata, leafrd));
1382633354d9SStefano Zampini   PetscCall(PetscFree(newleafdata));
13833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
138489d82c54SBarry Smith }
138589d82c54SBarry Smith 
13866a818285SBarry Smith /*@C
1387cab54364SBarry Smith   ISLocalToGlobalMappingRestoreBlockInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetBlockInfo()`
13886a818285SBarry Smith 
1389633354d9SStefano Zampini   Not Collective
13906a818285SBarry Smith 
1391633354d9SStefano Zampini   Input Parameters:
1392633354d9SStefano Zampini + mapping  - the mapping from local to global indexing
1393633354d9SStefano Zampini . nproc    - number of processes that are connected to the calling process
1394633354d9SStefano Zampini . procs    - neighboring processes
1395633354d9SStefano Zampini . numprocs - number of block indices for each process
1396633354d9SStefano Zampini - indices  - block indices (in local numbering) shared with neighbors (sorted by global numbering)
13976a818285SBarry Smith 
13986a818285SBarry Smith   Level: advanced
13996a818285SBarry Smith 
1400cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1401db781477SPatrick Sanan           `ISLocalToGlobalMappingGetInfo()`
14026a818285SBarry Smith @*/
ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping,PetscInt * nproc,PetscInt * procs[],PetscInt * numprocs[],PetscInt ** indices[])1403d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[])
1404d71ae5a4SJacob Faibussowitsch {
14056a818285SBarry Smith   PetscFunctionBegin;
1406cbc1caf0SMatthew G. Knepley   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1407633354d9SStefano Zampini   if (nproc) *nproc = 0;
1408633354d9SStefano Zampini   if (procs) *procs = NULL;
1409633354d9SStefano Zampini   if (numprocs) *numprocs = NULL;
1410633354d9SStefano Zampini   if (indices) *indices = NULL;
14113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14126a818285SBarry Smith }
14136a818285SBarry Smith 
14146a818285SBarry Smith /*@C
1415633354d9SStefano Zampini   ISLocalToGlobalMappingGetInfo - Gets the neighbor information for each process
14166a818285SBarry Smith 
1417633354d9SStefano Zampini   Collective the first time it is called
14186a818285SBarry Smith 
1419f899ff85SJose E. Roman   Input Parameter:
14206a818285SBarry Smith . mapping - the mapping from local to global indexing
14216a818285SBarry Smith 
1422d8d19677SJose E. Roman   Output Parameters:
1423633354d9SStefano Zampini + nproc    - number of processes that are connected to the calling process
1424633354d9SStefano Zampini . procs    - neighboring processes
1425633354d9SStefano Zampini . numprocs - number of indices for each process
1426633354d9SStefano Zampini - indices  - indices (in local numbering) shared with neighbors (sorted by global numbering)
14276a818285SBarry Smith 
14286a818285SBarry Smith   Level: advanced
14296a818285SBarry Smith 
1430cab54364SBarry Smith   Note:
1431cab54364SBarry Smith   The user needs to call `ISLocalToGlobalMappingRestoreInfo()` when the data is no longer needed.
14321bd0b88eSStefano Zampini 
143338b5cf2dSJacob Faibussowitsch   Fortran Notes:
1434e33f79d8SJacob Faibussowitsch   There is no `ISLocalToGlobalMappingRestoreInfo()` in Fortran. You must make sure that
1435e33f79d8SJacob Faibussowitsch   `procs`[], `numprocs`[] and `indices`[][] are large enough arrays, either by allocating them
1436e33f79d8SJacob Faibussowitsch   dynamically or defining static ones large enough.
1437e33f79d8SJacob Faibussowitsch 
1438cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1439633354d9SStefano Zampini           `ISLocalToGlobalMappingRestoreInfo()`, `ISLocalToGlobalMappingGetNodeInfo()`
14406a818285SBarry Smith @*/
ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping,PetscInt * nproc,PetscInt * procs[],PetscInt * numprocs[],PetscInt ** indices[])1441d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[])
1442d71ae5a4SJacob Faibussowitsch {
1443633354d9SStefano Zampini   PetscInt **bindices = NULL, *bnumprocs = NULL, bs, i, j, k, n, *bprocs;
14446a818285SBarry Smith 
14456a818285SBarry Smith   PetscFunctionBegin;
14466a818285SBarry Smith   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
14478a1f772fSStefano Zampini   bs = mapping->bs;
1448633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingGetBlockInfo(mapping, &n, &bprocs, &bnumprocs, &bindices));
1449268a049cSStefano Zampini   if (bs > 1) { /* we need to expand the cached info */
1450633354d9SStefano Zampini     if (indices) PetscCall(PetscCalloc1(n, indices));
1451633354d9SStefano Zampini     if (numprocs) PetscCall(PetscCalloc1(n, numprocs));
1452633354d9SStefano Zampini     if (indices || numprocs) {
1453633354d9SStefano Zampini       for (i = 0; i < n; i++) {
1454633354d9SStefano Zampini         if (indices) {
14559566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(bs * bnumprocs[i], &(*indices)[i]));
1456268a049cSStefano Zampini           for (j = 0; j < bnumprocs[i]; j++) {
1457ad540459SPierre Jolivet             for (k = 0; k < bs; k++) (*indices)[i][j * bs + k] = bs * bindices[i][j] + k;
14586a818285SBarry Smith           }
14596a818285SBarry Smith         }
1460633354d9SStefano Zampini         if (numprocs) (*numprocs)[i] = bnumprocs[i] * bs;
1461633354d9SStefano Zampini       }
1462633354d9SStefano Zampini     }
1463268a049cSStefano Zampini   } else {
1464633354d9SStefano Zampini     if (numprocs) *numprocs = bnumprocs;
1465633354d9SStefano Zampini     if (indices) *indices = bindices;
14666a818285SBarry Smith   }
1467633354d9SStefano Zampini   if (nproc) *nproc = n;
1468633354d9SStefano Zampini   if (procs) *procs = bprocs;
14693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14706a818285SBarry Smith }
14716a818285SBarry Smith 
147207b52d57SBarry Smith /*@C
1473cab54364SBarry Smith   ISLocalToGlobalMappingRestoreInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetInfo()`
147489d82c54SBarry Smith 
1475633354d9SStefano Zampini   Not Collective
147607b52d57SBarry Smith 
1477633354d9SStefano Zampini   Input Parameters:
1478633354d9SStefano Zampini + mapping  - the mapping from local to global indexing
1479633354d9SStefano Zampini . nproc    - number of processes that are connected to the calling process
1480633354d9SStefano Zampini . procs    - neighboring processes
1481633354d9SStefano Zampini . numprocs - number of indices for each process
1482633354d9SStefano Zampini - indices  - indices (in local numbering) shared with neighbors (sorted by global numbering)
148307b52d57SBarry Smith 
148407b52d57SBarry Smith   Level: advanced
148507b52d57SBarry Smith 
1486cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1487db781477SPatrick Sanan           `ISLocalToGlobalMappingGetInfo()`
148807b52d57SBarry Smith @*/
ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping,PetscInt * nproc,PetscInt * procs[],PetscInt * numprocs[],PetscInt ** indices[])1489d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping mapping, PetscInt *nproc, PetscInt *procs[], PetscInt *numprocs[], PetscInt **indices[])
1490d71ae5a4SJacob Faibussowitsch {
149107b52d57SBarry Smith   PetscFunctionBegin;
1492633354d9SStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1493633354d9SStefano Zampini   if (mapping->bs > 1) {
1494633354d9SStefano Zampini     if (numprocs) PetscCall(PetscFree(*numprocs));
1495633354d9SStefano Zampini     if (indices) {
1496633354d9SStefano Zampini       if (*indices)
1497633354d9SStefano Zampini         for (PetscInt i = 0; i < *nproc; i++) PetscCall(PetscFree((*indices)[i]));
1498633354d9SStefano Zampini       PetscCall(PetscFree(*indices));
1499633354d9SStefano Zampini     }
1500633354d9SStefano Zampini   }
15013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
150207b52d57SBarry Smith }
150386994e45SJed Brown 
150486994e45SJed Brown /*@C
1505633354d9SStefano Zampini   ISLocalToGlobalMappingGetNodeInfo - Gets the neighbor information of local nodes
15061bd0b88eSStefano Zampini 
1507633354d9SStefano Zampini   Collective the first time it is called
15081bd0b88eSStefano Zampini 
1509f899ff85SJose E. Roman   Input Parameter:
15101bd0b88eSStefano Zampini . mapping - the mapping from local to global indexing
15111bd0b88eSStefano Zampini 
1512d8d19677SJose E. Roman   Output Parameters:
1513633354d9SStefano Zampini + n       - number of local nodes
1514633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local node (including self)
1515633354d9SStefano Zampini - procs   - the processes' rank for each local node (sorted, self is first)
15161bd0b88eSStefano Zampini 
15171bd0b88eSStefano Zampini   Level: advanced
15181bd0b88eSStefano Zampini 
1519cab54364SBarry Smith   Note:
1520633354d9SStefano Zampini   The user needs to call `ISLocalToGlobalMappingRestoreNodeInfo()` when the data is no longer needed.
15211bd0b88eSStefano Zampini 
1522cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1523633354d9SStefano Zampini           `ISLocalToGlobalMappingGetInfo()`, `ISLocalToGlobalMappingRestoreNodeInfo()`, `ISLocalToGlobalMappingGetBlockNodeInfo()`
15241bd0b88eSStefano Zampini @*/
ISLocalToGlobalMappingGetNodeInfo(ISLocalToGlobalMapping mapping,PetscInt * n,PetscInt * n_procs[],PetscInt ** procs[])1525633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingGetNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[])
1526d71ae5a4SJacob Faibussowitsch {
1527633354d9SStefano Zampini   PetscInt **bprocs = NULL, *bn_procs = NULL, bs, i, j, k, bn;
15281bd0b88eSStefano Zampini 
15291bd0b88eSStefano Zampini   PetscFunctionBegin;
15301bd0b88eSStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1531633354d9SStefano Zampini   bs = mapping->bs;
1532633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingGetBlockNodeInfo(mapping, &bn, &bn_procs, &bprocs));
1533633354d9SStefano Zampini   if (bs > 1) { /* we need to expand the cached info */
1534633354d9SStefano Zampini     PetscInt *tn_procs;
1535633354d9SStefano Zampini     PetscInt  c;
15361bd0b88eSStefano Zampini 
1537633354d9SStefano Zampini     PetscCall(PetscMalloc1(bn * bs, &tn_procs));
1538633354d9SStefano Zampini     for (i = 0, c = 0; i < bn; i++) {
1539633354d9SStefano Zampini       for (k = 0; k < bs; k++) tn_procs[i * bs + k] = bn_procs[i];
1540633354d9SStefano Zampini       c += bs * bn_procs[i];
1541633354d9SStefano Zampini     }
1542633354d9SStefano Zampini     if (n) *n = bn * bs;
1543633354d9SStefano Zampini     if (procs) {
1544633354d9SStefano Zampini       PetscInt **tprocs;
1545633354d9SStefano Zampini       PetscInt   tn = bn * bs;
15461bd0b88eSStefano Zampini 
1547633354d9SStefano Zampini       PetscCall(PetscMalloc1(tn, &tprocs));
1548633354d9SStefano Zampini       if (tn) PetscCall(PetscMalloc1(c, &tprocs[0]));
1549633354d9SStefano Zampini       for (i = 0; i < tn - 1; i++) tprocs[i + 1] = tprocs[i] + tn_procs[i];
1550633354d9SStefano Zampini       for (i = 0; i < bn; i++) {
1551633354d9SStefano Zampini         for (k = 0; k < bs; k++) {
1552633354d9SStefano Zampini           for (j = 0; j < bn_procs[i]; j++) tprocs[i * bs + k][j] = bprocs[i][j];
15531bd0b88eSStefano Zampini         }
15541bd0b88eSStefano Zampini       }
1555633354d9SStefano Zampini       *procs = tprocs;
15561bd0b88eSStefano Zampini     }
1557633354d9SStefano Zampini     if (n_procs) *n_procs = tn_procs;
1558633354d9SStefano Zampini     else PetscCall(PetscFree(tn_procs));
1559633354d9SStefano Zampini   } else {
1560633354d9SStefano Zampini     if (n) *n = bn;
1561633354d9SStefano Zampini     if (n_procs) *n_procs = bn_procs;
1562633354d9SStefano Zampini     if (procs) *procs = bprocs;
1563633354d9SStefano Zampini   }
15643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15651bd0b88eSStefano Zampini }
15661bd0b88eSStefano Zampini 
15671bd0b88eSStefano Zampini /*@C
1568cab54364SBarry Smith   ISLocalToGlobalMappingRestoreNodeInfo - Frees the memory allocated by `ISLocalToGlobalMappingGetNodeInfo()`
15691bd0b88eSStefano Zampini 
1570633354d9SStefano Zampini   Not Collective
15711bd0b88eSStefano Zampini 
1572633354d9SStefano Zampini   Input Parameters:
1573633354d9SStefano Zampini + mapping - the mapping from local to global indexing
1574633354d9SStefano Zampini . n       - number of local nodes
1575633354d9SStefano Zampini . n_procs - an array storing the number of processes for each local node (including self)
1576633354d9SStefano Zampini - procs   - the processes' rank for each local node (sorted, self is first)
15771bd0b88eSStefano Zampini 
15781bd0b88eSStefano Zampini   Level: advanced
15791bd0b88eSStefano Zampini 
1580cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingDestroy()`, `ISLocalToGlobalMappingCreateIS()`, `ISLocalToGlobalMappingCreate()`,
1581db781477SPatrick Sanan           `ISLocalToGlobalMappingGetInfo()`
15821bd0b88eSStefano Zampini @*/
ISLocalToGlobalMappingRestoreNodeInfo(ISLocalToGlobalMapping mapping,PetscInt * n,PetscInt * n_procs[],PetscInt ** procs[])1583633354d9SStefano Zampini PetscErrorCode ISLocalToGlobalMappingRestoreNodeInfo(ISLocalToGlobalMapping mapping, PetscInt *n, PetscInt *n_procs[], PetscInt **procs[])
1584d71ae5a4SJacob Faibussowitsch {
15851bd0b88eSStefano Zampini   PetscFunctionBegin;
15861bd0b88eSStefano Zampini   PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 1);
1587633354d9SStefano Zampini   if (mapping->bs > 1) {
1588633354d9SStefano Zampini     if (n_procs) PetscCall(PetscFree(*n_procs));
1589633354d9SStefano Zampini     if (procs) {
1590633354d9SStefano Zampini       if (*procs) PetscCall(PetscFree((*procs)[0]));
1591633354d9SStefano Zampini       PetscCall(PetscFree(*procs));
1592633354d9SStefano Zampini     }
1593633354d9SStefano Zampini   }
1594633354d9SStefano Zampini   PetscCall(ISLocalToGlobalMappingRestoreBlockNodeInfo(mapping, n, n_procs, procs));
15953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15961bd0b88eSStefano Zampini }
15971bd0b88eSStefano Zampini 
15981bd0b88eSStefano Zampini /*@C
1599107e9a97SBarry Smith   ISLocalToGlobalMappingGetIndices - Get global indices for every local point that is mapped
160086994e45SJed Brown 
160186994e45SJed Brown   Not Collective
160286994e45SJed Brown 
16034165533cSJose E. Roman   Input Parameter:
160486994e45SJed Brown . ltog - local to global mapping
160586994e45SJed Brown 
16064165533cSJose E. Roman   Output Parameter:
1607cab54364SBarry Smith . array - array of indices, the length of this array may be obtained with `ISLocalToGlobalMappingGetSize()`
160886994e45SJed Brown 
160986994e45SJed Brown   Level: advanced
161086994e45SJed Brown 
1611cab54364SBarry Smith   Note:
1612cab54364SBarry Smith   `ISLocalToGlobalMappingGetSize()` returns the length the this array
1613107e9a97SBarry Smith 
161420662ed9SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingRestoreIndices()`,
161520662ed9SBarry Smith           `ISLocalToGlobalMappingGetBlockIndices()`, `ISLocalToGlobalMappingRestoreBlockIndices()`
161686994e45SJed Brown @*/
ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog,const PetscInt * array[])1617cc4c1da9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping ltog, const PetscInt *array[])
1618d71ae5a4SJacob Faibussowitsch {
161986994e45SJed Brown   PetscFunctionBegin;
162086994e45SJed Brown   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
16214f572ea9SToby Isaac   PetscAssertPointer(array, 2);
162245b6f7e9SBarry Smith   if (ltog->bs == 1) {
162386994e45SJed Brown     *array = ltog->indices;
162445b6f7e9SBarry Smith   } else {
162545b6f7e9SBarry Smith     PetscInt       *jj, k, i, j, n = ltog->n, bs = ltog->bs;
162645b6f7e9SBarry Smith     const PetscInt *ii;
162745b6f7e9SBarry Smith 
16289566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(bs * n, &jj));
162945b6f7e9SBarry Smith     *array = jj;
163045b6f7e9SBarry Smith     k      = 0;
163145b6f7e9SBarry Smith     ii     = ltog->indices;
163245b6f7e9SBarry Smith     for (i = 0; i < n; i++)
16339371c9d4SSatish Balay       for (j = 0; j < bs; j++) jj[k++] = bs * ii[i] + j;
163445b6f7e9SBarry Smith   }
16353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
163686994e45SJed Brown }
163786994e45SJed Brown 
163886994e45SJed Brown /*@C
1639cab54364SBarry Smith   ISLocalToGlobalMappingRestoreIndices - Restore indices obtained with `ISLocalToGlobalMappingGetIndices()`
164086994e45SJed Brown 
164186994e45SJed Brown   Not Collective
164286994e45SJed Brown 
16434165533cSJose E. Roman   Input Parameters:
164486994e45SJed Brown + ltog  - local to global mapping
164586994e45SJed Brown - array - array of indices
164686994e45SJed Brown 
164786994e45SJed Brown   Level: advanced
164886994e45SJed Brown 
1649cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingGetIndices()`
165086994e45SJed Brown @*/
ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog,const PetscInt * array[])1651cc4c1da9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping ltog, const PetscInt *array[])
1652d71ae5a4SJacob Faibussowitsch {
165386994e45SJed Brown   PetscFunctionBegin;
165486994e45SJed Brown   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
16554f572ea9SToby Isaac   PetscAssertPointer(array, 2);
1656c9cc58a2SBarry Smith   PetscCheck(ltog->bs != 1 || *array == ltog->indices, PETSC_COMM_SELF, PETSC_ERR_ARG_BADPTR, "Trying to return mismatched pointer");
165748a46eb9SPierre Jolivet   if (ltog->bs > 1) PetscCall(PetscFree(*(void **)array));
16583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
165945b6f7e9SBarry Smith }
166045b6f7e9SBarry Smith 
166145b6f7e9SBarry Smith /*@C
1662ce78bad3SBarry Smith   ISLocalToGlobalMappingGetBlockIndices - Get global indices for every local block in a `ISLocalToGlobalMapping`
166345b6f7e9SBarry Smith 
166445b6f7e9SBarry Smith   Not Collective
166545b6f7e9SBarry Smith 
16664165533cSJose E. Roman   Input Parameter:
166745b6f7e9SBarry Smith . ltog - local to global mapping
166845b6f7e9SBarry Smith 
16694165533cSJose E. Roman   Output Parameter:
167045b6f7e9SBarry Smith . array - array of indices
167145b6f7e9SBarry Smith 
167245b6f7e9SBarry Smith   Level: advanced
167345b6f7e9SBarry Smith 
1674ce78bad3SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`,
1675ce78bad3SBarry Smith           `ISLocalToGlobalMappingRestoreBlockIndices()`
167645b6f7e9SBarry Smith @*/
ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt * array[])1677cc4c1da9SBarry Smith PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping ltog, const PetscInt *array[])
1678d71ae5a4SJacob Faibussowitsch {
167945b6f7e9SBarry Smith   PetscFunctionBegin;
168045b6f7e9SBarry Smith   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
16814f572ea9SToby Isaac   PetscAssertPointer(array, 2);
168245b6f7e9SBarry Smith   *array = ltog->indices;
16833ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
168445b6f7e9SBarry Smith }
168545b6f7e9SBarry Smith 
168645b6f7e9SBarry Smith /*@C
1687cab54364SBarry Smith   ISLocalToGlobalMappingRestoreBlockIndices - Restore indices obtained with `ISLocalToGlobalMappingGetBlockIndices()`
168845b6f7e9SBarry Smith 
168945b6f7e9SBarry Smith   Not Collective
169045b6f7e9SBarry Smith 
16914165533cSJose E. Roman   Input Parameters:
169245b6f7e9SBarry Smith + ltog  - local to global mapping
169345b6f7e9SBarry Smith - array - array of indices
169445b6f7e9SBarry Smith 
169545b6f7e9SBarry Smith   Level: advanced
169645b6f7e9SBarry Smith 
1697cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingApply()`, `ISLocalToGlobalMappingGetIndices()`
169845b6f7e9SBarry Smith @*/
ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog,const PetscInt * array[])1699cc4c1da9SBarry Smith PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping ltog, const PetscInt *array[])
1700d71ae5a4SJacob Faibussowitsch {
170145b6f7e9SBarry Smith   PetscFunctionBegin;
170245b6f7e9SBarry Smith   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
17034f572ea9SToby Isaac   PetscAssertPointer(array, 2);
170408401ef6SPierre Jolivet   PetscCheck(*array == ltog->indices, PETSC_COMM_SELF, PETSC_ERR_ARG_BADPTR, "Trying to return mismatched pointer");
17050298fd71SBarry Smith   *array = NULL;
17063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
170786994e45SJed Brown }
1708f7efa3c7SJed Brown 
1709cc4c1da9SBarry Smith /*@
1710f7efa3c7SJed Brown   ISLocalToGlobalMappingConcatenate - Create a new mapping that concatenates a list of mappings
1711f7efa3c7SJed Brown 
1712f7efa3c7SJed Brown   Not Collective
1713f7efa3c7SJed Brown 
17144165533cSJose E. Roman   Input Parameters:
1715f7efa3c7SJed Brown + comm  - communicator for the new mapping, must contain the communicator of every mapping to concatenate
1716f7efa3c7SJed Brown . n     - number of mappings to concatenate
1717f7efa3c7SJed Brown - ltogs - local to global mappings
1718f7efa3c7SJed Brown 
17194165533cSJose E. Roman   Output Parameter:
1720f7efa3c7SJed Brown . ltogcat - new mapping
1721f7efa3c7SJed Brown 
1722f7efa3c7SJed Brown   Level: advanced
1723f7efa3c7SJed Brown 
1724cab54364SBarry Smith   Note:
1725cab54364SBarry Smith   This currently always returns a mapping with block size of 1
1726cab54364SBarry Smith 
172738b5cf2dSJacob Faibussowitsch   Developer Notes:
1728cab54364SBarry Smith   If all the input mapping have the same block size we could easily handle that as a special case
1729cab54364SBarry Smith 
1730cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingCreate()`
1731f7efa3c7SJed Brown @*/
ISLocalToGlobalMappingConcatenate(MPI_Comm comm,PetscInt n,const ISLocalToGlobalMapping ltogs[],ISLocalToGlobalMapping * ltogcat)1732d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm comm, PetscInt n, const ISLocalToGlobalMapping ltogs[], ISLocalToGlobalMapping *ltogcat)
1733d71ae5a4SJacob Faibussowitsch {
1734f7efa3c7SJed Brown   PetscInt i, cnt, m, *idx;
1735f7efa3c7SJed Brown 
1736f7efa3c7SJed Brown   PetscFunctionBegin;
173708401ef6SPierre Jolivet   PetscCheck(n >= 0, comm, PETSC_ERR_ARG_OUTOFRANGE, "Must have a non-negative number of mappings, given %" PetscInt_FMT, n);
17384f572ea9SToby Isaac   if (n > 0) PetscAssertPointer(ltogs, 3);
1739f7efa3c7SJed Brown   for (i = 0; i < n; i++) PetscValidHeaderSpecific(ltogs[i], IS_LTOGM_CLASSID, 3);
17404f572ea9SToby Isaac   PetscAssertPointer(ltogcat, 4);
1741f7efa3c7SJed Brown   for (cnt = 0, i = 0; i < n; i++) {
17429566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetSize(ltogs[i], &m));
1743f7efa3c7SJed Brown     cnt += m;
1744f7efa3c7SJed Brown   }
17459566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(cnt, &idx));
1746f7efa3c7SJed Brown   for (cnt = 0, i = 0; i < n; i++) {
1747f7efa3c7SJed Brown     const PetscInt *subidx;
17489566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetSize(ltogs[i], &m));
17499566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetIndices(ltogs[i], &subidx));
17509566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(&idx[cnt], subidx, m));
17519566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingRestoreIndices(ltogs[i], &subidx));
1752f7efa3c7SJed Brown     cnt += m;
1753f7efa3c7SJed Brown   }
17549566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingCreate(comm, 1, cnt, idx, PETSC_OWN_POINTER, ltogcat));
17553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1756f7efa3c7SJed Brown }
175704a59952SBarry Smith 
1758413f72f0SBarry Smith /*MC
1759cab54364SBarry Smith       ISLOCALTOGLOBALMAPPINGBASIC - basic implementation of the `ISLocalToGlobalMapping` object. When `ISGlobalToLocalMappingApply()` is
1760413f72f0SBarry Smith                                     used this is good for only small and moderate size problems.
1761413f72f0SBarry Smith 
176220662ed9SBarry Smith    Options Database Key:
1763a2b725a8SWilliam Gropp .   -islocaltoglobalmapping_type basic - select this method
1764413f72f0SBarry Smith 
1765413f72f0SBarry Smith    Level: beginner
1766413f72f0SBarry Smith 
1767cab54364SBarry Smith    Developer Note:
1768cab54364SBarry Smith    This stores all the mapping information on each MPI rank.
1769cab54364SBarry Smith 
1770cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetType()`, `ISLOCALTOGLOBALMAPPINGHASH`
1771413f72f0SBarry Smith M*/
ISLocalToGlobalMappingCreate_Basic(ISLocalToGlobalMapping ltog)1772d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreate_Basic(ISLocalToGlobalMapping ltog)
1773d71ae5a4SJacob Faibussowitsch {
1774413f72f0SBarry Smith   PetscFunctionBegin;
1775413f72f0SBarry Smith   ltog->ops->globaltolocalmappingapply      = ISGlobalToLocalMappingApply_Basic;
1776413f72f0SBarry Smith   ltog->ops->globaltolocalmappingsetup      = ISGlobalToLocalMappingSetUp_Basic;
1777413f72f0SBarry Smith   ltog->ops->globaltolocalmappingapplyblock = ISGlobalToLocalMappingApplyBlock_Basic;
1778413f72f0SBarry Smith   ltog->ops->destroy                        = ISLocalToGlobalMappingDestroy_Basic;
17793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1780413f72f0SBarry Smith }
1781413f72f0SBarry Smith 
1782413f72f0SBarry Smith /*MC
1783cab54364SBarry Smith       ISLOCALTOGLOBALMAPPINGHASH - hash implementation of the `ISLocalToGlobalMapping` object. When `ISGlobalToLocalMappingApply()` is
1784ed56e8eaSBarry Smith                                     used this is good for large memory problems.
1785413f72f0SBarry Smith 
178620662ed9SBarry Smith    Options Database Key:
1787a2b725a8SWilliam Gropp .   -islocaltoglobalmapping_type hash - select this method
1788413f72f0SBarry Smith 
1789413f72f0SBarry Smith    Level: beginner
1790413f72f0SBarry Smith 
1791cab54364SBarry Smith    Note:
1792cab54364SBarry Smith     This is selected automatically for large problems if the user does not set the type.
1793cab54364SBarry Smith 
1794cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetType()`, `ISLOCALTOGLOBALMAPPINGBASIC`
1795413f72f0SBarry Smith M*/
ISLocalToGlobalMappingCreate_Hash(ISLocalToGlobalMapping ltog)1796d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreate_Hash(ISLocalToGlobalMapping ltog)
1797d71ae5a4SJacob Faibussowitsch {
1798413f72f0SBarry Smith   PetscFunctionBegin;
1799413f72f0SBarry Smith   ltog->ops->globaltolocalmappingapply      = ISGlobalToLocalMappingApply_Hash;
1800413f72f0SBarry Smith   ltog->ops->globaltolocalmappingsetup      = ISGlobalToLocalMappingSetUp_Hash;
1801413f72f0SBarry Smith   ltog->ops->globaltolocalmappingapplyblock = ISGlobalToLocalMappingApplyBlock_Hash;
1802413f72f0SBarry Smith   ltog->ops->destroy                        = ISLocalToGlobalMappingDestroy_Hash;
18033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1804413f72f0SBarry Smith }
1805413f72f0SBarry Smith 
1806413f72f0SBarry Smith /*@C
1807cab54364SBarry Smith   ISLocalToGlobalMappingRegister -  Registers a method for applying a global to local mapping with an `ISLocalToGlobalMapping`
1808413f72f0SBarry Smith 
1809cc4c1da9SBarry Smith   Not Collective, No Fortran Support
1810413f72f0SBarry Smith 
1811413f72f0SBarry Smith   Input Parameters:
1812413f72f0SBarry Smith + sname    - name of a new method
18132fe279fdSBarry Smith - function - routine to create method context
1814413f72f0SBarry Smith 
181538b5cf2dSJacob Faibussowitsch   Example Usage:
1816413f72f0SBarry Smith .vb
1817413f72f0SBarry Smith    ISLocalToGlobalMappingRegister("my_mapper", MyCreate);
1818413f72f0SBarry Smith .ve
1819413f72f0SBarry Smith 
1820ed56e8eaSBarry Smith   Then, your mapping can be chosen with the procedural interface via
1821b44f4de4SBarry Smith .vb
1822b44f4de4SBarry Smith   ISLocalToGlobalMappingSetType(ltog, "my_mapper")
1823b44f4de4SBarry Smith .ve
1824413f72f0SBarry Smith   or at runtime via the option
1825b44f4de4SBarry Smith .vb
1826b44f4de4SBarry Smith   -islocaltoglobalmapping_type my_mapper
1827b44f4de4SBarry Smith .ve
1828413f72f0SBarry Smith 
1829413f72f0SBarry Smith   Level: advanced
1830413f72f0SBarry Smith 
1831cab54364SBarry Smith   Note:
1832cab54364SBarry Smith   `ISLocalToGlobalMappingRegister()` may be called multiple times to add several user-defined mappings.
1833413f72f0SBarry Smith 
1834cab54364SBarry Smith .seealso: [](sec_scatter), `ISLocalToGlobalMappingRegisterAll()`, `ISLocalToGlobalMappingRegisterDestroy()`, `ISLOCALTOGLOBALMAPPINGBASIC`,
1835cab54364SBarry Smith           `ISLOCALTOGLOBALMAPPINGHASH`, `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingApply()`
1836413f72f0SBarry Smith @*/
ISLocalToGlobalMappingRegister(const char sname[],PetscErrorCode (* function)(ISLocalToGlobalMapping))1837d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRegister(const char sname[], PetscErrorCode (*function)(ISLocalToGlobalMapping))
1838d71ae5a4SJacob Faibussowitsch {
1839413f72f0SBarry Smith   PetscFunctionBegin;
18409566063dSJacob Faibussowitsch   PetscCall(ISInitializePackage());
18419566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&ISLocalToGlobalMappingList, sname, function));
18423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1843413f72f0SBarry Smith }
1844413f72f0SBarry Smith 
1845cc4c1da9SBarry Smith /*@
1846cab54364SBarry Smith   ISLocalToGlobalMappingSetType - Sets the implementation type `ISLocalToGlobalMapping` will use
1847413f72f0SBarry Smith 
1848c3339decSBarry Smith   Logically Collective
1849413f72f0SBarry Smith 
1850413f72f0SBarry Smith   Input Parameters:
1851cab54364SBarry Smith + ltog - the `ISLocalToGlobalMapping` object
1852413f72f0SBarry Smith - type - a known method
1853413f72f0SBarry Smith 
1854413f72f0SBarry Smith   Options Database Key:
1855cab54364SBarry Smith . -islocaltoglobalmapping_type  <method> - Sets the method; use -help for a list of available methods (for instance, basic or hash)
1856cab54364SBarry Smith 
1857cab54364SBarry Smith   Level: intermediate
1858413f72f0SBarry Smith 
1859413f72f0SBarry Smith   Notes:
186020662ed9SBarry Smith   See `ISLocalToGlobalMappingType` for available methods
1861413f72f0SBarry Smith 
1862cab54364SBarry Smith   Normally, it is best to use the `ISLocalToGlobalMappingSetFromOptions()` command and
1863cab54364SBarry Smith   then set the `ISLocalToGlobalMappingType` from the options database rather than by using
1864413f72f0SBarry Smith   this routine.
1865413f72f0SBarry Smith 
186638b5cf2dSJacob Faibussowitsch   Developer Notes:
1867cab54364SBarry Smith   `ISLocalToGlobalMappingRegister()` is used to add new types to `ISLocalToGlobalMappingList` from which they
1868cab54364SBarry Smith   are accessed by `ISLocalToGlobalMappingSetType()`.
1869413f72f0SBarry Smith 
187038b5cf2dSJacob Faibussowitsch .seealso: [](sec_scatter), `ISLocalToGlobalMappingType`, `ISLocalToGlobalMappingRegister()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingGetType()`
1871413f72f0SBarry Smith @*/
ISLocalToGlobalMappingSetType(ISLocalToGlobalMapping ltog,ISLocalToGlobalMappingType type)1872d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingSetType(ISLocalToGlobalMapping ltog, ISLocalToGlobalMappingType type)
1873d71ae5a4SJacob Faibussowitsch {
1874413f72f0SBarry Smith   PetscBool match;
18755f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(ISLocalToGlobalMapping) = NULL;
1876413f72f0SBarry Smith 
1877413f72f0SBarry Smith   PetscFunctionBegin;
1878413f72f0SBarry Smith   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
18794f572ea9SToby Isaac   if (type) PetscAssertPointer(type, 2);
1880413f72f0SBarry Smith 
18819566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)ltog, type, &match));
18823ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
1883413f72f0SBarry Smith 
1884a0d79125SStefano Zampini   /* L2G maps defer type setup at globaltolocal calls, allow passing NULL here */
1885a0d79125SStefano Zampini   if (type) {
18869566063dSJacob Faibussowitsch     PetscCall(PetscFunctionListFind(ISLocalToGlobalMappingList, type, &r));
1887a0d79125SStefano Zampini     PetscCheck(r, PetscObjectComm((PetscObject)ltog), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested ISLocalToGlobalMapping type %s", type);
1888a0d79125SStefano Zampini   }
1889413f72f0SBarry Smith   /* Destroy the previous private LTOG context */
1890dbbe0bcdSBarry Smith   PetscTryTypeMethod(ltog, destroy);
1891413f72f0SBarry Smith   ltog->ops->destroy = NULL;
1892dbbe0bcdSBarry Smith 
18939566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)ltog, type));
18949566063dSJacob Faibussowitsch   if (r) PetscCall((*r)(ltog));
18953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1896a0d79125SStefano Zampini }
1897a0d79125SStefano Zampini 
1898cc4c1da9SBarry Smith /*@
1899cab54364SBarry Smith   ISLocalToGlobalMappingGetType - Get the type of the `ISLocalToGlobalMapping`
1900a0d79125SStefano Zampini 
1901a0d79125SStefano Zampini   Not Collective
1902a0d79125SStefano Zampini 
1903a0d79125SStefano Zampini   Input Parameter:
1904cab54364SBarry Smith . ltog - the `ISLocalToGlobalMapping` object
1905a0d79125SStefano Zampini 
1906a0d79125SStefano Zampini   Output Parameter:
1907a0d79125SStefano Zampini . type - the type
1908a0d79125SStefano Zampini 
190949762cbcSSatish Balay   Level: intermediate
191049762cbcSSatish Balay 
191138b5cf2dSJacob Faibussowitsch .seealso: [](sec_scatter), `ISLocalToGlobalMappingType`, `ISLocalToGlobalMappingRegister()`, `ISLocalToGlobalMappingCreate()`, `ISLocalToGlobalMappingSetType()`
1912a0d79125SStefano Zampini @*/
ISLocalToGlobalMappingGetType(ISLocalToGlobalMapping ltog,ISLocalToGlobalMappingType * type)1913d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingGetType(ISLocalToGlobalMapping ltog, ISLocalToGlobalMappingType *type)
1914d71ae5a4SJacob Faibussowitsch {
1915a0d79125SStefano Zampini   PetscFunctionBegin;
1916a0d79125SStefano Zampini   PetscValidHeaderSpecific(ltog, IS_LTOGM_CLASSID, 1);
19174f572ea9SToby Isaac   PetscAssertPointer(type, 2);
1918a0d79125SStefano Zampini   *type = ((PetscObject)ltog)->type_name;
19193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1920413f72f0SBarry Smith }
1921413f72f0SBarry Smith 
1922413f72f0SBarry Smith PetscBool ISLocalToGlobalMappingRegisterAllCalled = PETSC_FALSE;
1923413f72f0SBarry Smith 
1924413f72f0SBarry Smith /*@C
1925cab54364SBarry Smith   ISLocalToGlobalMappingRegisterAll - Registers all of the local to global mapping components in the `IS` package.
1926413f72f0SBarry Smith 
1927413f72f0SBarry Smith   Not Collective
1928413f72f0SBarry Smith 
1929413f72f0SBarry Smith   Level: advanced
1930413f72f0SBarry Smith 
1931cab54364SBarry Smith .seealso: [](sec_scatter), `ISRegister()`, `ISLocalToGlobalRegister()`
1932413f72f0SBarry Smith @*/
ISLocalToGlobalMappingRegisterAll(void)1933d71ae5a4SJacob Faibussowitsch PetscErrorCode ISLocalToGlobalMappingRegisterAll(void)
1934d71ae5a4SJacob Faibussowitsch {
1935413f72f0SBarry Smith   PetscFunctionBegin;
19363ba16761SJacob Faibussowitsch   if (ISLocalToGlobalMappingRegisterAllCalled) PetscFunctionReturn(PETSC_SUCCESS);
1937413f72f0SBarry Smith   ISLocalToGlobalMappingRegisterAllCalled = PETSC_TRUE;
19389566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingRegister(ISLOCALTOGLOBALMAPPINGBASIC, ISLocalToGlobalMappingCreate_Basic));
19399566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingRegister(ISLOCALTOGLOBALMAPPINGHASH, ISLocalToGlobalMappingCreate_Hash));
19403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1941413f72f0SBarry Smith }
1942