xref: /petsc/src/dm/label/dmlabel.c (revision f1a722f8c411b335aaa5b04a3b4219fef8ff4c99)
15fdea053SToby Isaac #include <petscdm.h>
2c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h>   /*I      "petscdmlabel.h"   I*/
3ea844a1aSMatthew Knepley #include <petsc/private/sectionimpl.h>   /*I      "petscsection.h"   I*/
4c58f1c22SToby Isaac #include <petscsf.h>
5ea844a1aSMatthew Knepley #include <petscsection.h>
6c58f1c22SToby Isaac 
7c58f1c22SToby Isaac /*@C
8c58f1c22SToby Isaac   DMLabelCreate - Create a DMLabel object, which is a multimap
9c58f1c22SToby Isaac 
105b5e7992SMatthew G. Knepley   Collective
115b5e7992SMatthew G. Knepley 
12d67d17b1SMatthew G. Knepley   Input parameters:
13d67d17b1SMatthew G. Knepley + comm - The communicator, usually PETSC_COMM_SELF
14d67d17b1SMatthew G. Knepley - name - The label name
15c58f1c22SToby Isaac 
16c58f1c22SToby Isaac   Output parameter:
17c58f1c22SToby Isaac . label - The DMLabel
18c58f1c22SToby Isaac 
19c58f1c22SToby Isaac   Level: beginner
20c58f1c22SToby Isaac 
2105ab7a9fSVaclav Hapla   Notes:
2205ab7a9fSVaclav Hapla   The label name is actually usual PetscObject name.
2305ab7a9fSVaclav Hapla   One can get/set it with PetscObjectGetName()/PetscObjectSetName().
2405ab7a9fSVaclav Hapla 
25c58f1c22SToby Isaac .seealso: DMLabelDestroy()
26c58f1c22SToby Isaac @*/
27d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelCreate(MPI_Comm comm, const char name[], DMLabel *label)
28c58f1c22SToby Isaac {
29c58f1c22SToby Isaac   PetscErrorCode ierr;
30c58f1c22SToby Isaac 
31c58f1c22SToby Isaac   PetscFunctionBegin;
32064a246eSJacob Faibussowitsch   PetscValidPointer(label,3);
33d67d17b1SMatthew G. Knepley   ierr = DMInitializePackage();CHKERRQ(ierr);
34c58f1c22SToby Isaac 
35d67d17b1SMatthew G. Knepley   ierr = PetscHeaderCreate(*label,DMLABEL_CLASSID,"DMLabel","DMLabel","DM",comm,DMLabelDestroy,DMLabelView);CHKERRQ(ierr);
36d67d17b1SMatthew G. Knepley 
37c58f1c22SToby Isaac   (*label)->numStrata      = 0;
385aa44df4SToby Isaac   (*label)->defaultValue   = -1;
39c58f1c22SToby Isaac   (*label)->stratumValues  = NULL;
40ad8374ffSToby Isaac   (*label)->validIS        = NULL;
41c58f1c22SToby Isaac   (*label)->stratumSizes   = NULL;
42c58f1c22SToby Isaac   (*label)->points         = NULL;
43c58f1c22SToby Isaac   (*label)->ht             = NULL;
44c58f1c22SToby Isaac   (*label)->pStart         = -1;
45c58f1c22SToby Isaac   (*label)->pEnd           = -1;
46c58f1c22SToby Isaac   (*label)->bt             = NULL;
47b9907514SLisandro Dalcin   ierr = PetscHMapICreate(&(*label)->hmap);CHKERRQ(ierr);
48d67d17b1SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *label, name);CHKERRQ(ierr);
49c58f1c22SToby Isaac   PetscFunctionReturn(0);
50c58f1c22SToby Isaac }
51c58f1c22SToby Isaac 
52c58f1c22SToby Isaac /*
53c58f1c22SToby Isaac   DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format
54c58f1c22SToby Isaac 
555b5e7992SMatthew G. Knepley   Not collective
565b5e7992SMatthew G. Knepley 
57c58f1c22SToby Isaac   Input parameter:
58c58f1c22SToby Isaac + label - The DMLabel
59c58f1c22SToby Isaac - v - The stratum value
60c58f1c22SToby Isaac 
61c58f1c22SToby Isaac   Output parameter:
62c58f1c22SToby Isaac . label - The DMLabel with stratum in sorted list format
63c58f1c22SToby Isaac 
64c58f1c22SToby Isaac   Level: developer
65c58f1c22SToby Isaac 
66c58f1c22SToby Isaac .seealso: DMLabelCreate()
67c58f1c22SToby Isaac */
68c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v)
69c58f1c22SToby Isaac {
70277ea44aSLisandro Dalcin   IS             is;
71b9907514SLisandro Dalcin   PetscInt       off = 0, *pointArray, p;
72c58f1c22SToby Isaac   PetscErrorCode ierr;
73c58f1c22SToby Isaac 
74b9907514SLisandro Dalcin   if (PetscLikely(v >= 0 && v < label->numStrata) && label->validIS[v]) return 0;
75c58f1c22SToby Isaac   PetscFunctionBegin;
762c71b3e2SJacob Faibussowitsch   PetscCheckFalse(v < 0 || v >= label->numStrata,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %D in DMLabelMakeValid_Private", v);
77e8f14785SLisandro Dalcin   ierr = PetscHSetIGetSize(label->ht[v], &label->stratumSizes[v]);CHKERRQ(ierr);
78ad8374ffSToby Isaac   ierr = PetscMalloc1(label->stratumSizes[v], &pointArray);CHKERRQ(ierr);
79e8f14785SLisandro Dalcin   ierr = PetscHSetIGetElems(label->ht[v], &off, pointArray);CHKERRQ(ierr);
80b9907514SLisandro Dalcin   ierr = PetscHSetIClear(label->ht[v]);CHKERRQ(ierr);
81ad8374ffSToby Isaac   ierr = PetscSortInt(label->stratumSizes[v], pointArray);CHKERRQ(ierr);
82c58f1c22SToby Isaac   if (label->bt) {
83c58f1c22SToby Isaac     for (p = 0; p < label->stratumSizes[v]; ++p) {
84ad8374ffSToby Isaac       const PetscInt point = pointArray[p];
852c71b3e2SJacob Faibussowitsch       PetscCheckFalse((point < label->pStart) || (point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd);
86c58f1c22SToby Isaac       ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr);
87c58f1c22SToby Isaac     }
88c58f1c22SToby Isaac   }
89ba2698f1SMatthew G. Knepley   if (label->stratumSizes[v] > 0 && pointArray[label->stratumSizes[v]-1] == pointArray[0] + label->stratumSizes[v]-1) {
90ba2698f1SMatthew G. Knepley     ierr = ISCreateStride(PETSC_COMM_SELF, label->stratumSizes[v], pointArray[0], 1, &is);CHKERRQ(ierr);
91ba2698f1SMatthew G. Knepley     ierr = PetscFree(pointArray);CHKERRQ(ierr);
92ba2698f1SMatthew G. Knepley   } else {
93277ea44aSLisandro Dalcin     ierr = ISCreateGeneral(PETSC_COMM_SELF, label->stratumSizes[v], pointArray, PETSC_OWN_POINTER, &is);CHKERRQ(ierr);
94ba2698f1SMatthew G. Knepley   }
95277ea44aSLisandro Dalcin   ierr = PetscObjectSetName((PetscObject) is, "indices");CHKERRQ(ierr);
96277ea44aSLisandro Dalcin   label->points[v]  = is;
97ad8374ffSToby Isaac   label->validIS[v] = PETSC_TRUE;
98d67d17b1SMatthew G. Knepley   ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr);
99c58f1c22SToby Isaac   PetscFunctionReturn(0);
100c58f1c22SToby Isaac }
101c58f1c22SToby Isaac 
102c58f1c22SToby Isaac /*
103c58f1c22SToby Isaac   DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format
104c58f1c22SToby Isaac 
1055b5e7992SMatthew G. Knepley   Not collective
1065b5e7992SMatthew G. Knepley 
107c58f1c22SToby Isaac   Input parameter:
108c58f1c22SToby Isaac . label - The DMLabel
109c58f1c22SToby Isaac 
110c58f1c22SToby Isaac   Output parameter:
111c58f1c22SToby Isaac . label - The DMLabel with all strata in sorted list format
112c58f1c22SToby Isaac 
113c58f1c22SToby Isaac   Level: developer
114c58f1c22SToby Isaac 
115c58f1c22SToby Isaac .seealso: DMLabelCreate()
116c58f1c22SToby Isaac */
117c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label)
118c58f1c22SToby Isaac {
119c58f1c22SToby Isaac   PetscInt       v;
120c58f1c22SToby Isaac   PetscErrorCode ierr;
121c58f1c22SToby Isaac 
122c58f1c22SToby Isaac   PetscFunctionBegin;
123c58f1c22SToby Isaac   for (v = 0; v < label->numStrata; v++) {
124c58f1c22SToby Isaac     ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr);
125c58f1c22SToby Isaac   }
126c58f1c22SToby Isaac   PetscFunctionReturn(0);
127c58f1c22SToby Isaac }
128c58f1c22SToby Isaac 
129c58f1c22SToby Isaac /*
130c58f1c22SToby Isaac   DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format
131c58f1c22SToby Isaac 
1325b5e7992SMatthew G. Knepley   Not collective
1335b5e7992SMatthew G. Knepley 
134c58f1c22SToby Isaac   Input parameter:
135c58f1c22SToby Isaac + label - The DMLabel
136c58f1c22SToby Isaac - v - The stratum value
137c58f1c22SToby Isaac 
138c58f1c22SToby Isaac   Output parameter:
139c58f1c22SToby Isaac . label - The DMLabel with stratum in hash format
140c58f1c22SToby Isaac 
141c58f1c22SToby Isaac   Level: developer
142c58f1c22SToby Isaac 
143c58f1c22SToby Isaac .seealso: DMLabelCreate()
144c58f1c22SToby Isaac */
145c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v)
146c58f1c22SToby Isaac {
147c58f1c22SToby Isaac   PetscInt       p;
148ad8374ffSToby Isaac   const PetscInt *points;
149c58f1c22SToby Isaac   PetscErrorCode ierr;
150c58f1c22SToby Isaac 
151b9907514SLisandro Dalcin   if (PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) return 0;
152c58f1c22SToby Isaac   PetscFunctionBegin;
1532c71b3e2SJacob Faibussowitsch   PetscCheckFalse(v < 0 || v >= label->numStrata,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %D in DMLabelMakeInvalid_Private", v);
154ad8374ffSToby Isaac   if (label->points[v]) {
155ad8374ffSToby Isaac     ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr);
156e8f14785SLisandro Dalcin     for (p = 0; p < label->stratumSizes[v]; ++p) {
157e8f14785SLisandro Dalcin       ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr);
158e8f14785SLisandro Dalcin     }
159ad8374ffSToby Isaac     ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr);
160ad8374ffSToby Isaac     ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr);
161ad8374ffSToby Isaac   }
162ad8374ffSToby Isaac   label->validIS[v] = PETSC_FALSE;
163c58f1c22SToby Isaac   PetscFunctionReturn(0);
164c58f1c22SToby Isaac }
165c58f1c22SToby Isaac 
166b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD)
167b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16
168b9907514SLisandro Dalcin #endif
169b9907514SLisandro Dalcin 
1709fbee547SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index)
1710c3c4a36SLisandro Dalcin {
1720c3c4a36SLisandro Dalcin   PetscInt       v;
173b9907514SLisandro Dalcin   PetscErrorCode ierr;
1740e79e033SBarry Smith 
1750c3c4a36SLisandro Dalcin   PetscFunctionBegin;
1760e79e033SBarry Smith   *index = -1;
177b9907514SLisandro Dalcin   if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) {
178b9907514SLisandro Dalcin     for (v = 0; v < label->numStrata; ++v)
179b9907514SLisandro Dalcin       if (label->stratumValues[v] == value) {*index = v; break;}
180b9907514SLisandro Dalcin   } else {
181b9907514SLisandro Dalcin     ierr = PetscHMapIGet(label->hmap, value, index);CHKERRQ(ierr);
1820e79e033SBarry Smith   }
18376bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) { /* Check strata hash map consistency */
18490e9b2aeSLisandro Dalcin     PetscInt len, loc = -1;
18590e9b2aeSLisandro Dalcin     ierr = PetscHMapIGetSize(label->hmap, &len);CHKERRQ(ierr);
1862c71b3e2SJacob Faibussowitsch     PetscCheckFalse(len != label->numStrata,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size");
18790e9b2aeSLisandro Dalcin     if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) {
18890e9b2aeSLisandro Dalcin       ierr = PetscHMapIGet(label->hmap, value, &loc);CHKERRQ(ierr);
18990e9b2aeSLisandro Dalcin     } else {
19090e9b2aeSLisandro Dalcin       for (v = 0; v < label->numStrata; ++v)
19190e9b2aeSLisandro Dalcin         if (label->stratumValues[v] == value) {loc = v; break;}
19290e9b2aeSLisandro Dalcin     }
1932c71b3e2SJacob Faibussowitsch     PetscCheckFalse(loc != *index,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup");
19490e9b2aeSLisandro Dalcin   }
1950c3c4a36SLisandro Dalcin   PetscFunctionReturn(0);
1960c3c4a36SLisandro Dalcin }
1970c3c4a36SLisandro Dalcin 
1989fbee547SJacob Faibussowitsch static inline PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index)
199c58f1c22SToby Isaac {
200b9907514SLisandro Dalcin   PetscInt       v;
201b9907514SLisandro Dalcin   PetscInt      *tmpV;
202b9907514SLisandro Dalcin   PetscInt      *tmpS;
203b9907514SLisandro Dalcin   PetscHSetI    *tmpH, ht;
204b9907514SLisandro Dalcin   IS            *tmpP, is;
205c58f1c22SToby Isaac   PetscBool     *tmpB;
206b9907514SLisandro Dalcin   PetscHMapI     hmap = label->hmap;
207c58f1c22SToby Isaac   PetscErrorCode ierr;
208c58f1c22SToby Isaac 
209c58f1c22SToby Isaac   PetscFunctionBegin;
210b9907514SLisandro Dalcin   v    = label->numStrata;
211b9907514SLisandro Dalcin   tmpV = label->stratumValues;
212b9907514SLisandro Dalcin   tmpS = label->stratumSizes;
213b9907514SLisandro Dalcin   tmpH = label->ht;
214b9907514SLisandro Dalcin   tmpP = label->points;
215b9907514SLisandro Dalcin   tmpB = label->validIS;
2168e1f8cf0SLisandro Dalcin   { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free  */
2178e1f8cf0SLisandro Dalcin     PetscInt   *oldV = tmpV;
2188e1f8cf0SLisandro Dalcin     PetscInt   *oldS = tmpS;
2198e1f8cf0SLisandro Dalcin     PetscHSetI *oldH = tmpH;
2208e1f8cf0SLisandro Dalcin     IS         *oldP = tmpP;
2218e1f8cf0SLisandro Dalcin     PetscBool  *oldB = tmpB;
2228e1f8cf0SLisandro Dalcin     ierr = PetscMalloc((v+1)*sizeof(*tmpV), &tmpV);CHKERRQ(ierr);
2238e1f8cf0SLisandro Dalcin     ierr = PetscMalloc((v+1)*sizeof(*tmpS), &tmpS);CHKERRQ(ierr);
2248e1f8cf0SLisandro Dalcin     ierr = PetscMalloc((v+1)*sizeof(*tmpH), &tmpH);CHKERRQ(ierr);
2258e1f8cf0SLisandro Dalcin     ierr = PetscMalloc((v+1)*sizeof(*tmpP), &tmpP);CHKERRQ(ierr);
2268e1f8cf0SLisandro Dalcin     ierr = PetscMalloc((v+1)*sizeof(*tmpB), &tmpB);CHKERRQ(ierr);
227580bdb30SBarry Smith     ierr = PetscArraycpy(tmpV, oldV, v);CHKERRQ(ierr);
228580bdb30SBarry Smith     ierr = PetscArraycpy(tmpS, oldS, v);CHKERRQ(ierr);
229580bdb30SBarry Smith     ierr = PetscArraycpy(tmpH, oldH, v);CHKERRQ(ierr);
230580bdb30SBarry Smith     ierr = PetscArraycpy(tmpP, oldP, v);CHKERRQ(ierr);
231580bdb30SBarry Smith     ierr = PetscArraycpy(tmpB, oldB, v);CHKERRQ(ierr);
2328e1f8cf0SLisandro Dalcin     ierr = PetscFree(oldV);CHKERRQ(ierr);
2338e1f8cf0SLisandro Dalcin     ierr = PetscFree(oldS);CHKERRQ(ierr);
2348e1f8cf0SLisandro Dalcin     ierr = PetscFree(oldH);CHKERRQ(ierr);
2358e1f8cf0SLisandro Dalcin     ierr = PetscFree(oldP);CHKERRQ(ierr);
2368e1f8cf0SLisandro Dalcin     ierr = PetscFree(oldB);CHKERRQ(ierr);
2378e1f8cf0SLisandro Dalcin   }
238b9907514SLisandro Dalcin   label->numStrata     = v+1;
239c58f1c22SToby Isaac   label->stratumValues = tmpV;
240c58f1c22SToby Isaac   label->stratumSizes  = tmpS;
241c58f1c22SToby Isaac   label->ht            = tmpH;
242c58f1c22SToby Isaac   label->points        = tmpP;
243ad8374ffSToby Isaac   label->validIS       = tmpB;
244b9907514SLisandro Dalcin   ierr = PetscHSetICreate(&ht);CHKERRQ(ierr);
245b9907514SLisandro Dalcin   ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is);CHKERRQ(ierr);
246b9907514SLisandro Dalcin   ierr = PetscHMapISet(hmap, value, v);CHKERRQ(ierr);
247b9907514SLisandro Dalcin   tmpV[v] = value;
248b9907514SLisandro Dalcin   tmpS[v] = 0;
249b9907514SLisandro Dalcin   tmpH[v] = ht;
250b9907514SLisandro Dalcin   tmpP[v] = is;
251b9907514SLisandro Dalcin   tmpB[v] = PETSC_TRUE;
252277ea44aSLisandro Dalcin   ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr);
2530c3c4a36SLisandro Dalcin   *index = v;
2540c3c4a36SLisandro Dalcin   PetscFunctionReturn(0);
2550c3c4a36SLisandro Dalcin }
2560c3c4a36SLisandro Dalcin 
2579fbee547SJacob Faibussowitsch static inline PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index)
258b9907514SLisandro Dalcin {
259b9907514SLisandro Dalcin   PetscErrorCode ierr;
260b9907514SLisandro Dalcin   PetscFunctionBegin;
261b9907514SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, index);CHKERRQ(ierr);
262b9907514SLisandro Dalcin   if (*index < 0) {ierr = DMLabelNewStratum(label, value, index);CHKERRQ(ierr);}
263b9907514SLisandro Dalcin   PetscFunctionReturn(0);
264b9907514SLisandro Dalcin }
265b9907514SLisandro Dalcin 
2669fbee547SJacob Faibussowitsch static inline PetscErrorCode DMLabelGetStratumSize_Private(DMLabel label, PetscInt v, PetscInt *size)
2679e63cc69SVaclav Hapla {
2689e63cc69SVaclav Hapla   PetscErrorCode ierr;
2699e63cc69SVaclav Hapla 
2709e63cc69SVaclav Hapla   PetscFunctionBegin;
2719e63cc69SVaclav Hapla   *size = 0;
2729e63cc69SVaclav Hapla   if (v < 0) PetscFunctionReturn(0);
2739e63cc69SVaclav Hapla   if (label->validIS[v]) {
2749e63cc69SVaclav Hapla     *size = label->stratumSizes[v];
2759e63cc69SVaclav Hapla   } else {
2769e63cc69SVaclav Hapla     ierr = PetscHSetIGetSize(label->ht[v], size);CHKERRQ(ierr);
2779e63cc69SVaclav Hapla   }
2789e63cc69SVaclav Hapla   PetscFunctionReturn(0);
2799e63cc69SVaclav Hapla }
2809e63cc69SVaclav Hapla 
281b9907514SLisandro Dalcin /*@
282b9907514SLisandro Dalcin   DMLabelAddStratum - Adds a new stratum value in a DMLabel
283b9907514SLisandro Dalcin 
284d8d19677SJose E. Roman   Input Parameters:
285b9907514SLisandro Dalcin + label - The DMLabel
286b9907514SLisandro Dalcin - value - The stratum value
287b9907514SLisandro Dalcin 
288b9907514SLisandro Dalcin   Level: beginner
289b9907514SLisandro Dalcin 
290b9907514SLisandro Dalcin .seealso:  DMLabelCreate(), DMLabelDestroy()
291b9907514SLisandro Dalcin @*/
2920c3c4a36SLisandro Dalcin PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value)
2930c3c4a36SLisandro Dalcin {
2940c3c4a36SLisandro Dalcin   PetscInt       v;
2950c3c4a36SLisandro Dalcin   PetscErrorCode ierr;
2960c3c4a36SLisandro Dalcin 
2970c3c4a36SLisandro Dalcin   PetscFunctionBegin;
298d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
299b9907514SLisandro Dalcin   ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr);
300b9907514SLisandro Dalcin   PetscFunctionReturn(0);
301b9907514SLisandro Dalcin }
302b9907514SLisandro Dalcin 
303b9907514SLisandro Dalcin /*@
304b9907514SLisandro Dalcin   DMLabelAddStrata - Adds new stratum values in a DMLabel
305b9907514SLisandro Dalcin 
3065b5e7992SMatthew G. Knepley   Not collective
3075b5e7992SMatthew G. Knepley 
308d8d19677SJose E. Roman   Input Parameters:
309b9907514SLisandro Dalcin + label - The DMLabel
310b9907514SLisandro Dalcin . numStrata - The number of stratum values
311b9907514SLisandro Dalcin - stratumValues - The stratum values
312b9907514SLisandro Dalcin 
313b9907514SLisandro Dalcin   Level: beginner
314b9907514SLisandro Dalcin 
315b9907514SLisandro Dalcin .seealso:  DMLabelCreate(), DMLabelDestroy()
316b9907514SLisandro Dalcin @*/
317b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[])
318b9907514SLisandro Dalcin {
319b9907514SLisandro Dalcin   PetscInt       *values, v;
320b9907514SLisandro Dalcin   PetscErrorCode ierr;
321b9907514SLisandro Dalcin 
322b9907514SLisandro Dalcin   PetscFunctionBegin;
323b9907514SLisandro Dalcin   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
324b9907514SLisandro Dalcin   if (numStrata) PetscValidIntPointer(stratumValues, 3);
325b9907514SLisandro Dalcin   ierr = PetscMalloc1(numStrata, &values);CHKERRQ(ierr);
326580bdb30SBarry Smith   ierr = PetscArraycpy(values, stratumValues, numStrata);CHKERRQ(ierr);
327b9907514SLisandro Dalcin   ierr = PetscSortRemoveDupsInt(&numStrata, values);CHKERRQ(ierr);
328b9907514SLisandro Dalcin   if (!label->numStrata) { /* Fast preallocation */
329b9907514SLisandro Dalcin     PetscInt   *tmpV;
330b9907514SLisandro Dalcin     PetscInt   *tmpS;
331b9907514SLisandro Dalcin     PetscHSetI *tmpH, ht;
332b9907514SLisandro Dalcin     IS         *tmpP, is;
333b9907514SLisandro Dalcin     PetscBool  *tmpB;
334b9907514SLisandro Dalcin     PetscHMapI  hmap = label->hmap;
335b9907514SLisandro Dalcin 
336b9907514SLisandro Dalcin     ierr = PetscMalloc1(numStrata, &tmpV);CHKERRQ(ierr);
337b9907514SLisandro Dalcin     ierr = PetscMalloc1(numStrata, &tmpS);CHKERRQ(ierr);
338b9907514SLisandro Dalcin     ierr = PetscMalloc1(numStrata, &tmpH);CHKERRQ(ierr);
339b9907514SLisandro Dalcin     ierr = PetscMalloc1(numStrata, &tmpP);CHKERRQ(ierr);
340b9907514SLisandro Dalcin     ierr = PetscMalloc1(numStrata, &tmpB);CHKERRQ(ierr);
341b9907514SLisandro Dalcin     label->numStrata     = numStrata;
342b9907514SLisandro Dalcin     label->stratumValues = tmpV;
343b9907514SLisandro Dalcin     label->stratumSizes  = tmpS;
344b9907514SLisandro Dalcin     label->ht            = tmpH;
345b9907514SLisandro Dalcin     label->points        = tmpP;
346b9907514SLisandro Dalcin     label->validIS       = tmpB;
347b9907514SLisandro Dalcin     for (v = 0; v < numStrata; ++v) {
348b9907514SLisandro Dalcin       ierr = PetscHSetICreate(&ht);CHKERRQ(ierr);
349b9907514SLisandro Dalcin       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is);CHKERRQ(ierr);
350b9907514SLisandro Dalcin       ierr = PetscHMapISet(hmap, values[v], v);CHKERRQ(ierr);
351b9907514SLisandro Dalcin       tmpV[v] = values[v];
352b9907514SLisandro Dalcin       tmpS[v] = 0;
353b9907514SLisandro Dalcin       tmpH[v] = ht;
354b9907514SLisandro Dalcin       tmpP[v] = is;
355b9907514SLisandro Dalcin       tmpB[v] = PETSC_TRUE;
356b9907514SLisandro Dalcin     }
357277ea44aSLisandro Dalcin     ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr);
358b9907514SLisandro Dalcin   } else {
359b9907514SLisandro Dalcin     for (v = 0; v < numStrata; ++v) {
360b9907514SLisandro Dalcin       ierr = DMLabelAddStratum(label, values[v]);CHKERRQ(ierr);
361b9907514SLisandro Dalcin     }
362b9907514SLisandro Dalcin   }
363b9907514SLisandro Dalcin   ierr = PetscFree(values);CHKERRQ(ierr);
364b9907514SLisandro Dalcin   PetscFunctionReturn(0);
365b9907514SLisandro Dalcin }
366b9907514SLisandro Dalcin 
367b9907514SLisandro Dalcin /*@
368b9907514SLisandro Dalcin   DMLabelAddStrataIS - Adds new stratum values in a DMLabel
369b9907514SLisandro Dalcin 
3705b5e7992SMatthew G. Knepley   Not collective
3715b5e7992SMatthew G. Knepley 
372d8d19677SJose E. Roman   Input Parameters:
373b9907514SLisandro Dalcin + label - The DMLabel
374b9907514SLisandro Dalcin - valueIS - Index set with stratum values
375b9907514SLisandro Dalcin 
376b9907514SLisandro Dalcin   Level: beginner
377b9907514SLisandro Dalcin 
378b9907514SLisandro Dalcin .seealso:  DMLabelCreate(), DMLabelDestroy()
379b9907514SLisandro Dalcin @*/
380b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS)
381b9907514SLisandro Dalcin {
382b9907514SLisandro Dalcin   PetscInt       numStrata;
383b9907514SLisandro Dalcin   const PetscInt *stratumValues;
384b9907514SLisandro Dalcin   PetscErrorCode ierr;
385b9907514SLisandro Dalcin 
386b9907514SLisandro Dalcin   PetscFunctionBegin;
387b9907514SLisandro Dalcin   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
388b9907514SLisandro Dalcin   PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2);
389b9907514SLisandro Dalcin   ierr = ISGetLocalSize(valueIS, &numStrata);CHKERRQ(ierr);
390b9907514SLisandro Dalcin   ierr = ISGetIndices(valueIS, &stratumValues);CHKERRQ(ierr);
391b9907514SLisandro Dalcin   ierr = DMLabelAddStrata(label, numStrata, stratumValues);CHKERRQ(ierr);
392c58f1c22SToby Isaac   PetscFunctionReturn(0);
393c58f1c22SToby Isaac }
394c58f1c22SToby Isaac 
395c58f1c22SToby Isaac static PetscErrorCode DMLabelView_Ascii(DMLabel label, PetscViewer viewer)
396c58f1c22SToby Isaac {
397c58f1c22SToby Isaac   PetscInt       v;
398c58f1c22SToby Isaac   PetscMPIInt    rank;
399c58f1c22SToby Isaac   PetscErrorCode ierr;
400c58f1c22SToby Isaac 
401c58f1c22SToby Isaac   PetscFunctionBegin;
402ffc4695bSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);CHKERRMPI(ierr);
403c58f1c22SToby Isaac   ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
404c58f1c22SToby Isaac   if (label) {
405d67d17b1SMatthew G. Knepley     const char *name;
406d67d17b1SMatthew G. Knepley 
407d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr);
408d67d17b1SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name);CHKERRQ(ierr);
409c58f1c22SToby Isaac     if (label->bt) {ierr = PetscViewerASCIIPrintf(viewer, "  Index has been calculated in [%D, %D)\n", label->pStart, label->pEnd);CHKERRQ(ierr);}
410c58f1c22SToby Isaac     for (v = 0; v < label->numStrata; ++v) {
411c58f1c22SToby Isaac       const PetscInt value = label->stratumValues[v];
412ad8374ffSToby Isaac       const PetscInt *points;
413c58f1c22SToby Isaac       PetscInt       p;
414c58f1c22SToby Isaac 
415ad8374ffSToby Isaac       ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr);
416c58f1c22SToby Isaac       for (p = 0; p < label->stratumSizes[v]; ++p) {
417ad8374ffSToby Isaac         ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D (%D)\n", rank, points[p], value);CHKERRQ(ierr);
418c58f1c22SToby Isaac       }
419ad8374ffSToby Isaac       ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr);
420c58f1c22SToby Isaac     }
421c58f1c22SToby Isaac   }
422c58f1c22SToby Isaac   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
423c58f1c22SToby Isaac   ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
424c58f1c22SToby Isaac   PetscFunctionReturn(0);
425c58f1c22SToby Isaac }
426c58f1c22SToby Isaac 
427c58f1c22SToby Isaac /*@C
428c58f1c22SToby Isaac   DMLabelView - View the label
429c58f1c22SToby Isaac 
4305b5e7992SMatthew G. Knepley   Collective on viewer
4315b5e7992SMatthew G. Knepley 
432c58f1c22SToby Isaac   Input Parameters:
433c58f1c22SToby Isaac + label - The DMLabel
434c58f1c22SToby Isaac - viewer - The PetscViewer
435c58f1c22SToby Isaac 
436c58f1c22SToby Isaac   Level: intermediate
437c58f1c22SToby Isaac 
438c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelDestroy()
439c58f1c22SToby Isaac @*/
440c58f1c22SToby Isaac PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer)
441c58f1c22SToby Isaac {
442c58f1c22SToby Isaac   PetscBool      iascii;
443c58f1c22SToby Isaac   PetscErrorCode ierr;
444c58f1c22SToby Isaac 
445c58f1c22SToby Isaac   PetscFunctionBegin;
446d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
447b9907514SLisandro Dalcin   if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer);CHKERRQ(ierr);}
448c58f1c22SToby Isaac   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
449c58f1c22SToby Isaac   if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);}
450c58f1c22SToby Isaac   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
451c58f1c22SToby Isaac   if (iascii) {
452c58f1c22SToby Isaac     ierr = DMLabelView_Ascii(label, viewer);CHKERRQ(ierr);
453c58f1c22SToby Isaac   }
454c58f1c22SToby Isaac   PetscFunctionReturn(0);
455c58f1c22SToby Isaac }
456c58f1c22SToby Isaac 
45784f0b6dfSMatthew G. Knepley /*@
458d67d17b1SMatthew G. Knepley   DMLabelReset - Destroys internal data structures in a DMLabel
459d67d17b1SMatthew G. Knepley 
4605b5e7992SMatthew G. Knepley   Not collective
4615b5e7992SMatthew G. Knepley 
462d67d17b1SMatthew G. Knepley   Input Parameter:
463d67d17b1SMatthew G. Knepley . label - The DMLabel
464d67d17b1SMatthew G. Knepley 
465d67d17b1SMatthew G. Knepley   Level: beginner
466d67d17b1SMatthew G. Knepley 
467d67d17b1SMatthew G. Knepley .seealso: DMLabelDestroy(), DMLabelCreate()
468d67d17b1SMatthew G. Knepley @*/
469d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelReset(DMLabel label)
470d67d17b1SMatthew G. Knepley {
471d67d17b1SMatthew G. Knepley   PetscInt       v;
472d67d17b1SMatthew G. Knepley   PetscErrorCode ierr;
473d67d17b1SMatthew G. Knepley 
474d67d17b1SMatthew G. Knepley   PetscFunctionBegin;
475d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
476d67d17b1SMatthew G. Knepley   for (v = 0; v < label->numStrata; ++v) {
477d67d17b1SMatthew G. Knepley     ierr = PetscHSetIDestroy(&label->ht[v]);CHKERRQ(ierr);
478d67d17b1SMatthew G. Knepley     ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr);
479d67d17b1SMatthew G. Knepley   }
480b9907514SLisandro Dalcin   label->numStrata = 0;
481b9907514SLisandro Dalcin   ierr = PetscFree(label->stratumValues);CHKERRQ(ierr);
482b9907514SLisandro Dalcin   ierr = PetscFree(label->stratumSizes);CHKERRQ(ierr);
483d67d17b1SMatthew G. Knepley   ierr = PetscFree(label->ht);CHKERRQ(ierr);
484d67d17b1SMatthew G. Knepley   ierr = PetscFree(label->points);CHKERRQ(ierr);
485d67d17b1SMatthew G. Knepley   ierr = PetscFree(label->validIS);CHKERRQ(ierr);
486f9244615SMatthew G. Knepley   label->stratumValues = NULL;
487f9244615SMatthew G. Knepley   label->stratumSizes  = NULL;
488f9244615SMatthew G. Knepley   label->ht            = NULL;
489f9244615SMatthew G. Knepley   label->points        = NULL;
490f9244615SMatthew G. Knepley   label->validIS       = NULL;
491b9907514SLisandro Dalcin   ierr = PetscHMapIReset(label->hmap);CHKERRQ(ierr);
492b9907514SLisandro Dalcin   label->pStart = -1;
493b9907514SLisandro Dalcin   label->pEnd   = -1;
494d67d17b1SMatthew G. Knepley   ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr);
495d67d17b1SMatthew G. Knepley   PetscFunctionReturn(0);
496d67d17b1SMatthew G. Knepley }
497d67d17b1SMatthew G. Knepley 
498d67d17b1SMatthew G. Knepley /*@
49984f0b6dfSMatthew G. Knepley   DMLabelDestroy - Destroys a DMLabel
50084f0b6dfSMatthew G. Knepley 
5015b5e7992SMatthew G. Knepley   Collective on label
5025b5e7992SMatthew G. Knepley 
50384f0b6dfSMatthew G. Knepley   Input Parameter:
50484f0b6dfSMatthew G. Knepley . label - The DMLabel
50584f0b6dfSMatthew G. Knepley 
50684f0b6dfSMatthew G. Knepley   Level: beginner
50784f0b6dfSMatthew G. Knepley 
508d67d17b1SMatthew G. Knepley .seealso: DMLabelReset(), DMLabelCreate()
50984f0b6dfSMatthew G. Knepley @*/
510c58f1c22SToby Isaac PetscErrorCode DMLabelDestroy(DMLabel *label)
511c58f1c22SToby Isaac {
512c58f1c22SToby Isaac   PetscErrorCode ierr;
513c58f1c22SToby Isaac 
514c58f1c22SToby Isaac   PetscFunctionBegin;
515d67d17b1SMatthew G. Knepley   if (!*label) PetscFunctionReturn(0);
516d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific((*label),DMLABEL_CLASSID,1);
517b9907514SLisandro Dalcin   if (--((PetscObject)(*label))->refct > 0) {*label = NULL; PetscFunctionReturn(0);}
518d67d17b1SMatthew G. Knepley   ierr = DMLabelReset(*label);CHKERRQ(ierr);
519b9907514SLisandro Dalcin   ierr = PetscHMapIDestroy(&(*label)->hmap);CHKERRQ(ierr);
520d67d17b1SMatthew G. Knepley   ierr = PetscHeaderDestroy(label);CHKERRQ(ierr);
521c58f1c22SToby Isaac   PetscFunctionReturn(0);
522c58f1c22SToby Isaac }
523c58f1c22SToby Isaac 
52484f0b6dfSMatthew G. Knepley /*@
52584f0b6dfSMatthew G. Knepley   DMLabelDuplicate - Duplicates a DMLabel
52684f0b6dfSMatthew G. Knepley 
5275b5e7992SMatthew G. Knepley   Collective on label
5285b5e7992SMatthew G. Knepley 
52984f0b6dfSMatthew G. Knepley   Input Parameter:
53084f0b6dfSMatthew G. Knepley . label - The DMLabel
53184f0b6dfSMatthew G. Knepley 
53284f0b6dfSMatthew G. Knepley   Output Parameter:
53384f0b6dfSMatthew G. Knepley . labelnew - location to put new vector
53484f0b6dfSMatthew G. Knepley 
53584f0b6dfSMatthew G. Knepley   Level: intermediate
53684f0b6dfSMatthew G. Knepley 
53784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelDestroy()
53884f0b6dfSMatthew G. Knepley @*/
539c58f1c22SToby Isaac PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew)
540c58f1c22SToby Isaac {
541d67d17b1SMatthew G. Knepley   const char    *name;
542ad8374ffSToby Isaac   PetscInt       v;
543c58f1c22SToby Isaac   PetscErrorCode ierr;
544c58f1c22SToby Isaac 
545c58f1c22SToby Isaac   PetscFunctionBegin;
546d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
547c58f1c22SToby Isaac   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
548d67d17b1SMatthew G. Knepley   ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr);
549d67d17b1SMatthew G. Knepley   ierr = DMLabelCreate(PetscObjectComm((PetscObject) label), name, labelnew);CHKERRQ(ierr);
550c58f1c22SToby Isaac 
551c58f1c22SToby Isaac   (*labelnew)->numStrata    = label->numStrata;
5525aa44df4SToby Isaac   (*labelnew)->defaultValue = label->defaultValue;
553c58f1c22SToby Isaac   ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues);CHKERRQ(ierr);
554c58f1c22SToby Isaac   ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes);CHKERRQ(ierr);
555c58f1c22SToby Isaac   ierr = PetscMalloc1(label->numStrata, &(*labelnew)->ht);CHKERRQ(ierr);
556c58f1c22SToby Isaac   ierr = PetscMalloc1(label->numStrata, &(*labelnew)->points);CHKERRQ(ierr);
557ad8374ffSToby Isaac   ierr = PetscMalloc1(label->numStrata, &(*labelnew)->validIS);CHKERRQ(ierr);
558c58f1c22SToby Isaac   for (v = 0; v < label->numStrata; ++v) {
559e8f14785SLisandro Dalcin     ierr = PetscHSetICreate(&(*labelnew)->ht[v]);CHKERRQ(ierr);
560c58f1c22SToby Isaac     (*labelnew)->stratumValues[v]  = label->stratumValues[v];
561c58f1c22SToby Isaac     (*labelnew)->stratumSizes[v]   = label->stratumSizes[v];
562ad8374ffSToby Isaac     ierr = PetscObjectReference((PetscObject) (label->points[v]));CHKERRQ(ierr);
563ad8374ffSToby Isaac     (*labelnew)->points[v]         = label->points[v];
564b9907514SLisandro Dalcin     (*labelnew)->validIS[v]        = PETSC_TRUE;
565c58f1c22SToby Isaac   }
566f14fe40dSLisandro Dalcin   ierr = PetscHMapIDestroy(&(*labelnew)->hmap);CHKERRQ(ierr);
567b9907514SLisandro Dalcin   ierr = PetscHMapIDuplicate(label->hmap,&(*labelnew)->hmap);CHKERRQ(ierr);
568c58f1c22SToby Isaac   (*labelnew)->pStart = -1;
569c58f1c22SToby Isaac   (*labelnew)->pEnd   = -1;
570c58f1c22SToby Isaac   (*labelnew)->bt     = NULL;
571c58f1c22SToby Isaac   PetscFunctionReturn(0);
572c58f1c22SToby Isaac }
573c58f1c22SToby Isaac 
574609dae6eSVaclav Hapla /*@C
575609dae6eSVaclav Hapla   DMLabelCompare - Compare two DMLabel objects
576609dae6eSVaclav Hapla 
5775efe38ccSVaclav Hapla   Collective on comm
578609dae6eSVaclav Hapla 
579609dae6eSVaclav Hapla   Input Parameters:
580*f1a722f8SMatthew G. Knepley + comm - Comm over which to compare labels
581*f1a722f8SMatthew G. Knepley . l0 - First DMLabel
582609dae6eSVaclav Hapla - l1 - Second DMLabel
583609dae6eSVaclav Hapla 
584609dae6eSVaclav Hapla   Output Parameters
5855efe38ccSVaclav Hapla + equal   - (Optional) Flag whether the two labels are equal
5865efe38ccSVaclav Hapla - message - (Optional) Message describing the difference
587609dae6eSVaclav Hapla 
588609dae6eSVaclav Hapla   Level: intermediate
589609dae6eSVaclav Hapla 
590609dae6eSVaclav Hapla   Notes:
5915efe38ccSVaclav Hapla   The output flag equal is the same on all processes.
5925efe38ccSVaclav Hapla   If it is passed as NULL and difference is found, an error is thrown on all processes.
5935efe38ccSVaclav Hapla   Make sure to pass NULL on all processes.
594609dae6eSVaclav Hapla 
5955efe38ccSVaclav Hapla   The output message is set independently on each rank.
5965efe38ccSVaclav Hapla   It is set to NULL if no difference was found on the current rank. It must be freed by user.
5975efe38ccSVaclav Hapla   If message is passed as NULL and difference is found, the difference description is printed to stderr in synchronized manner.
5985efe38ccSVaclav Hapla   Make sure to pass NULL on all processes.
599609dae6eSVaclav Hapla 
600609dae6eSVaclav Hapla   For the comparison, we ignore the order of stratum values, and strata with no points.
601609dae6eSVaclav Hapla 
6025efe38ccSVaclav Hapla   The communicator needs to be specified because currently DMLabel can live on PETSC_COMM_SELF even if the underlying DM is parallel.
6035efe38ccSVaclav Hapla 
604609dae6eSVaclav Hapla   Fortran Notes:
605609dae6eSVaclav Hapla   This function is currently not available from Fortran.
606609dae6eSVaclav Hapla 
607609dae6eSVaclav Hapla .seealso: DMCompareLabels(), DMLabelGetNumValues(), DMLabelGetDefaultValue(), DMLabelGetNonEmptyStratumValuesIS(), DMLabelGetStratumIS()
608609dae6eSVaclav Hapla @*/
6095efe38ccSVaclav Hapla PetscErrorCode DMLabelCompare(MPI_Comm comm, DMLabel l0, DMLabel l1, PetscBool *equal, char **message)
610609dae6eSVaclav Hapla {
611609dae6eSVaclav Hapla   const char     *name0, *name1;
612609dae6eSVaclav Hapla   char            msg[PETSC_MAX_PATH_LEN] = "";
6135efe38ccSVaclav Hapla   PetscBool       eq;
6145efe38ccSVaclav Hapla   PetscMPIInt     rank;
615609dae6eSVaclav Hapla   PetscErrorCode  ierr;
616609dae6eSVaclav Hapla 
617609dae6eSVaclav Hapla   PetscFunctionBegin;
6185efe38ccSVaclav Hapla   PetscValidHeaderSpecific(l0, DMLABEL_CLASSID, 2);
6195efe38ccSVaclav Hapla   PetscValidHeaderSpecific(l1, DMLABEL_CLASSID, 3);
6205efe38ccSVaclav Hapla   if (equal) PetscValidBoolPointer(equal, 4);
6215efe38ccSVaclav Hapla   if (message) PetscValidPointer(message, 5);
6225efe38ccSVaclav Hapla   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
623609dae6eSVaclav Hapla   ierr = PetscObjectGetName((PetscObject)l0, &name0);CHKERRQ(ierr);
624609dae6eSVaclav Hapla   ierr = PetscObjectGetName((PetscObject)l1, &name1);CHKERRQ(ierr);
625609dae6eSVaclav Hapla   {
626609dae6eSVaclav Hapla     PetscInt v0, v1;
627609dae6eSVaclav Hapla 
628609dae6eSVaclav Hapla     ierr = DMLabelGetDefaultValue(l0, &v0);CHKERRQ(ierr);
629609dae6eSVaclav Hapla     ierr = DMLabelGetDefaultValue(l1, &v1);CHKERRQ(ierr);
6305efe38ccSVaclav Hapla     eq = (PetscBool) (v0 == v1);
6315efe38ccSVaclav Hapla     if (!eq) {
632609dae6eSVaclav Hapla       ierr = PetscSNPrintf(msg, sizeof(msg), "Default value of DMLabel l0 \"%s\" = %D != %D = Default value of DMLabel l1 \"%s\"", name0, v0, v1, name1);CHKERRQ(ierr);
633609dae6eSVaclav Hapla     }
6345efe38ccSVaclav Hapla     ierr = MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRMPI(ierr);
6355efe38ccSVaclav Hapla     if (!eq) goto finish;
636609dae6eSVaclav Hapla   }
637609dae6eSVaclav Hapla   {
638609dae6eSVaclav Hapla     IS              is0, is1;
639609dae6eSVaclav Hapla 
640609dae6eSVaclav Hapla     ierr = DMLabelGetNonEmptyStratumValuesIS(l0, &is0);CHKERRQ(ierr);
641609dae6eSVaclav Hapla     ierr = DMLabelGetNonEmptyStratumValuesIS(l1, &is1);CHKERRQ(ierr);
6425efe38ccSVaclav Hapla     ierr = ISEqual(is0, is1, &eq);CHKERRQ(ierr);
643609dae6eSVaclav Hapla     ierr = ISDestroy(&is0);CHKERRQ(ierr);
644609dae6eSVaclav Hapla     ierr = ISDestroy(&is1);CHKERRQ(ierr);
6455efe38ccSVaclav Hapla     if (!eq) {
646609dae6eSVaclav Hapla       ierr = PetscSNPrintf(msg, sizeof(msg), "Stratum values in DMLabel l0 \"%s\" are different than in DMLabel l1 \"%s\"", name0, name1);CHKERRQ(ierr);
647609dae6eSVaclav Hapla     }
6485efe38ccSVaclav Hapla     ierr = MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRMPI(ierr);
6495efe38ccSVaclav Hapla     if (!eq) goto finish;
650609dae6eSVaclav Hapla   }
651609dae6eSVaclav Hapla   {
652609dae6eSVaclav Hapla     PetscInt i, nValues;
653609dae6eSVaclav Hapla 
654609dae6eSVaclav Hapla     ierr = DMLabelGetNumValues(l0, &nValues);CHKERRQ(ierr);
655609dae6eSVaclav Hapla     for (i=0; i<nValues; i++) {
656609dae6eSVaclav Hapla       const PetscInt  v = l0->stratumValues[i];
657609dae6eSVaclav Hapla       PetscInt        n;
658609dae6eSVaclav Hapla       IS              is0, is1;
659609dae6eSVaclav Hapla 
660609dae6eSVaclav Hapla       ierr = DMLabelGetStratumSize_Private(l0, i, &n);CHKERRQ(ierr);
661609dae6eSVaclav Hapla       if (!n) continue;
662609dae6eSVaclav Hapla       ierr = DMLabelGetStratumIS(l0, v, &is0);CHKERRQ(ierr);
663609dae6eSVaclav Hapla       ierr = DMLabelGetStratumIS(l1, v, &is1);CHKERRQ(ierr);
6645efe38ccSVaclav Hapla       ierr = ISEqualUnsorted(is0, is1, &eq);CHKERRQ(ierr);
665609dae6eSVaclav Hapla       ierr = ISDestroy(&is0);CHKERRQ(ierr);
666609dae6eSVaclav Hapla       ierr = ISDestroy(&is1);CHKERRQ(ierr);
6675efe38ccSVaclav Hapla       if (!eq) {
668609dae6eSVaclav Hapla         ierr = PetscSNPrintf(msg, sizeof(msg), "Stratum #%D with value %D contains different points in DMLabel l0 \"%s\" and DMLabel l1 \"%s\"", i, v, name0, name1);CHKERRQ(ierr);
6695efe38ccSVaclav Hapla         break;
670609dae6eSVaclav Hapla       }
671609dae6eSVaclav Hapla     }
6725efe38ccSVaclav Hapla     ierr = MPI_Allreduce(MPI_IN_PLACE, &eq, 1, MPIU_BOOL, MPI_LAND, comm);CHKERRMPI(ierr);
673609dae6eSVaclav Hapla   }
674609dae6eSVaclav Hapla finish:
6755efe38ccSVaclav Hapla   /* If message output arg not set, print to stderr */
676609dae6eSVaclav Hapla   if (message) {
677609dae6eSVaclav Hapla     *message = NULL;
678609dae6eSVaclav Hapla     if (msg[0]) {
679609dae6eSVaclav Hapla       ierr = PetscStrallocpy(msg, message);CHKERRQ(ierr);
680609dae6eSVaclav Hapla     }
6815efe38ccSVaclav Hapla   } else {
6825efe38ccSVaclav Hapla     if (msg[0]) {
6835efe38ccSVaclav Hapla       ierr = PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] %s\n", rank, msg);CHKERRQ(ierr);
684609dae6eSVaclav Hapla     }
6855efe38ccSVaclav Hapla     ierr = PetscSynchronizedFlush(comm, PETSC_STDERR);CHKERRQ(ierr);
6865efe38ccSVaclav Hapla   }
6875efe38ccSVaclav Hapla   /* If same output arg not ser and labels are not equal, throw error */
6885efe38ccSVaclav Hapla   if (equal) *equal = eq;
6892c71b3e2SJacob Faibussowitsch   else PetscCheckFalse(!eq,comm, PETSC_ERR_ARG_INCOMP, "DMLabels l0 \"%s\" and l1 \"%s\" are not equal");
690609dae6eSVaclav Hapla   PetscFunctionReturn(0);
691609dae6eSVaclav Hapla }
692609dae6eSVaclav Hapla 
693c6a43d28SMatthew G. Knepley /*@
694c6a43d28SMatthew G. Knepley   DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds
695c6a43d28SMatthew G. Knepley 
6965b5e7992SMatthew G. Knepley   Not collective
6975b5e7992SMatthew G. Knepley 
698c6a43d28SMatthew G. Knepley   Input Parameter:
699c6a43d28SMatthew G. Knepley . label  - The DMLabel
700c6a43d28SMatthew G. Knepley 
701c6a43d28SMatthew G. Knepley   Level: intermediate
702c6a43d28SMatthew G. Knepley 
703c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue()
704c6a43d28SMatthew G. Knepley @*/
705c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelComputeIndex(DMLabel label)
706c6a43d28SMatthew G. Knepley {
707c6a43d28SMatthew G. Knepley   PetscInt       pStart = PETSC_MAX_INT, pEnd = -1, v;
708c6a43d28SMatthew G. Knepley   PetscErrorCode ierr;
709c6a43d28SMatthew G. Knepley 
710c6a43d28SMatthew G. Knepley   PetscFunctionBegin;
711c6a43d28SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
712c6a43d28SMatthew G. Knepley   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
713c6a43d28SMatthew G. Knepley   for (v = 0; v < label->numStrata; ++v) {
714c6a43d28SMatthew G. Knepley     const PetscInt *points;
715c6a43d28SMatthew G. Knepley     PetscInt       i;
716c6a43d28SMatthew G. Knepley 
717c6a43d28SMatthew G. Knepley     ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr);
718c6a43d28SMatthew G. Knepley     for (i = 0; i < label->stratumSizes[v]; ++i) {
719c6a43d28SMatthew G. Knepley       const PetscInt point = points[i];
720c6a43d28SMatthew G. Knepley 
721c6a43d28SMatthew G. Knepley       pStart = PetscMin(point,   pStart);
722c6a43d28SMatthew G. Knepley       pEnd   = PetscMax(point+1, pEnd);
723c6a43d28SMatthew G. Knepley     }
724c6a43d28SMatthew G. Knepley     ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr);
725c6a43d28SMatthew G. Knepley   }
726c6a43d28SMatthew G. Knepley   label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart;
727c6a43d28SMatthew G. Knepley   label->pEnd   = pEnd;
728c6a43d28SMatthew G. Knepley   ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr);
729c6a43d28SMatthew G. Knepley   PetscFunctionReturn(0);
730c6a43d28SMatthew G. Knepley }
731c6a43d28SMatthew G. Knepley 
732c6a43d28SMatthew G. Knepley /*@
733c6a43d28SMatthew G. Knepley   DMLabelCreateIndex - Create an index structure for membership determination
734c6a43d28SMatthew G. Knepley 
7355b5e7992SMatthew G. Knepley   Not collective
7365b5e7992SMatthew G. Knepley 
737c6a43d28SMatthew G. Knepley   Input Parameters:
738c6a43d28SMatthew G. Knepley + label  - The DMLabel
739c6a43d28SMatthew G. Knepley . pStart - The smallest point
740c6a43d28SMatthew G. Knepley - pEnd   - The largest point + 1
741c6a43d28SMatthew G. Knepley 
742c6a43d28SMatthew G. Knepley   Level: intermediate
743c6a43d28SMatthew G. Knepley 
744c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelComputeIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue()
745c6a43d28SMatthew G. Knepley @*/
746c58f1c22SToby Isaac PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd)
747c58f1c22SToby Isaac {
748c58f1c22SToby Isaac   PetscInt       v;
749c58f1c22SToby Isaac   PetscErrorCode ierr;
750c58f1c22SToby Isaac 
751c58f1c22SToby Isaac   PetscFunctionBegin;
752d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
7530c3c4a36SLisandro Dalcin   ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr);
754c58f1c22SToby Isaac   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
755c58f1c22SToby Isaac   label->pStart = pStart;
756c58f1c22SToby Isaac   label->pEnd   = pEnd;
757c6a43d28SMatthew G. Knepley   /* This can be hooked into SetValue(),  ClearValue(), etc. for updating */
758c58f1c22SToby Isaac   ierr = PetscBTCreate(pEnd - pStart, &label->bt);CHKERRQ(ierr);
759c58f1c22SToby Isaac   for (v = 0; v < label->numStrata; ++v) {
760ad8374ffSToby Isaac     const PetscInt *points;
761c58f1c22SToby Isaac     PetscInt       i;
762c58f1c22SToby Isaac 
763ad8374ffSToby Isaac     ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr);
764c58f1c22SToby Isaac     for (i = 0; i < label->stratumSizes[v]; ++i) {
765ad8374ffSToby Isaac       const PetscInt point = points[i];
766c58f1c22SToby Isaac 
7672c71b3e2SJacob Faibussowitsch       PetscCheckFalse((point < pStart) || (point >= pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, pStart, pEnd);
768c58f1c22SToby Isaac       ierr = PetscBTSet(label->bt, point - pStart);CHKERRQ(ierr);
769c58f1c22SToby Isaac     }
770ad8374ffSToby Isaac     ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr);
771c58f1c22SToby Isaac   }
772c58f1c22SToby Isaac   PetscFunctionReturn(0);
773c58f1c22SToby Isaac }
774c58f1c22SToby Isaac 
775c6a43d28SMatthew G. Knepley /*@
776c6a43d28SMatthew G. Knepley   DMLabelDestroyIndex - Destroy the index structure
777c6a43d28SMatthew G. Knepley 
7785b5e7992SMatthew G. Knepley   Not collective
7795b5e7992SMatthew G. Knepley 
780c6a43d28SMatthew G. Knepley   Input Parameter:
781c6a43d28SMatthew G. Knepley . label - the DMLabel
782c6a43d28SMatthew G. Knepley 
783c6a43d28SMatthew G. Knepley   Level: intermediate
784c6a43d28SMatthew G. Knepley 
785c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue()
786c6a43d28SMatthew G. Knepley @*/
787c58f1c22SToby Isaac PetscErrorCode DMLabelDestroyIndex(DMLabel label)
788c58f1c22SToby Isaac {
789c58f1c22SToby Isaac   PetscErrorCode ierr;
790c58f1c22SToby Isaac 
791c58f1c22SToby Isaac   PetscFunctionBegin;
792d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
793c58f1c22SToby Isaac   label->pStart = -1;
794c58f1c22SToby Isaac   label->pEnd   = -1;
7950c3c4a36SLisandro Dalcin   ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr);
796c58f1c22SToby Isaac   PetscFunctionReturn(0);
797c58f1c22SToby Isaac }
798c58f1c22SToby Isaac 
799c58f1c22SToby Isaac /*@
800c6a43d28SMatthew G. Knepley   DMLabelGetBounds - Return the smallest and largest point in the label
801c6a43d28SMatthew G. Knepley 
8025b5e7992SMatthew G. Knepley   Not collective
8035b5e7992SMatthew G. Knepley 
804c6a43d28SMatthew G. Knepley   Input Parameter:
805c6a43d28SMatthew G. Knepley . label - the DMLabel
806c6a43d28SMatthew G. Knepley 
807c6a43d28SMatthew G. Knepley   Output Parameters:
808c6a43d28SMatthew G. Knepley + pStart - The smallest point
809c6a43d28SMatthew G. Knepley - pEnd   - The largest point + 1
810c6a43d28SMatthew G. Knepley 
811c6a43d28SMatthew G. Knepley   Note: This will compute an index for the label if one does not exist.
812c6a43d28SMatthew G. Knepley 
813c6a43d28SMatthew G. Knepley   Level: intermediate
814c6a43d28SMatthew G. Knepley 
815c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue()
816c6a43d28SMatthew G. Knepley @*/
817c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd)
818c6a43d28SMatthew G. Knepley {
819c6a43d28SMatthew G. Knepley   PetscErrorCode ierr;
820c6a43d28SMatthew G. Knepley 
821c6a43d28SMatthew G. Knepley   PetscFunctionBegin;
822c6a43d28SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
823c6a43d28SMatthew G. Knepley   if ((label->pStart == -1) && (label->pEnd == -1)) {ierr = DMLabelComputeIndex(label);CHKERRQ(ierr);}
824c6a43d28SMatthew G. Knepley   if (pStart) {
825534a8f05SLisandro Dalcin     PetscValidIntPointer(pStart, 2);
826c6a43d28SMatthew G. Knepley     *pStart = label->pStart;
827c6a43d28SMatthew G. Knepley   }
828c6a43d28SMatthew G. Knepley   if (pEnd) {
829534a8f05SLisandro Dalcin     PetscValidIntPointer(pEnd, 3);
830c6a43d28SMatthew G. Knepley     *pEnd = label->pEnd;
831c6a43d28SMatthew G. Knepley   }
832c6a43d28SMatthew G. Knepley   PetscFunctionReturn(0);
833c6a43d28SMatthew G. Knepley }
834c6a43d28SMatthew G. Knepley 
835c6a43d28SMatthew G. Knepley /*@
836c58f1c22SToby Isaac   DMLabelHasValue - Determine whether a label assigns the value to any point
837c58f1c22SToby Isaac 
8385b5e7992SMatthew G. Knepley   Not collective
8395b5e7992SMatthew G. Knepley 
840c58f1c22SToby Isaac   Input Parameters:
841c58f1c22SToby Isaac + label - the DMLabel
842c58f1c22SToby Isaac - value - the value
843c58f1c22SToby Isaac 
844c58f1c22SToby Isaac   Output Parameter:
845c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point
846c58f1c22SToby Isaac 
847c58f1c22SToby Isaac   Level: developer
848c58f1c22SToby Isaac 
849c58f1c22SToby Isaac .seealso: DMLabelHasPoint(), DMLabelGetValue(), DMLabelSetValue()
850c58f1c22SToby Isaac @*/
851c58f1c22SToby Isaac PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains)
852c58f1c22SToby Isaac {
853c58f1c22SToby Isaac   PetscInt v;
8540c3c4a36SLisandro Dalcin   PetscErrorCode ierr;
855c58f1c22SToby Isaac 
856c58f1c22SToby Isaac   PetscFunctionBegin;
857d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
858534a8f05SLisandro Dalcin   PetscValidBoolPointer(contains, 3);
8590c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
8600c3c4a36SLisandro Dalcin   *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE;
861c58f1c22SToby Isaac   PetscFunctionReturn(0);
862c58f1c22SToby Isaac }
863c58f1c22SToby Isaac 
864c58f1c22SToby Isaac /*@
865c58f1c22SToby Isaac   DMLabelHasPoint - Determine whether a label assigns a value to a point
866c58f1c22SToby Isaac 
8675b5e7992SMatthew G. Knepley   Not collective
8685b5e7992SMatthew G. Knepley 
869c58f1c22SToby Isaac   Input Parameters:
870c58f1c22SToby Isaac + label - the DMLabel
871c58f1c22SToby Isaac - point - the point
872c58f1c22SToby Isaac 
873c58f1c22SToby Isaac   Output Parameter:
874c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value
875c58f1c22SToby Isaac 
876c58f1c22SToby Isaac   Note: The user must call DMLabelCreateIndex() before this function.
877c58f1c22SToby Isaac 
878c58f1c22SToby Isaac   Level: developer
879c58f1c22SToby Isaac 
880c58f1c22SToby Isaac .seealso: DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue()
881c58f1c22SToby Isaac @*/
882c58f1c22SToby Isaac PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains)
883c58f1c22SToby Isaac {
884c58f1c22SToby Isaac   PetscErrorCode ierr;
885c58f1c22SToby Isaac 
886c58f1c22SToby Isaac   PetscFunctionBeginHot;
887d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
888534a8f05SLisandro Dalcin   PetscValidBoolPointer(contains, 3);
889c58f1c22SToby Isaac   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
89076bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
8912c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!label->bt,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()");
8922c71b3e2SJacob Faibussowitsch     PetscCheckFalse((point < label->pStart) || (point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd);
89376bd3646SJed Brown   }
894c58f1c22SToby Isaac   *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE;
895c58f1c22SToby Isaac   PetscFunctionReturn(0);
896c58f1c22SToby Isaac }
897c58f1c22SToby Isaac 
898c58f1c22SToby Isaac /*@
899c58f1c22SToby Isaac   DMLabelStratumHasPoint - Return true if the stratum contains a point
900c58f1c22SToby Isaac 
9015b5e7992SMatthew G. Knepley   Not collective
9025b5e7992SMatthew G. Knepley 
903c58f1c22SToby Isaac   Input Parameters:
904c58f1c22SToby Isaac + label - the DMLabel
905c58f1c22SToby Isaac . value - the stratum value
906c58f1c22SToby Isaac - point - the point
907c58f1c22SToby Isaac 
908c58f1c22SToby Isaac   Output Parameter:
909c58f1c22SToby Isaac . contains - true if the stratum contains the point
910c58f1c22SToby Isaac 
911c58f1c22SToby Isaac   Level: intermediate
912c58f1c22SToby Isaac 
913c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue()
914c58f1c22SToby Isaac @*/
915c58f1c22SToby Isaac PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains)
916c58f1c22SToby Isaac {
917c58f1c22SToby Isaac   PetscInt       v;
918c58f1c22SToby Isaac   PetscErrorCode ierr;
919c58f1c22SToby Isaac 
9200c3c4a36SLisandro Dalcin   PetscFunctionBeginHot;
921d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
922534a8f05SLisandro Dalcin   PetscValidBoolPointer(contains, 4);
923c58f1c22SToby Isaac   *contains = PETSC_FALSE;
9240c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
9250c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
9260c3c4a36SLisandro Dalcin 
927ad8374ffSToby Isaac   if (label->validIS[v]) {
928c58f1c22SToby Isaac     PetscInt i;
929c58f1c22SToby Isaac 
930a2d74346SToby Isaac     ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr);
9310c3c4a36SLisandro Dalcin     if (i >= 0) *contains = PETSC_TRUE;
932c58f1c22SToby Isaac   } else {
933c58f1c22SToby Isaac     PetscBool has;
934c58f1c22SToby Isaac 
935b9907514SLisandro Dalcin     ierr = PetscHSetIHas(label->ht[v], point, &has);CHKERRQ(ierr);
9360c3c4a36SLisandro Dalcin     if (has) *contains = PETSC_TRUE;
937c58f1c22SToby Isaac   }
938c58f1c22SToby Isaac   PetscFunctionReturn(0);
939c58f1c22SToby Isaac }
940c58f1c22SToby Isaac 
94184f0b6dfSMatthew G. Knepley /*@
9425aa44df4SToby Isaac   DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value.
9435aa44df4SToby Isaac   When a label is created, it is initialized to -1.
9445aa44df4SToby Isaac 
9455b5e7992SMatthew G. Knepley   Not collective
9465b5e7992SMatthew G. Knepley 
9475aa44df4SToby Isaac   Input parameter:
9485aa44df4SToby Isaac . label - a DMLabel object
9495aa44df4SToby Isaac 
9505aa44df4SToby Isaac   Output parameter:
9515aa44df4SToby Isaac . defaultValue - the default value
9525aa44df4SToby Isaac 
9535aa44df4SToby Isaac   Level: beginner
9545aa44df4SToby Isaac 
9555aa44df4SToby Isaac .seealso: DMLabelSetDefaultValue(), DMLabelGetValue(), DMLabelSetValue()
95684f0b6dfSMatthew G. Knepley @*/
9575aa44df4SToby Isaac PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue)
9585aa44df4SToby Isaac {
9595aa44df4SToby Isaac   PetscFunctionBegin;
960d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
9615aa44df4SToby Isaac   *defaultValue = label->defaultValue;
9625aa44df4SToby Isaac   PetscFunctionReturn(0);
9635aa44df4SToby Isaac }
9645aa44df4SToby Isaac 
96584f0b6dfSMatthew G. Knepley /*@
9665aa44df4SToby Isaac   DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value.
9675aa44df4SToby Isaac   When a label is created, it is initialized to -1.
9685aa44df4SToby Isaac 
9695b5e7992SMatthew G. Knepley   Not collective
9705b5e7992SMatthew G. Knepley 
9715aa44df4SToby Isaac   Input parameter:
9725aa44df4SToby Isaac . label - a DMLabel object
9735aa44df4SToby Isaac 
9745aa44df4SToby Isaac   Output parameter:
9755aa44df4SToby Isaac . defaultValue - the default value
9765aa44df4SToby Isaac 
9775aa44df4SToby Isaac   Level: beginner
9785aa44df4SToby Isaac 
9795aa44df4SToby Isaac .seealso: DMLabelGetDefaultValue(), DMLabelGetValue(), DMLabelSetValue()
98084f0b6dfSMatthew G. Knepley @*/
9815aa44df4SToby Isaac PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue)
9825aa44df4SToby Isaac {
9835aa44df4SToby Isaac   PetscFunctionBegin;
984d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
9855aa44df4SToby Isaac   label->defaultValue = defaultValue;
9865aa44df4SToby Isaac   PetscFunctionReturn(0);
9875aa44df4SToby Isaac }
9885aa44df4SToby Isaac 
989c58f1c22SToby Isaac /*@
9905aa44df4SToby Isaac   DMLabelGetValue - Return the value a label assigns to a point, or the label's default value (which is initially -1, and can be changed with DMLabelSetDefaultValue())
991c58f1c22SToby Isaac 
9925b5e7992SMatthew G. Knepley   Not collective
9935b5e7992SMatthew G. Knepley 
994c58f1c22SToby Isaac   Input Parameters:
995c58f1c22SToby Isaac + label - the DMLabel
996c58f1c22SToby Isaac - point - the point
997c58f1c22SToby Isaac 
998c58f1c22SToby Isaac   Output Parameter:
9998e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default)
1000c58f1c22SToby Isaac 
1001c58f1c22SToby Isaac   Level: intermediate
1002c58f1c22SToby Isaac 
10035aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue()
1004c58f1c22SToby Isaac @*/
1005c58f1c22SToby Isaac PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value)
1006c58f1c22SToby Isaac {
1007c58f1c22SToby Isaac   PetscInt       v;
1008c58f1c22SToby Isaac   PetscErrorCode ierr;
1009c58f1c22SToby Isaac 
10100c3c4a36SLisandro Dalcin   PetscFunctionBeginHot;
1011d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1012c58f1c22SToby Isaac   PetscValidPointer(value, 3);
10135aa44df4SToby Isaac   *value = label->defaultValue;
1014c58f1c22SToby Isaac   for (v = 0; v < label->numStrata; ++v) {
1015ad8374ffSToby Isaac     if (label->validIS[v]) {
1016c58f1c22SToby Isaac       PetscInt i;
1017c58f1c22SToby Isaac 
1018a2d74346SToby Isaac       ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr);
1019c58f1c22SToby Isaac       if (i >= 0) {
1020c58f1c22SToby Isaac         *value = label->stratumValues[v];
1021c58f1c22SToby Isaac         break;
1022c58f1c22SToby Isaac       }
1023c58f1c22SToby Isaac     } else {
1024c58f1c22SToby Isaac       PetscBool has;
1025c58f1c22SToby Isaac 
1026b9907514SLisandro Dalcin       ierr = PetscHSetIHas(label->ht[v], point, &has);CHKERRQ(ierr);
1027c58f1c22SToby Isaac       if (has) {
1028c58f1c22SToby Isaac         *value = label->stratumValues[v];
1029c58f1c22SToby Isaac         break;
1030c58f1c22SToby Isaac       }
1031c58f1c22SToby Isaac     }
1032c58f1c22SToby Isaac   }
1033c58f1c22SToby Isaac   PetscFunctionReturn(0);
1034c58f1c22SToby Isaac }
1035c58f1c22SToby Isaac 
1036c58f1c22SToby Isaac /*@
1037367003a6SStefano Zampini   DMLabelSetValue - Set the value a label assigns to a point.  If the value is the same as the label's default value (which is initially -1, and can be changed with DMLabelSetDefaultValue() to something different), then this function will do nothing.
1038c58f1c22SToby Isaac 
10395b5e7992SMatthew G. Knepley   Not collective
10405b5e7992SMatthew G. Knepley 
1041c58f1c22SToby Isaac   Input Parameters:
1042c58f1c22SToby Isaac + label - the DMLabel
1043c58f1c22SToby Isaac . point - the point
1044c58f1c22SToby Isaac - value - The point value
1045c58f1c22SToby Isaac 
1046c58f1c22SToby Isaac   Level: intermediate
1047c58f1c22SToby Isaac 
10485aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue()
1049c58f1c22SToby Isaac @*/
1050c58f1c22SToby Isaac PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value)
1051c58f1c22SToby Isaac {
1052c58f1c22SToby Isaac   PetscInt       v;
1053c58f1c22SToby Isaac   PetscErrorCode ierr;
1054c58f1c22SToby Isaac 
1055c58f1c22SToby Isaac   PetscFunctionBegin;
1056d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
10570c3c4a36SLisandro Dalcin   /* Find label value, add new entry if needed */
10585aa44df4SToby Isaac   if (value == label->defaultValue) PetscFunctionReturn(0);
1059b9907514SLisandro Dalcin   ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr);
1060c58f1c22SToby Isaac   /* Set key */
10610c3c4a36SLisandro Dalcin   ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr);
1062e8f14785SLisandro Dalcin   ierr = PetscHSetIAdd(label->ht[v], point);CHKERRQ(ierr);
1063c58f1c22SToby Isaac   PetscFunctionReturn(0);
1064c58f1c22SToby Isaac }
1065c58f1c22SToby Isaac 
1066c58f1c22SToby Isaac /*@
1067c58f1c22SToby Isaac   DMLabelClearValue - Clear the value a label assigns to a point
1068c58f1c22SToby Isaac 
10695b5e7992SMatthew G. Knepley   Not collective
10705b5e7992SMatthew G. Knepley 
1071c58f1c22SToby Isaac   Input Parameters:
1072c58f1c22SToby Isaac + label - the DMLabel
1073c58f1c22SToby Isaac . point - the point
1074c58f1c22SToby Isaac - value - The point value
1075c58f1c22SToby Isaac 
1076c58f1c22SToby Isaac   Level: intermediate
1077c58f1c22SToby Isaac 
1078c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue()
1079c58f1c22SToby Isaac @*/
1080c58f1c22SToby Isaac PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value)
1081c58f1c22SToby Isaac {
1082ad8374ffSToby Isaac   PetscInt       v;
1083c58f1c22SToby Isaac   PetscErrorCode ierr;
1084c58f1c22SToby Isaac 
1085c58f1c22SToby Isaac   PetscFunctionBegin;
1086d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1087c58f1c22SToby Isaac   /* Find label value */
10880c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
10890c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
10900c3c4a36SLisandro Dalcin 
1091eeed21e7SToby Isaac   if (label->bt) {
10922c71b3e2SJacob Faibussowitsch     PetscCheckFalse((point < label->pStart) || (point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd);
1093eeed21e7SToby Isaac     ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr);
1094eeed21e7SToby Isaac   }
10950c3c4a36SLisandro Dalcin 
10960c3c4a36SLisandro Dalcin   /* Delete key */
10970c3c4a36SLisandro Dalcin   ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr);
1098e8f14785SLisandro Dalcin   ierr = PetscHSetIDel(label->ht[v], point);CHKERRQ(ierr);
1099c58f1c22SToby Isaac   PetscFunctionReturn(0);
1100c58f1c22SToby Isaac }
1101c58f1c22SToby Isaac 
1102c58f1c22SToby Isaac /*@
1103c58f1c22SToby Isaac   DMLabelInsertIS - Set all points in the IS to a value
1104c58f1c22SToby Isaac 
11055b5e7992SMatthew G. Knepley   Not collective
11065b5e7992SMatthew G. Knepley 
1107c58f1c22SToby Isaac   Input Parameters:
1108c58f1c22SToby Isaac + label - the DMLabel
1109c58f1c22SToby Isaac . is    - the point IS
1110c58f1c22SToby Isaac - value - The point value
1111c58f1c22SToby Isaac 
1112c58f1c22SToby Isaac   Level: intermediate
1113c58f1c22SToby Isaac 
1114c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
1115c58f1c22SToby Isaac @*/
1116c58f1c22SToby Isaac PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value)
1117c58f1c22SToby Isaac {
11180c3c4a36SLisandro Dalcin   PetscInt        v, n, p;
1119c58f1c22SToby Isaac   const PetscInt *points;
1120c58f1c22SToby Isaac   PetscErrorCode  ierr;
1121c58f1c22SToby Isaac 
1122c58f1c22SToby Isaac   PetscFunctionBegin;
1123d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1124c58f1c22SToby Isaac   PetscValidHeaderSpecific(is, IS_CLASSID, 2);
11250c3c4a36SLisandro Dalcin   /* Find label value, add new entry if needed */
11260c3c4a36SLisandro Dalcin   if (value == label->defaultValue) PetscFunctionReturn(0);
1127b9907514SLisandro Dalcin   ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr);
11280c3c4a36SLisandro Dalcin   /* Set keys */
11290c3c4a36SLisandro Dalcin   ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr);
1130c58f1c22SToby Isaac   ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr);
1131c58f1c22SToby Isaac   ierr = ISGetIndices(is, &points);CHKERRQ(ierr);
1132e8f14785SLisandro Dalcin   for (p = 0; p < n; ++p) {ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr);}
1133c58f1c22SToby Isaac   ierr = ISRestoreIndices(is, &points);CHKERRQ(ierr);
1134c58f1c22SToby Isaac   PetscFunctionReturn(0);
1135c58f1c22SToby Isaac }
1136c58f1c22SToby Isaac 
113784f0b6dfSMatthew G. Knepley /*@
113884f0b6dfSMatthew G. Knepley   DMLabelGetNumValues - Get the number of values that the DMLabel takes
113984f0b6dfSMatthew G. Knepley 
11405b5e7992SMatthew G. Knepley   Not collective
11415b5e7992SMatthew G. Knepley 
114284f0b6dfSMatthew G. Knepley   Input Parameter:
114384f0b6dfSMatthew G. Knepley . label - the DMLabel
114484f0b6dfSMatthew G. Knepley 
114501d2d390SJose E. Roman   Output Parameter:
114684f0b6dfSMatthew G. Knepley . numValues - the number of values
114784f0b6dfSMatthew G. Knepley 
114884f0b6dfSMatthew G. Knepley   Level: intermediate
114984f0b6dfSMatthew G. Knepley 
115084f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
115184f0b6dfSMatthew G. Knepley @*/
1152c58f1c22SToby Isaac PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues)
1153c58f1c22SToby Isaac {
1154c58f1c22SToby Isaac   PetscFunctionBegin;
1155d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1156c58f1c22SToby Isaac   PetscValidPointer(numValues, 2);
1157c58f1c22SToby Isaac   *numValues = label->numStrata;
1158c58f1c22SToby Isaac   PetscFunctionReturn(0);
1159c58f1c22SToby Isaac }
1160c58f1c22SToby Isaac 
116184f0b6dfSMatthew G. Knepley /*@
116284f0b6dfSMatthew G. Knepley   DMLabelGetValueIS - Get an IS of all values that the DMlabel takes
116384f0b6dfSMatthew G. Knepley 
11645b5e7992SMatthew G. Knepley   Not collective
11655b5e7992SMatthew G. Knepley 
116684f0b6dfSMatthew G. Knepley   Input Parameter:
116784f0b6dfSMatthew G. Knepley . label - the DMLabel
116884f0b6dfSMatthew G. Knepley 
116901d2d390SJose E. Roman   Output Parameter:
117084f0b6dfSMatthew G. Knepley . is    - the value IS
117184f0b6dfSMatthew G. Knepley 
117284f0b6dfSMatthew G. Knepley   Level: intermediate
117384f0b6dfSMatthew G. Knepley 
11741d04cbbeSVaclav Hapla   Notes:
11751d04cbbeSVaclav Hapla   The output IS should be destroyed when no longer needed.
11761d04cbbeSVaclav Hapla   Strata which are allocated but empty [DMLabelGetStratumSize() yields 0] are counted.
11771d04cbbeSVaclav Hapla   If you need to count only nonempty strata, use DMLabelGetNonEmptyStratumValuesIS().
11781d04cbbeSVaclav Hapla 
11791d04cbbeSVaclav Hapla .seealso: DMLabelGetNonEmptyStratumValuesIS(), DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
118084f0b6dfSMatthew G. Knepley @*/
1181c58f1c22SToby Isaac PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values)
1182c58f1c22SToby Isaac {
1183c58f1c22SToby Isaac   PetscErrorCode ierr;
1184c58f1c22SToby Isaac 
1185c58f1c22SToby Isaac   PetscFunctionBegin;
1186d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1187c58f1c22SToby Isaac   PetscValidPointer(values, 2);
1188c58f1c22SToby Isaac   ierr = ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values);CHKERRQ(ierr);
1189c58f1c22SToby Isaac   PetscFunctionReturn(0);
1190c58f1c22SToby Isaac }
1191c58f1c22SToby Isaac 
119284f0b6dfSMatthew G. Knepley /*@
11931d04cbbeSVaclav Hapla   DMLabelGetNonEmptyStratumValuesIS - Get an IS of all values that the DMlabel takes
11941d04cbbeSVaclav Hapla 
11951d04cbbeSVaclav Hapla   Not collective
11961d04cbbeSVaclav Hapla 
11971d04cbbeSVaclav Hapla   Input Parameter:
11981d04cbbeSVaclav Hapla . label - the DMLabel
11991d04cbbeSVaclav Hapla 
12001d04cbbeSVaclav Hapla   Output Paramater:
12011d04cbbeSVaclav Hapla . is    - the value IS
12021d04cbbeSVaclav Hapla 
12031d04cbbeSVaclav Hapla   Level: intermediate
12041d04cbbeSVaclav Hapla 
12051d04cbbeSVaclav Hapla   Notes:
12061d04cbbeSVaclav Hapla   The output IS should be destroyed when no longer needed.
12071d04cbbeSVaclav Hapla   This is similar to DMLabelGetValueIS() but counts only nonempty strata.
12081d04cbbeSVaclav Hapla 
12091d04cbbeSVaclav Hapla .seealso: DMLabelGetValueIS(), DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
12101d04cbbeSVaclav Hapla @*/
12111d04cbbeSVaclav Hapla PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(DMLabel label, IS *values)
12121d04cbbeSVaclav Hapla {
12131d04cbbeSVaclav Hapla   PetscInt        i, j;
12141d04cbbeSVaclav Hapla   PetscInt       *valuesArr;
12151d04cbbeSVaclav Hapla   PetscErrorCode  ierr;
12161d04cbbeSVaclav Hapla 
12171d04cbbeSVaclav Hapla   PetscFunctionBegin;
12181d04cbbeSVaclav Hapla   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
12191d04cbbeSVaclav Hapla   PetscValidPointer(values, 2);
12201d04cbbeSVaclav Hapla   ierr = PetscMalloc1(label->numStrata, &valuesArr);CHKERRQ(ierr);
12211d04cbbeSVaclav Hapla   for (i = 0, j = 0; i < label->numStrata; i++) {
12221d04cbbeSVaclav Hapla     PetscInt        n;
12231d04cbbeSVaclav Hapla 
12241d04cbbeSVaclav Hapla     ierr = DMLabelGetStratumSize_Private(label, i, &n);CHKERRQ(ierr);
12251d04cbbeSVaclav Hapla     if (n) valuesArr[j++] = label->stratumValues[i];
12261d04cbbeSVaclav Hapla   }
12271d04cbbeSVaclav Hapla   if (j == label->numStrata) {
12281d04cbbeSVaclav Hapla     ierr = ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values);CHKERRQ(ierr);
12291d04cbbeSVaclav Hapla   } else {
12301d04cbbeSVaclav Hapla     ierr = ISCreateGeneral(PETSC_COMM_SELF, j, valuesArr, PETSC_COPY_VALUES, values);CHKERRQ(ierr);
12311d04cbbeSVaclav Hapla   }
12321d04cbbeSVaclav Hapla   ierr = PetscFree(valuesArr);CHKERRQ(ierr);
12331d04cbbeSVaclav Hapla   PetscFunctionReturn(0);
12341d04cbbeSVaclav Hapla }
12351d04cbbeSVaclav Hapla 
12361d04cbbeSVaclav Hapla /*@
1237d123abd9SMatthew G. Knepley   DMLabelGetValueIndex - Get the index of a given value in the list of values for the DMlabel, or -1 if it is not present
1238d123abd9SMatthew G. Knepley 
1239d123abd9SMatthew G. Knepley   Not collective
1240d123abd9SMatthew G. Knepley 
1241d123abd9SMatthew G. Knepley   Input Parameters:
1242d123abd9SMatthew G. Knepley + label - the DMLabel
124397bb3fdcSJose E. Roman - value - the value
1244d123abd9SMatthew G. Knepley 
124501d2d390SJose E. Roman   Output Parameter:
1246d123abd9SMatthew G. Knepley . index - the index of value in the list of values
1247d123abd9SMatthew G. Knepley 
1248d123abd9SMatthew G. Knepley   Level: intermediate
1249d123abd9SMatthew G. Knepley 
1250d123abd9SMatthew G. Knepley .seealso: DMLabelGetValueIS(), DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
1251d123abd9SMatthew G. Knepley @*/
1252d123abd9SMatthew G. Knepley PetscErrorCode DMLabelGetValueIndex(DMLabel label, PetscInt value, PetscInt *index)
1253d123abd9SMatthew G. Knepley {
1254d123abd9SMatthew G. Knepley   PetscInt v;
1255d123abd9SMatthew G. Knepley 
1256d123abd9SMatthew G. Knepley   PetscFunctionBegin;
1257d123abd9SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1258d123abd9SMatthew G. Knepley   PetscValidPointer(index, 3);
1259d123abd9SMatthew G. Knepley   /* Do not assume they are sorted */
1260d123abd9SMatthew G. Knepley   for (v = 0; v < label->numStrata; ++v) if (label->stratumValues[v] == value) break;
1261d123abd9SMatthew G. Knepley   if (v >= label->numStrata) *index = -1;
1262d123abd9SMatthew G. Knepley   else                       *index = v;
1263d123abd9SMatthew G. Knepley   PetscFunctionReturn(0);
1264d123abd9SMatthew G. Knepley }
1265d123abd9SMatthew G. Knepley 
1266d123abd9SMatthew G. Knepley /*@
126784f0b6dfSMatthew G. Knepley   DMLabelHasStratum - Determine whether points exist with the given value
126884f0b6dfSMatthew G. Knepley 
12695b5e7992SMatthew G. Knepley   Not collective
12705b5e7992SMatthew G. Knepley 
127184f0b6dfSMatthew G. Knepley   Input Parameters:
127284f0b6dfSMatthew G. Knepley + label - the DMLabel
127384f0b6dfSMatthew G. Knepley - value - the stratum value
127484f0b6dfSMatthew G. Knepley 
127501d2d390SJose E. Roman   Output Parameter:
127684f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist
127784f0b6dfSMatthew G. Knepley 
127884f0b6dfSMatthew G. Knepley   Level: intermediate
127984f0b6dfSMatthew G. Knepley 
128084f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
128184f0b6dfSMatthew G. Knepley @*/
1282fada774cSMatthew G. Knepley PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists)
1283fada774cSMatthew G. Knepley {
1284fada774cSMatthew G. Knepley   PetscInt       v;
12850c3c4a36SLisandro Dalcin   PetscErrorCode ierr;
1286fada774cSMatthew G. Knepley 
1287fada774cSMatthew G. Knepley   PetscFunctionBegin;
1288d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1289fada774cSMatthew G. Knepley   PetscValidPointer(exists, 3);
12900c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
12910c3c4a36SLisandro Dalcin   *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE;
1292fada774cSMatthew G. Knepley   PetscFunctionReturn(0);
1293fada774cSMatthew G. Knepley }
1294fada774cSMatthew G. Knepley 
129584f0b6dfSMatthew G. Knepley /*@
129684f0b6dfSMatthew G. Knepley   DMLabelGetStratumSize - Get the size of a stratum
129784f0b6dfSMatthew G. Knepley 
12985b5e7992SMatthew G. Knepley   Not collective
12995b5e7992SMatthew G. Knepley 
130084f0b6dfSMatthew G. Knepley   Input Parameters:
130184f0b6dfSMatthew G. Knepley + label - the DMLabel
130284f0b6dfSMatthew G. Knepley - value - the stratum value
130384f0b6dfSMatthew G. Knepley 
130401d2d390SJose E. Roman   Output Parameter:
130584f0b6dfSMatthew G. Knepley . size - The number of points in the stratum
130684f0b6dfSMatthew G. Knepley 
130784f0b6dfSMatthew G. Knepley   Level: intermediate
130884f0b6dfSMatthew G. Knepley 
130984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
131084f0b6dfSMatthew G. Knepley @*/
1311c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size)
1312c58f1c22SToby Isaac {
1313c58f1c22SToby Isaac   PetscInt       v;
1314c58f1c22SToby Isaac   PetscErrorCode ierr;
1315c58f1c22SToby Isaac 
1316c58f1c22SToby Isaac   PetscFunctionBegin;
1317d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1318c58f1c22SToby Isaac   PetscValidPointer(size, 3);
13190c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
13209e63cc69SVaclav Hapla   ierr = DMLabelGetStratumSize_Private(label, v, size);CHKERRQ(ierr);
1321c58f1c22SToby Isaac   PetscFunctionReturn(0);
1322c58f1c22SToby Isaac }
1323c58f1c22SToby Isaac 
132484f0b6dfSMatthew G. Knepley /*@
132584f0b6dfSMatthew G. Knepley   DMLabelGetStratumBounds - Get the largest and smallest point of a stratum
132684f0b6dfSMatthew G. Knepley 
13275b5e7992SMatthew G. Knepley   Not collective
13285b5e7992SMatthew G. Knepley 
132984f0b6dfSMatthew G. Knepley   Input Parameters:
133084f0b6dfSMatthew G. Knepley + label - the DMLabel
133184f0b6dfSMatthew G. Knepley - value - the stratum value
133284f0b6dfSMatthew G. Knepley 
133301d2d390SJose E. Roman   Output Parameters:
133484f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum
133584f0b6dfSMatthew G. Knepley - end - the largest point in the stratum
133684f0b6dfSMatthew G. Knepley 
133784f0b6dfSMatthew G. Knepley   Level: intermediate
133884f0b6dfSMatthew G. Knepley 
133984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
134084f0b6dfSMatthew G. Knepley @*/
1341c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end)
1342c58f1c22SToby Isaac {
13430c3c4a36SLisandro Dalcin   PetscInt       v, min, max;
1344c58f1c22SToby Isaac   PetscErrorCode ierr;
1345c58f1c22SToby Isaac 
1346c58f1c22SToby Isaac   PetscFunctionBegin;
1347d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1348cade499fSVaclav Hapla   if (start) {PetscValidPointer(start, 3); *start = -1;}
1349cade499fSVaclav Hapla   if (end)   {PetscValidPointer(end,   4); *end   = -1;}
13500c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
13510c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
1352c58f1c22SToby Isaac   ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr);
13530c3c4a36SLisandro Dalcin   if (label->stratumSizes[v] <= 0) PetscFunctionReturn(0);
1354d6cb179aSToby Isaac   ierr = ISGetMinMax(label->points[v], &min, &max);CHKERRQ(ierr);
1355d6cb179aSToby Isaac   if (start) *start = min;
1356d6cb179aSToby Isaac   if (end)   *end   = max+1;
1357c58f1c22SToby Isaac   PetscFunctionReturn(0);
1358c58f1c22SToby Isaac }
1359c58f1c22SToby Isaac 
136084f0b6dfSMatthew G. Knepley /*@
136184f0b6dfSMatthew G. Knepley   DMLabelGetStratumIS - Get an IS with the stratum points
136284f0b6dfSMatthew G. Knepley 
13635b5e7992SMatthew G. Knepley   Not collective
13645b5e7992SMatthew G. Knepley 
136584f0b6dfSMatthew G. Knepley   Input Parameters:
136684f0b6dfSMatthew G. Knepley + label - the DMLabel
136784f0b6dfSMatthew G. Knepley - value - the stratum value
136884f0b6dfSMatthew G. Knepley 
136901d2d390SJose E. Roman   Output Parameter:
137084f0b6dfSMatthew G. Knepley . points - The stratum points
137184f0b6dfSMatthew G. Knepley 
137284f0b6dfSMatthew G. Knepley   Level: intermediate
137384f0b6dfSMatthew G. Knepley 
1374593ce467SVaclav Hapla   Notes:
1375593ce467SVaclav Hapla   The output IS should be destroyed when no longer needed.
1376593ce467SVaclav Hapla   Returns NULL if the stratum is empty.
1377593ce467SVaclav Hapla 
137884f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
137984f0b6dfSMatthew G. Knepley @*/
1380c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points)
1381c58f1c22SToby Isaac {
1382c58f1c22SToby Isaac   PetscInt       v;
1383c58f1c22SToby Isaac   PetscErrorCode ierr;
1384c58f1c22SToby Isaac 
1385c58f1c22SToby Isaac   PetscFunctionBegin;
1386d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1387c58f1c22SToby Isaac   PetscValidPointer(points, 3);
1388c58f1c22SToby Isaac   *points = NULL;
13890c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
13900c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
1391c58f1c22SToby Isaac   ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr);
1392ad8374ffSToby Isaac   ierr = PetscObjectReference((PetscObject) label->points[v]);CHKERRQ(ierr);
1393ad8374ffSToby Isaac   *points = label->points[v];
1394c58f1c22SToby Isaac   PetscFunctionReturn(0);
1395c58f1c22SToby Isaac }
1396c58f1c22SToby Isaac 
139784f0b6dfSMatthew G. Knepley /*@
139884f0b6dfSMatthew G. Knepley   DMLabelSetStratumIS - Set the stratum points using an IS
139984f0b6dfSMatthew G. Knepley 
14005b5e7992SMatthew G. Knepley   Not collective
14015b5e7992SMatthew G. Knepley 
140284f0b6dfSMatthew G. Knepley   Input Parameters:
140384f0b6dfSMatthew G. Knepley + label - the DMLabel
140484f0b6dfSMatthew G. Knepley . value - the stratum value
140584f0b6dfSMatthew G. Knepley - points - The stratum points
140684f0b6dfSMatthew G. Knepley 
140784f0b6dfSMatthew G. Knepley   Level: intermediate
140884f0b6dfSMatthew G. Knepley 
140984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
141084f0b6dfSMatthew G. Knepley @*/
14114de306b1SToby Isaac PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is)
14124de306b1SToby Isaac {
14130c3c4a36SLisandro Dalcin   PetscInt       v;
14144de306b1SToby Isaac   PetscErrorCode ierr;
14154de306b1SToby Isaac 
14164de306b1SToby Isaac   PetscFunctionBegin;
1417d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1418d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(is, IS_CLASSID, 3);
1419b9907514SLisandro Dalcin   ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr);
14204de306b1SToby Isaac   if (is == label->points[v]) PetscFunctionReturn(0);
14214de306b1SToby Isaac   ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr);
14224de306b1SToby Isaac   ierr = ISGetLocalSize(is, &(label->stratumSizes[v]));CHKERRQ(ierr);
14234de306b1SToby Isaac   ierr = PetscObjectReference((PetscObject)is);CHKERRQ(ierr);
14244de306b1SToby Isaac   ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr);
14250c3c4a36SLisandro Dalcin   label->points[v]  = is;
14260c3c4a36SLisandro Dalcin   label->validIS[v] = PETSC_TRUE;
1427277ea44aSLisandro Dalcin   ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr);
14284de306b1SToby Isaac   if (label->bt) {
14294de306b1SToby Isaac     const PetscInt *points;
14304de306b1SToby Isaac     PetscInt p;
14314de306b1SToby Isaac 
14324de306b1SToby Isaac     ierr = ISGetIndices(is,&points);CHKERRQ(ierr);
14334de306b1SToby Isaac     for (p = 0; p < label->stratumSizes[v]; ++p) {
14344de306b1SToby Isaac       const PetscInt point = points[p];
14354de306b1SToby Isaac 
14362c71b3e2SJacob Faibussowitsch       PetscCheckFalse((point < label->pStart) || (point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd);
14374de306b1SToby Isaac       ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr);
14384de306b1SToby Isaac     }
14394de306b1SToby Isaac   }
14404de306b1SToby Isaac   PetscFunctionReturn(0);
14414de306b1SToby Isaac }
14424de306b1SToby Isaac 
144384f0b6dfSMatthew G. Knepley /*@
144484f0b6dfSMatthew G. Knepley   DMLabelClearStratum - Remove a stratum
14454de306b1SToby Isaac 
14465b5e7992SMatthew G. Knepley   Not collective
14475b5e7992SMatthew G. Knepley 
144884f0b6dfSMatthew G. Knepley   Input Parameters:
144984f0b6dfSMatthew G. Knepley + label - the DMLabel
145084f0b6dfSMatthew G. Knepley - value - the stratum value
145184f0b6dfSMatthew G. Knepley 
145284f0b6dfSMatthew G. Knepley   Level: intermediate
145384f0b6dfSMatthew G. Knepley 
145484f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
145584f0b6dfSMatthew G. Knepley @*/
1456c58f1c22SToby Isaac PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value)
1457c58f1c22SToby Isaac {
1458c58f1c22SToby Isaac   PetscInt       v;
1459c58f1c22SToby Isaac   PetscErrorCode ierr;
1460c58f1c22SToby Isaac 
1461c58f1c22SToby Isaac   PetscFunctionBegin;
1462d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
14630c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
14640c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
14654de306b1SToby Isaac   if (label->validIS[v]) {
14664de306b1SToby Isaac     if (label->bt) {
1467c58f1c22SToby Isaac       PetscInt       i;
1468ad8374ffSToby Isaac       const PetscInt *points;
1469c58f1c22SToby Isaac 
1470ad8374ffSToby Isaac       ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr);
1471c58f1c22SToby Isaac       for (i = 0; i < label->stratumSizes[v]; ++i) {
1472ad8374ffSToby Isaac         const PetscInt point = points[i];
1473c58f1c22SToby Isaac 
14742c71b3e2SJacob Faibussowitsch         PetscCheckFalse((point < label->pStart) || (point >= label->pEnd),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd);
1475c58f1c22SToby Isaac         ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr);
1476c58f1c22SToby Isaac       }
1477ad8374ffSToby Isaac       ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr);
1478c58f1c22SToby Isaac     }
1479c58f1c22SToby Isaac     label->stratumSizes[v] = 0;
14800c3c4a36SLisandro Dalcin     ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr);
1481277ea44aSLisandro Dalcin     ierr = ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v]);CHKERRQ(ierr);
14820c3c4a36SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject) label->points[v], "indices");CHKERRQ(ierr);
1483277ea44aSLisandro Dalcin     ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr);
1484c58f1c22SToby Isaac   } else {
1485b9907514SLisandro Dalcin     ierr = PetscHSetIClear(label->ht[v]);CHKERRQ(ierr);
1486c58f1c22SToby Isaac   }
1487c58f1c22SToby Isaac   PetscFunctionReturn(0);
1488c58f1c22SToby Isaac }
1489c58f1c22SToby Isaac 
149084f0b6dfSMatthew G. Knepley /*@
1491412e9a14SMatthew G. Knepley   DMLabelSetStratumBounds - Efficiently give a contiguous set of points a given label value
1492412e9a14SMatthew G. Knepley 
1493412e9a14SMatthew G. Knepley   Not collective
1494412e9a14SMatthew G. Knepley 
1495412e9a14SMatthew G. Knepley   Input Parameters:
1496412e9a14SMatthew G. Knepley + label  - The DMLabel
1497412e9a14SMatthew G. Knepley . value  - The label value for all points
1498412e9a14SMatthew G. Knepley . pStart - The first point
1499412e9a14SMatthew G. Knepley - pEnd   - A point beyond all marked points
1500412e9a14SMatthew G. Knepley 
1501412e9a14SMatthew G. Knepley   Note: The marks points are [pStart, pEnd), and only the bounds are stored.
1502412e9a14SMatthew G. Knepley 
1503412e9a14SMatthew G. Knepley   Level: intermediate
1504412e9a14SMatthew G. Knepley 
1505412e9a14SMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelSetStratumIS(), DMLabelGetStratumIS()
1506412e9a14SMatthew G. Knepley @*/
1507412e9a14SMatthew G. Knepley PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt pStart, PetscInt pEnd)
1508412e9a14SMatthew G. Knepley {
1509412e9a14SMatthew G. Knepley   IS             pIS;
1510412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1511412e9a14SMatthew G. Knepley 
1512412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1513412e9a14SMatthew G. Knepley   ierr = ISCreateStride(PETSC_COMM_SELF, pEnd - pStart, pStart, 1, &pIS);CHKERRQ(ierr);
1514412e9a14SMatthew G. Knepley   ierr = DMLabelSetStratumIS(label, value, pIS);CHKERRQ(ierr);
1515412e9a14SMatthew G. Knepley   ierr = ISDestroy(&pIS);CHKERRQ(ierr);
1516412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1517412e9a14SMatthew G. Knepley }
1518412e9a14SMatthew G. Knepley 
1519412e9a14SMatthew G. Knepley /*@
1520d123abd9SMatthew G. Knepley   DMLabelGetStratumPointIndex - Get the index of a point in a given stratum
1521d123abd9SMatthew G. Knepley 
1522d123abd9SMatthew G. Knepley   Not collective
1523d123abd9SMatthew G. Knepley 
1524d123abd9SMatthew G. Knepley   Input Parameters:
1525d123abd9SMatthew G. Knepley + label  - The DMLabel
1526d123abd9SMatthew G. Knepley . value  - The label value
1527d123abd9SMatthew G. Knepley - p      - A point with this value
1528d123abd9SMatthew G. Knepley 
1529d123abd9SMatthew G. Knepley   Output Parameter:
1530d123abd9SMatthew G. Knepley . index  - The index of this point in the stratum, or -1 if the point is not in the stratum or the stratum does not exist
1531d123abd9SMatthew G. Knepley 
1532d123abd9SMatthew G. Knepley   Level: intermediate
1533d123abd9SMatthew G. Knepley 
1534d123abd9SMatthew G. Knepley .seealso: DMLabelGetValueIndex(), DMLabelGetStratumIS(), DMLabelCreate()
1535d123abd9SMatthew G. Knepley @*/
1536d123abd9SMatthew G. Knepley PetscErrorCode DMLabelGetStratumPointIndex(DMLabel label, PetscInt value, PetscInt p, PetscInt *index)
1537d123abd9SMatthew G. Knepley {
1538d123abd9SMatthew G. Knepley   const PetscInt *indices;
1539d123abd9SMatthew G. Knepley   PetscInt        v;
1540d123abd9SMatthew G. Knepley   PetscErrorCode  ierr;
1541d123abd9SMatthew G. Knepley 
1542d123abd9SMatthew G. Knepley   PetscFunctionBegin;
1543d123abd9SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1544d123abd9SMatthew G. Knepley   PetscValidPointer(index, 4);
1545d123abd9SMatthew G. Knepley   *index = -1;
1546d123abd9SMatthew G. Knepley   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
1547d123abd9SMatthew G. Knepley   if (v < 0) PetscFunctionReturn(0);
1548d123abd9SMatthew G. Knepley   ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr);
1549d123abd9SMatthew G. Knepley   ierr = ISGetIndices(label->points[v], &indices);CHKERRQ(ierr);
1550d123abd9SMatthew G. Knepley   ierr = PetscFindInt(p, label->stratumSizes[v], indices, index);CHKERRQ(ierr);
1551d123abd9SMatthew G. Knepley   ierr = ISRestoreIndices(label->points[v], &indices);CHKERRQ(ierr);
1552d123abd9SMatthew G. Knepley   PetscFunctionReturn(0);
1553d123abd9SMatthew G. Knepley }
1554d123abd9SMatthew G. Knepley 
1555d123abd9SMatthew G. Knepley /*@
155684f0b6dfSMatthew G. Knepley   DMLabelFilter - Remove all points outside of [start, end)
155784f0b6dfSMatthew G. Knepley 
15585b5e7992SMatthew G. Knepley   Not collective
15595b5e7992SMatthew G. Knepley 
156084f0b6dfSMatthew G. Knepley   Input Parameters:
156184f0b6dfSMatthew G. Knepley + label - the DMLabel
156222cd2cdaSVaclav Hapla . start - the first point kept
156322cd2cdaSVaclav Hapla - end - one more than the last point kept
156484f0b6dfSMatthew G. Knepley 
156584f0b6dfSMatthew G. Knepley   Level: intermediate
156684f0b6dfSMatthew G. Knepley 
156784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
156884f0b6dfSMatthew G. Knepley @*/
1569c58f1c22SToby Isaac PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end)
1570c58f1c22SToby Isaac {
1571c58f1c22SToby Isaac   PetscInt       v;
1572c58f1c22SToby Isaac   PetscErrorCode ierr;
1573c58f1c22SToby Isaac 
1574c58f1c22SToby Isaac   PetscFunctionBegin;
1575d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
15760c3c4a36SLisandro Dalcin   ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr);
1577c58f1c22SToby Isaac   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
1578c58f1c22SToby Isaac   for (v = 0; v < label->numStrata; ++v) {
15799106b633SVaclav Hapla     ierr = ISGeneralFilter(label->points[v], start, end);CHKERRQ(ierr);
1580c58f1c22SToby Isaac   }
1581c58f1c22SToby Isaac   ierr = DMLabelCreateIndex(label, start, end);CHKERRQ(ierr);
1582c58f1c22SToby Isaac   PetscFunctionReturn(0);
1583c58f1c22SToby Isaac }
1584c58f1c22SToby Isaac 
158584f0b6dfSMatthew G. Knepley /*@
158684f0b6dfSMatthew G. Knepley   DMLabelPermute - Create a new label with permuted points
158784f0b6dfSMatthew G. Knepley 
15885b5e7992SMatthew G. Knepley   Not collective
15895b5e7992SMatthew G. Knepley 
159084f0b6dfSMatthew G. Knepley   Input Parameters:
159184f0b6dfSMatthew G. Knepley + label - the DMLabel
159284f0b6dfSMatthew G. Knepley - permutation - the point permutation
159384f0b6dfSMatthew G. Knepley 
159484f0b6dfSMatthew G. Knepley   Output Parameter:
159584f0b6dfSMatthew G. Knepley . labelnew - the new label containing the permuted points
159684f0b6dfSMatthew G. Knepley 
159784f0b6dfSMatthew G. Knepley   Level: intermediate
159884f0b6dfSMatthew G. Knepley 
159984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
160084f0b6dfSMatthew G. Knepley @*/
1601c58f1c22SToby Isaac PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew)
1602c58f1c22SToby Isaac {
1603c58f1c22SToby Isaac   const PetscInt *perm;
1604c58f1c22SToby Isaac   PetscInt        numValues, numPoints, v, q;
1605c58f1c22SToby Isaac   PetscErrorCode  ierr;
1606c58f1c22SToby Isaac 
1607c58f1c22SToby Isaac   PetscFunctionBegin;
1608d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1609d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(permutation, IS_CLASSID, 2);
1610c58f1c22SToby Isaac   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
1611c58f1c22SToby Isaac   ierr = DMLabelDuplicate(label, labelNew);CHKERRQ(ierr);
1612c58f1c22SToby Isaac   ierr = DMLabelGetNumValues(*labelNew, &numValues);CHKERRQ(ierr);
1613c58f1c22SToby Isaac   ierr = ISGetLocalSize(permutation, &numPoints);CHKERRQ(ierr);
1614c58f1c22SToby Isaac   ierr = ISGetIndices(permutation, &perm);CHKERRQ(ierr);
1615c58f1c22SToby Isaac   for (v = 0; v < numValues; ++v) {
1616c58f1c22SToby Isaac     const PetscInt size   = (*labelNew)->stratumSizes[v];
1617ad8374ffSToby Isaac     const PetscInt *points;
1618ad8374ffSToby Isaac     PetscInt *pointsNew;
1619c58f1c22SToby Isaac 
1620ad8374ffSToby Isaac     ierr = ISGetIndices((*labelNew)->points[v],&points);CHKERRQ(ierr);
1621ad8374ffSToby Isaac     ierr = PetscMalloc1(size,&pointsNew);CHKERRQ(ierr);
1622c58f1c22SToby Isaac     for (q = 0; q < size; ++q) {
1623ad8374ffSToby Isaac       const PetscInt point = points[q];
1624c58f1c22SToby Isaac 
16252c71b3e2SJacob Faibussowitsch       PetscCheckFalse((point < 0) || (point >= numPoints),PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [0, %D) for the remapping", point, numPoints);
1626ad8374ffSToby Isaac       pointsNew[q] = perm[point];
1627c58f1c22SToby Isaac     }
1628ad8374ffSToby Isaac     ierr = ISRestoreIndices((*labelNew)->points[v],&points);CHKERRQ(ierr);
1629ad8374ffSToby Isaac     ierr = PetscSortInt(size, pointsNew);CHKERRQ(ierr);
1630ad8374ffSToby Isaac     ierr = ISDestroy(&((*labelNew)->points[v]));CHKERRQ(ierr);
1631fa8e8ae5SToby Isaac     if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) {
1632fa8e8ae5SToby Isaac       ierr = ISCreateStride(PETSC_COMM_SELF,size,pointsNew[0],1,&((*labelNew)->points[v]));CHKERRQ(ierr);
1633fa8e8ae5SToby Isaac       ierr = PetscFree(pointsNew);CHKERRQ(ierr);
1634fa8e8ae5SToby Isaac     } else {
1635ad8374ffSToby Isaac       ierr = ISCreateGeneral(PETSC_COMM_SELF,size,pointsNew,PETSC_OWN_POINTER,&((*labelNew)->points[v]));CHKERRQ(ierr);
1636fa8e8ae5SToby Isaac     }
1637ad8374ffSToby Isaac     ierr = PetscObjectSetName((PetscObject) ((*labelNew)->points[v]), "indices");CHKERRQ(ierr);
1638c58f1c22SToby Isaac   }
1639c58f1c22SToby Isaac   ierr = ISRestoreIndices(permutation, &perm);CHKERRQ(ierr);
1640c58f1c22SToby Isaac   if (label->bt) {
1641c58f1c22SToby Isaac     ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr);
1642c58f1c22SToby Isaac     ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr);
1643c58f1c22SToby Isaac   }
1644c58f1c22SToby Isaac   PetscFunctionReturn(0);
1645c58f1c22SToby Isaac }
1646c58f1c22SToby Isaac 
164726c55118SMichael Lange PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata)
164826c55118SMichael Lange {
164926c55118SMichael Lange   MPI_Comm       comm;
165026c55118SMichael Lange   PetscInt       s, l, nroots, nleaves, dof, offset, size;
165126c55118SMichael Lange   PetscInt      *remoteOffsets, *rootStrata, *rootIdx;
165226c55118SMichael Lange   PetscSection   rootSection;
165326c55118SMichael Lange   PetscSF        labelSF;
165426c55118SMichael Lange   PetscErrorCode ierr;
165526c55118SMichael Lange 
165626c55118SMichael Lange   PetscFunctionBegin;
165726c55118SMichael Lange   if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);}
165826c55118SMichael Lange   ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr);
165926c55118SMichael Lange   /* Build a section of stratum values per point, generate the according SF
166026c55118SMichael Lange      and distribute point-wise stratum values to leaves. */
166126c55118SMichael Lange   ierr = PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL);CHKERRQ(ierr);
166226c55118SMichael Lange   ierr = PetscSectionCreate(comm, &rootSection);CHKERRQ(ierr);
166326c55118SMichael Lange   ierr = PetscSectionSetChart(rootSection, 0, nroots);CHKERRQ(ierr);
166426c55118SMichael Lange   if (label) {
166526c55118SMichael Lange     for (s = 0; s < label->numStrata; ++s) {
1666ad8374ffSToby Isaac       const PetscInt *points;
1667ad8374ffSToby Isaac 
1668ad8374ffSToby Isaac       ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr);
166926c55118SMichael Lange       for (l = 0; l < label->stratumSizes[s]; l++) {
1670ad8374ffSToby Isaac         ierr = PetscSectionGetDof(rootSection, points[l], &dof);CHKERRQ(ierr);
1671ad8374ffSToby Isaac         ierr = PetscSectionSetDof(rootSection, points[l], dof+1);CHKERRQ(ierr);
167226c55118SMichael Lange       }
1673ad8374ffSToby Isaac       ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr);
167426c55118SMichael Lange     }
167526c55118SMichael Lange   }
167626c55118SMichael Lange   ierr = PetscSectionSetUp(rootSection);CHKERRQ(ierr);
167726c55118SMichael Lange   /* Create a point-wise array of stratum values */
167826c55118SMichael Lange   ierr = PetscSectionGetStorageSize(rootSection, &size);CHKERRQ(ierr);
167926c55118SMichael Lange   ierr = PetscMalloc1(size, &rootStrata);CHKERRQ(ierr);
168026c55118SMichael Lange   ierr = PetscCalloc1(nroots, &rootIdx);CHKERRQ(ierr);
168126c55118SMichael Lange   if (label) {
168226c55118SMichael Lange     for (s = 0; s < label->numStrata; ++s) {
1683ad8374ffSToby Isaac       const PetscInt *points;
1684ad8374ffSToby Isaac 
1685ad8374ffSToby Isaac       ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr);
168626c55118SMichael Lange       for (l = 0; l < label->stratumSizes[s]; l++) {
1687ad8374ffSToby Isaac         const PetscInt p = points[l];
168826c55118SMichael Lange         ierr = PetscSectionGetOffset(rootSection, p, &offset);CHKERRQ(ierr);
168926c55118SMichael Lange         rootStrata[offset+rootIdx[p]++] = label->stratumValues[s];
169026c55118SMichael Lange       }
1691ad8374ffSToby Isaac       ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr);
169226c55118SMichael Lange     }
169326c55118SMichael Lange   }
169426c55118SMichael Lange   /* Build SF that maps label points to remote processes */
169526c55118SMichael Lange   ierr = PetscSectionCreate(comm, leafSection);CHKERRQ(ierr);
169626c55118SMichael Lange   ierr = PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection);CHKERRQ(ierr);
169726c55118SMichael Lange   ierr = PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF);CHKERRQ(ierr);
169826c55118SMichael Lange   ierr = PetscFree(remoteOffsets);CHKERRQ(ierr);
169926c55118SMichael Lange   /* Send the strata for each point over the derived SF */
170026c55118SMichael Lange   ierr = PetscSectionGetStorageSize(*leafSection, &size);CHKERRQ(ierr);
170126c55118SMichael Lange   ierr = PetscMalloc1(size, leafStrata);CHKERRQ(ierr);
1702ad227feaSJunchao Zhang   ierr = PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata,MPI_REPLACE);CHKERRQ(ierr);
1703ad227feaSJunchao Zhang   ierr = PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata,MPI_REPLACE);CHKERRQ(ierr);
170426c55118SMichael Lange   /* Clean up */
170526c55118SMichael Lange   ierr = PetscFree(rootStrata);CHKERRQ(ierr);
170626c55118SMichael Lange   ierr = PetscFree(rootIdx);CHKERRQ(ierr);
170726c55118SMichael Lange   ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr);
170826c55118SMichael Lange   ierr = PetscSFDestroy(&labelSF);CHKERRQ(ierr);
170926c55118SMichael Lange   PetscFunctionReturn(0);
171026c55118SMichael Lange }
171126c55118SMichael Lange 
171284f0b6dfSMatthew G. Knepley /*@
171384f0b6dfSMatthew G. Knepley   DMLabelDistribute - Create a new label pushed forward over the PetscSF
171484f0b6dfSMatthew G. Knepley 
17155b5e7992SMatthew G. Knepley   Collective on sf
17165b5e7992SMatthew G. Knepley 
171784f0b6dfSMatthew G. Knepley   Input Parameters:
171884f0b6dfSMatthew G. Knepley + label - the DMLabel
171984f0b6dfSMatthew G. Knepley - sf    - the map from old to new distribution
172084f0b6dfSMatthew G. Knepley 
172184f0b6dfSMatthew G. Knepley   Output Parameter:
172284f0b6dfSMatthew G. Knepley . labelnew - the new redistributed label
172384f0b6dfSMatthew G. Knepley 
172484f0b6dfSMatthew G. Knepley   Level: intermediate
172584f0b6dfSMatthew G. Knepley 
172684f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
172784f0b6dfSMatthew G. Knepley @*/
1728c58f1c22SToby Isaac PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew)
1729c58f1c22SToby Isaac {
1730c58f1c22SToby Isaac   MPI_Comm       comm;
173126c55118SMichael Lange   PetscSection   leafSection;
173226c55118SMichael Lange   PetscInt       p, pStart, pEnd, s, size, dof, offset, stratum;
173326c55118SMichael Lange   PetscInt      *leafStrata, *strataIdx;
1734ad8374ffSToby Isaac   PetscInt     **points;
1735d67d17b1SMatthew G. Knepley   const char    *lname = NULL;
1736c58f1c22SToby Isaac   char          *name;
1737c58f1c22SToby Isaac   PetscInt       nameSize;
1738e8f14785SLisandro Dalcin   PetscHSetI     stratumHash;
1739c58f1c22SToby Isaac   size_t         len = 0;
174026c55118SMichael Lange   PetscMPIInt    rank;
1741c58f1c22SToby Isaac   PetscErrorCode ierr;
1742c58f1c22SToby Isaac 
1743c58f1c22SToby Isaac   PetscFunctionBegin;
1744d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
1745f018e600SMatthew G. Knepley   if (label) {
1746f018e600SMatthew G. Knepley     PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1747f018e600SMatthew G. Knepley     ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
1748f018e600SMatthew G. Knepley   }
1749c58f1c22SToby Isaac   ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr);
1750ffc4695bSBarry Smith   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
1751c58f1c22SToby Isaac   /* Bcast name */
1752dd400576SPatrick Sanan   if (rank == 0) {
1753d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
1754d67d17b1SMatthew G. Knepley     ierr = PetscStrlen(lname, &len);CHKERRQ(ierr);
1755d67d17b1SMatthew G. Knepley   }
1756c58f1c22SToby Isaac   nameSize = len;
1757ffc4695bSBarry Smith   ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr);
1758c58f1c22SToby Isaac   ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr);
1759dd400576SPatrick Sanan   if (rank == 0) {ierr = PetscArraycpy(name, lname, nameSize+1);CHKERRQ(ierr);}
1760ffc4695bSBarry Smith   ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRMPI(ierr);
1761d67d17b1SMatthew G. Knepley   ierr = DMLabelCreate(PETSC_COMM_SELF, name, labelNew);CHKERRQ(ierr);
1762c58f1c22SToby Isaac   ierr = PetscFree(name);CHKERRQ(ierr);
176377d236dfSMichael Lange   /* Bcast defaultValue */
1764dd400576SPatrick Sanan   if (rank == 0) (*labelNew)->defaultValue = label->defaultValue;
1765ffc4695bSBarry Smith   ierr = MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr);
176626c55118SMichael Lange   /* Distribute stratum values over the SF and get the point mapping on the receiver */
176726c55118SMichael Lange   ierr = DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata);CHKERRQ(ierr);
17685cbdf6fcSMichael Lange   /* Determine received stratum values and initialise new label*/
1769e8f14785SLisandro Dalcin   ierr = PetscHSetICreate(&stratumHash);CHKERRQ(ierr);
177026c55118SMichael Lange   ierr = PetscSectionGetStorageSize(leafSection, &size);CHKERRQ(ierr);
1771e8f14785SLisandro Dalcin   for (p = 0; p < size; ++p) {ierr = PetscHSetIAdd(stratumHash, leafStrata[p]);CHKERRQ(ierr);}
1772e8f14785SLisandro Dalcin   ierr = PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata);CHKERRQ(ierr);
1773ad8374ffSToby Isaac   ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS);CHKERRQ(ierr);
1774ad8374ffSToby Isaac   for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE;
17755cbdf6fcSMichael Lange   ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues);CHKERRQ(ierr);
17765cbdf6fcSMichael Lange   /* Turn leafStrata into indices rather than stratum values */
17775cbdf6fcSMichael Lange   offset = 0;
1778e8f14785SLisandro Dalcin   ierr = PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues);CHKERRQ(ierr);
1779a205f1fdSToby Isaac   ierr = PetscSortInt((*labelNew)->numStrata,(*labelNew)->stratumValues);CHKERRQ(ierr);
178090e9b2aeSLisandro Dalcin   for (s = 0; s < (*labelNew)->numStrata; ++s) {
178190e9b2aeSLisandro Dalcin     ierr = PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s);CHKERRQ(ierr);
178290e9b2aeSLisandro Dalcin   }
17835cbdf6fcSMichael Lange   for (p = 0; p < size; ++p) {
1784231b9e6fSMatthew G. Knepley     for (s = 0; s < (*labelNew)->numStrata; ++s) {
1785231b9e6fSMatthew G. Knepley       if (leafStrata[p] == (*labelNew)->stratumValues[s]) {leafStrata[p] = s; break;}
17865cbdf6fcSMichael Lange     }
17875cbdf6fcSMichael Lange   }
1788c58f1c22SToby Isaac   /* Rebuild the point strata on the receiver */
1789c58f1c22SToby Isaac   ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->stratumSizes);CHKERRQ(ierr);
1790c58f1c22SToby Isaac   ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr);
1791c58f1c22SToby Isaac   for (p=pStart; p<pEnd; p++) {
1792c58f1c22SToby Isaac     ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr);
1793c58f1c22SToby Isaac     ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr);
1794c58f1c22SToby Isaac     for (s=0; s<dof; s++) {
1795c58f1c22SToby Isaac       (*labelNew)->stratumSizes[leafStrata[offset+s]]++;
1796c58f1c22SToby Isaac     }
1797c58f1c22SToby Isaac   }
1798c58f1c22SToby Isaac   ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->ht);CHKERRQ(ierr);
1799c58f1c22SToby Isaac   ierr = PetscMalloc1((*labelNew)->numStrata,&(*labelNew)->points);CHKERRQ(ierr);
1800ad8374ffSToby Isaac   ierr = PetscMalloc1((*labelNew)->numStrata,&points);CHKERRQ(ierr);
1801c58f1c22SToby Isaac   for (s = 0; s < (*labelNew)->numStrata; ++s) {
1802e8f14785SLisandro Dalcin     ierr = PetscHSetICreate(&(*labelNew)->ht[s]);CHKERRQ(ierr);
1803ad8374ffSToby Isaac     ierr = PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]));CHKERRQ(ierr);
1804c58f1c22SToby Isaac   }
1805c58f1c22SToby Isaac   /* Insert points into new strata */
1806c58f1c22SToby Isaac   ierr = PetscCalloc1((*labelNew)->numStrata, &strataIdx);CHKERRQ(ierr);
1807c58f1c22SToby Isaac   ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr);
1808c58f1c22SToby Isaac   for (p=pStart; p<pEnd; p++) {
1809c58f1c22SToby Isaac     ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr);
1810c58f1c22SToby Isaac     ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr);
1811c58f1c22SToby Isaac     for (s=0; s<dof; s++) {
1812c58f1c22SToby Isaac       stratum = leafStrata[offset+s];
1813ad8374ffSToby Isaac       points[stratum][strataIdx[stratum]++] = p;
1814c58f1c22SToby Isaac     }
1815c58f1c22SToby Isaac   }
1816ad8374ffSToby Isaac   for (s = 0; s < (*labelNew)->numStrata; s++) {
1817ad8374ffSToby Isaac     ierr = ISCreateGeneral(PETSC_COMM_SELF,(*labelNew)->stratumSizes[s],&(points[s][0]),PETSC_OWN_POINTER,&((*labelNew)->points[s]));CHKERRQ(ierr);
1818ad8374ffSToby Isaac     ierr = PetscObjectSetName((PetscObject)((*labelNew)->points[s]),"indices");CHKERRQ(ierr);
1819ad8374ffSToby Isaac   }
1820ad8374ffSToby Isaac   ierr = PetscFree(points);CHKERRQ(ierr);
1821e8f14785SLisandro Dalcin   ierr = PetscHSetIDestroy(&stratumHash);CHKERRQ(ierr);
1822c58f1c22SToby Isaac   ierr = PetscFree(leafStrata);CHKERRQ(ierr);
1823c58f1c22SToby Isaac   ierr = PetscFree(strataIdx);CHKERRQ(ierr);
1824c58f1c22SToby Isaac   ierr = PetscSectionDestroy(&leafSection);CHKERRQ(ierr);
1825c58f1c22SToby Isaac   PetscFunctionReturn(0);
1826c58f1c22SToby Isaac }
1827c58f1c22SToby Isaac 
18287937d9ceSMichael Lange /*@
18297937d9ceSMichael Lange   DMLabelGather - Gather all label values from leafs into roots
18307937d9ceSMichael Lange 
18315b5e7992SMatthew G. Knepley   Collective on sf
18325b5e7992SMatthew G. Knepley 
18337937d9ceSMichael Lange   Input Parameters:
18347937d9ceSMichael Lange + label - the DMLabel
183584f0b6dfSMatthew G. Knepley - sf - the Star Forest point communication map
18367937d9ceSMichael Lange 
183784f0b6dfSMatthew G. Knepley   Output Parameters:
183884f0b6dfSMatthew G. Knepley . labelNew - the new DMLabel with localised leaf values
18397937d9ceSMichael Lange 
18407937d9ceSMichael Lange   Level: developer
18417937d9ceSMichael Lange 
18427937d9ceSMichael Lange   Note: This is the inverse operation to DMLabelDistribute.
18437937d9ceSMichael Lange 
18447937d9ceSMichael Lange .seealso: DMLabelDistribute()
18457937d9ceSMichael Lange @*/
18467937d9ceSMichael Lange PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew)
18477937d9ceSMichael Lange {
18487937d9ceSMichael Lange   MPI_Comm       comm;
18497937d9ceSMichael Lange   PetscSection   rootSection;
18507937d9ceSMichael Lange   PetscSF        sfLabel;
18517937d9ceSMichael Lange   PetscSFNode   *rootPoints, *leafPoints;
18527937d9ceSMichael Lange   PetscInt       p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset;
18537937d9ceSMichael Lange   const PetscInt *rootDegree, *ilocal;
18547937d9ceSMichael Lange   PetscInt       *rootStrata;
1855d67d17b1SMatthew G. Knepley   const char    *lname;
18567937d9ceSMichael Lange   char          *name;
18577937d9ceSMichael Lange   PetscInt       nameSize;
18587937d9ceSMichael Lange   size_t         len = 0;
18599852e123SBarry Smith   PetscMPIInt    rank, size;
18607937d9ceSMichael Lange   PetscErrorCode ierr;
18617937d9ceSMichael Lange 
18627937d9ceSMichael Lange   PetscFunctionBegin;
1863d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1864d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
18657937d9ceSMichael Lange   ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr);
1866ffc4695bSBarry Smith   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
1867ffc4695bSBarry Smith   ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr);
18687937d9ceSMichael Lange   /* Bcast name */
1869dd400576SPatrick Sanan   if (rank == 0) {
1870d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
1871d67d17b1SMatthew G. Knepley     ierr = PetscStrlen(lname, &len);CHKERRQ(ierr);
1872d67d17b1SMatthew G. Knepley   }
18737937d9ceSMichael Lange   nameSize = len;
1874ffc4695bSBarry Smith   ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRMPI(ierr);
18757937d9ceSMichael Lange   ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr);
1876dd400576SPatrick Sanan   if (rank == 0) {ierr = PetscArraycpy(name, lname, nameSize+1);CHKERRQ(ierr);}
1877ffc4695bSBarry Smith   ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRMPI(ierr);
1878d67d17b1SMatthew G. Knepley   ierr = DMLabelCreate(PETSC_COMM_SELF, name, labelNew);CHKERRQ(ierr);
18797937d9ceSMichael Lange   ierr = PetscFree(name);CHKERRQ(ierr);
18807937d9ceSMichael Lange   /* Gather rank/index pairs of leaves into local roots to build
18817937d9ceSMichael Lange      an inverse, multi-rooted SF. Note that this ignores local leaf
18827937d9ceSMichael Lange      indexing due to the use of the multiSF in PetscSFGather. */
18837937d9ceSMichael Lange   ierr = PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL);CHKERRQ(ierr);
1884dc53bc9bSMatthew G. Knepley   ierr = PetscMalloc1(nroots, &leafPoints);CHKERRQ(ierr);
1885dc53bc9bSMatthew G. Knepley   for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1;
18867937d9ceSMichael Lange   for (p = 0; p < nleaves; p++) {
18878212dd46SStefano Zampini     PetscInt ilp = ilocal ? ilocal[p] : p;
18888212dd46SStefano Zampini 
18898212dd46SStefano Zampini     leafPoints[ilp].index = ilp;
18908212dd46SStefano Zampini     leafPoints[ilp].rank  = rank;
18917937d9ceSMichael Lange   }
18927937d9ceSMichael Lange   ierr = PetscSFComputeDegreeBegin(sf, &rootDegree);CHKERRQ(ierr);
18937937d9ceSMichael Lange   ierr = PetscSFComputeDegreeEnd(sf, &rootDegree);CHKERRQ(ierr);
18947937d9ceSMichael Lange   for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p];
18957937d9ceSMichael Lange   ierr = PetscMalloc1(nmultiroots, &rootPoints);CHKERRQ(ierr);
18967937d9ceSMichael Lange   ierr = PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr);
18977937d9ceSMichael Lange   ierr = PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr);
18987937d9ceSMichael Lange   ierr = PetscSFCreate(comm,& sfLabel);CHKERRQ(ierr);
18997937d9ceSMichael Lange   ierr = PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER);CHKERRQ(ierr);
19007937d9ceSMichael Lange   /* Migrate label over inverted SF to pull stratum values at leaves into roots. */
19017937d9ceSMichael Lange   ierr = DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata);CHKERRQ(ierr);
19027937d9ceSMichael Lange   /* Rebuild the point strata on the receiver */
19037937d9ceSMichael Lange   for (p = 0, idx = 0; p < nroots; p++) {
19047937d9ceSMichael Lange     for (d = 0; d < rootDegree[p]; d++) {
19057937d9ceSMichael Lange       ierr = PetscSectionGetDof(rootSection, idx+d, &dof);CHKERRQ(ierr);
19067937d9ceSMichael Lange       ierr = PetscSectionGetOffset(rootSection, idx+d, &offset);CHKERRQ(ierr);
19077937d9ceSMichael Lange       for (s = 0; s < dof; s++) {ierr = DMLabelSetValue(*labelNew, p, rootStrata[offset+s]);CHKERRQ(ierr);}
19087937d9ceSMichael Lange     }
19097937d9ceSMichael Lange     idx += rootDegree[p];
19107937d9ceSMichael Lange   }
191177e0c0e7SMichael Lange   ierr = PetscFree(leafPoints);CHKERRQ(ierr);
191277e0c0e7SMichael Lange   ierr = PetscFree(rootStrata);CHKERRQ(ierr);
191377e0c0e7SMichael Lange   ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr);
191477e0c0e7SMichael Lange   ierr = PetscSFDestroy(&sfLabel);CHKERRQ(ierr);
19157937d9ceSMichael Lange   PetscFunctionReturn(0);
19167937d9ceSMichael Lange }
19177937d9ceSMichael Lange 
191884f0b6dfSMatthew G. Knepley /*@
191984f0b6dfSMatthew G. Knepley   DMLabelConvertToSection - Make a PetscSection/IS pair that encodes the label
192084f0b6dfSMatthew G. Knepley 
19215b5e7992SMatthew G. Knepley   Not collective
19225b5e7992SMatthew G. Knepley 
192384f0b6dfSMatthew G. Knepley   Input Parameter:
192484f0b6dfSMatthew G. Knepley . label - the DMLabel
192584f0b6dfSMatthew G. Knepley 
192684f0b6dfSMatthew G. Knepley   Output Parameters:
192784f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum
192884f0b6dfSMatthew G. Knepley - is - An IS containing all the label points
192984f0b6dfSMatthew G. Knepley 
193084f0b6dfSMatthew G. Knepley   Level: developer
193184f0b6dfSMatthew G. Knepley 
193284f0b6dfSMatthew G. Knepley .seealso: DMLabelDistribute()
193384f0b6dfSMatthew G. Knepley @*/
1934c58f1c22SToby Isaac PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is)
1935c58f1c22SToby Isaac {
1936c58f1c22SToby Isaac   IS              vIS;
1937c58f1c22SToby Isaac   const PetscInt *values;
1938c58f1c22SToby Isaac   PetscInt       *points;
1939c58f1c22SToby Isaac   PetscInt        nV, vS = 0, vE = 0, v, N;
1940c58f1c22SToby Isaac   PetscErrorCode  ierr;
1941c58f1c22SToby Isaac 
1942c58f1c22SToby Isaac   PetscFunctionBegin;
1943d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1944c58f1c22SToby Isaac   ierr = DMLabelGetNumValues(label, &nV);CHKERRQ(ierr);
1945c58f1c22SToby Isaac   ierr = DMLabelGetValueIS(label, &vIS);CHKERRQ(ierr);
1946c58f1c22SToby Isaac   ierr = ISGetIndices(vIS, &values);CHKERRQ(ierr);
1947c58f1c22SToby Isaac   if (nV) {vS = values[0]; vE = values[0]+1;}
1948c58f1c22SToby Isaac   for (v = 1; v < nV; ++v) {
1949c58f1c22SToby Isaac     vS = PetscMin(vS, values[v]);
1950c58f1c22SToby Isaac     vE = PetscMax(vE, values[v]+1);
1951c58f1c22SToby Isaac   }
1952c58f1c22SToby Isaac   ierr = PetscSectionCreate(PETSC_COMM_SELF, section);CHKERRQ(ierr);
1953c58f1c22SToby Isaac   ierr = PetscSectionSetChart(*section, vS, vE);CHKERRQ(ierr);
1954c58f1c22SToby Isaac   for (v = 0; v < nV; ++v) {
1955c58f1c22SToby Isaac     PetscInt n;
1956c58f1c22SToby Isaac 
1957c58f1c22SToby Isaac     ierr = DMLabelGetStratumSize(label, values[v], &n);CHKERRQ(ierr);
1958c58f1c22SToby Isaac     ierr = PetscSectionSetDof(*section, values[v], n);CHKERRQ(ierr);
1959c58f1c22SToby Isaac   }
1960c58f1c22SToby Isaac   ierr = PetscSectionSetUp(*section);CHKERRQ(ierr);
1961c58f1c22SToby Isaac   ierr = PetscSectionGetStorageSize(*section, &N);CHKERRQ(ierr);
1962c58f1c22SToby Isaac   ierr = PetscMalloc1(N, &points);CHKERRQ(ierr);
1963c58f1c22SToby Isaac   for (v = 0; v < nV; ++v) {
1964c58f1c22SToby Isaac     IS              is;
1965c58f1c22SToby Isaac     const PetscInt *spoints;
1966c58f1c22SToby Isaac     PetscInt        dof, off, p;
1967c58f1c22SToby Isaac 
1968c58f1c22SToby Isaac     ierr = PetscSectionGetDof(*section, values[v], &dof);CHKERRQ(ierr);
1969c58f1c22SToby Isaac     ierr = PetscSectionGetOffset(*section, values[v], &off);CHKERRQ(ierr);
1970c58f1c22SToby Isaac     ierr = DMLabelGetStratumIS(label, values[v], &is);CHKERRQ(ierr);
1971c58f1c22SToby Isaac     ierr = ISGetIndices(is, &spoints);CHKERRQ(ierr);
1972c58f1c22SToby Isaac     for (p = 0; p < dof; ++p) points[off+p] = spoints[p];
1973c58f1c22SToby Isaac     ierr = ISRestoreIndices(is, &spoints);CHKERRQ(ierr);
1974c58f1c22SToby Isaac     ierr = ISDestroy(&is);CHKERRQ(ierr);
1975c58f1c22SToby Isaac   }
1976c58f1c22SToby Isaac   ierr = ISRestoreIndices(vIS, &values);CHKERRQ(ierr);
1977c58f1c22SToby Isaac   ierr = ISDestroy(&vIS);CHKERRQ(ierr);
1978c58f1c22SToby Isaac   ierr = ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
1979c58f1c22SToby Isaac   PetscFunctionReturn(0);
1980c58f1c22SToby Isaac }
1981c58f1c22SToby Isaac 
198284f0b6dfSMatthew G. Knepley /*@
1983c58f1c22SToby Isaac   PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using
1984c58f1c22SToby Isaac   the local section and an SF describing the section point overlap.
1985c58f1c22SToby Isaac 
19865b5e7992SMatthew G. Knepley   Collective on sf
19875b5e7992SMatthew G. Knepley 
1988c58f1c22SToby Isaac   Input Parameters:
1989c58f1c22SToby Isaac   + s - The PetscSection for the local field layout
1990c58f1c22SToby Isaac   . sf - The SF describing parallel layout of the section points
1991c58f1c22SToby Isaac   . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs
1992c58f1c22SToby Isaac   . label - The label specifying the points
1993c58f1c22SToby Isaac   - labelValue - The label stratum specifying the points
1994c58f1c22SToby Isaac 
1995c58f1c22SToby Isaac   Output Parameter:
1996c58f1c22SToby Isaac   . gsection - The PetscSection for the global field layout
1997c58f1c22SToby Isaac 
1998c58f1c22SToby Isaac   Note: This gives negative sizes and offsets to points not owned by this process
1999c58f1c22SToby Isaac 
2000c58f1c22SToby Isaac   Level: developer
2001c58f1c22SToby Isaac 
2002c58f1c22SToby Isaac .seealso: PetscSectionCreate()
2003c58f1c22SToby Isaac @*/
2004c58f1c22SToby Isaac PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection)
2005c58f1c22SToby Isaac {
2006c58f1c22SToby Isaac   PetscInt      *neg = NULL, *tmpOff = NULL;
2007c58f1c22SToby Isaac   PetscInt       pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots;
2008c58f1c22SToby Isaac   PetscErrorCode ierr;
2009c58f1c22SToby Isaac 
2010c58f1c22SToby Isaac   PetscFunctionBegin;
2011d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
2012d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
2013d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
2014c58f1c22SToby Isaac   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection);CHKERRQ(ierr);
2015c58f1c22SToby Isaac   ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr);
2016c58f1c22SToby Isaac   ierr = PetscSectionSetChart(*gsection, pStart, pEnd);CHKERRQ(ierr);
2017c58f1c22SToby Isaac   ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr);
2018c58f1c22SToby Isaac   if (nroots >= 0) {
20192c71b3e2SJacob Faibussowitsch     PetscCheckFalse(nroots < pEnd-pStart,PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %d < %d section size", nroots, pEnd-pStart);
2020c58f1c22SToby Isaac     ierr = PetscCalloc1(nroots, &neg);CHKERRQ(ierr);
2021c58f1c22SToby Isaac     if (nroots > pEnd-pStart) {
2022c58f1c22SToby Isaac       ierr = PetscCalloc1(nroots, &tmpOff);CHKERRQ(ierr);
2023c58f1c22SToby Isaac     } else {
2024c58f1c22SToby Isaac       tmpOff = &(*gsection)->atlasDof[-pStart];
2025c58f1c22SToby Isaac     }
2026c58f1c22SToby Isaac   }
2027c58f1c22SToby Isaac   /* Mark ghost points with negative dof */
2028c58f1c22SToby Isaac   for (p = pStart; p < pEnd; ++p) {
2029c58f1c22SToby Isaac     PetscInt value;
2030c58f1c22SToby Isaac 
2031c58f1c22SToby Isaac     ierr = DMLabelGetValue(label, p, &value);CHKERRQ(ierr);
2032c58f1c22SToby Isaac     if (value != labelValue) continue;
2033c58f1c22SToby Isaac     ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr);
2034c58f1c22SToby Isaac     ierr = PetscSectionSetDof(*gsection, p, dof);CHKERRQ(ierr);
2035c58f1c22SToby Isaac     ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr);
2036c58f1c22SToby Isaac     if (!includeConstraints && cdof > 0) {ierr = PetscSectionSetConstraintDof(*gsection, p, cdof);CHKERRQ(ierr);}
2037c58f1c22SToby Isaac     if (neg) neg[p] = -(dof+1);
2038c58f1c22SToby Isaac   }
2039c58f1c22SToby Isaac   ierr = PetscSectionSetUpBC(*gsection);CHKERRQ(ierr);
2040c58f1c22SToby Isaac   if (nroots >= 0) {
2041ad227feaSJunchao Zhang     ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr);
2042ad227feaSJunchao Zhang     ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr);
2043c58f1c22SToby Isaac     if (nroots > pEnd-pStart) {
2044c58f1c22SToby Isaac       for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];}
2045c58f1c22SToby Isaac     }
2046c58f1c22SToby Isaac   }
2047c58f1c22SToby Isaac   /* Calculate new sizes, get proccess offset, and calculate point offsets */
2048c58f1c22SToby Isaac   for (p = 0, off = 0; p < pEnd-pStart; ++p) {
2049c58f1c22SToby Isaac     cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0;
2050c58f1c22SToby Isaac     (*gsection)->atlasOff[p] = off;
2051c58f1c22SToby Isaac     off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p]-cdof : 0;
2052c58f1c22SToby Isaac   }
205355b25c41SPierre Jolivet   ierr       = MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s));CHKERRMPI(ierr);
2054c58f1c22SToby Isaac   globalOff -= off;
2055c58f1c22SToby Isaac   for (p = 0, off = 0; p < pEnd-pStart; ++p) {
2056c58f1c22SToby Isaac     (*gsection)->atlasOff[p] += globalOff;
2057c58f1c22SToby Isaac     if (neg) neg[p] = -((*gsection)->atlasOff[p]+1);
2058c58f1c22SToby Isaac   }
2059c58f1c22SToby Isaac   /* Put in negative offsets for ghost points */
2060c58f1c22SToby Isaac   if (nroots >= 0) {
2061ad227feaSJunchao Zhang     ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr);
2062ad227feaSJunchao Zhang     ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff,MPI_REPLACE);CHKERRQ(ierr);
2063c58f1c22SToby Isaac     if (nroots > pEnd-pStart) {
2064c58f1c22SToby Isaac       for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];}
2065c58f1c22SToby Isaac     }
2066c58f1c22SToby Isaac   }
2067c58f1c22SToby Isaac   if (nroots >= 0 && nroots > pEnd-pStart) {ierr = PetscFree(tmpOff);CHKERRQ(ierr);}
2068c58f1c22SToby Isaac   ierr = PetscFree(neg);CHKERRQ(ierr);
2069c58f1c22SToby Isaac   PetscFunctionReturn(0);
2070c58f1c22SToby Isaac }
2071c58f1c22SToby Isaac 
20725fdea053SToby Isaac typedef struct _n_PetscSectionSym_Label
20735fdea053SToby Isaac {
20745fdea053SToby Isaac   DMLabel           label;
20755fdea053SToby Isaac   PetscCopyMode     *modes;
20765fdea053SToby Isaac   PetscInt          *sizes;
20775fdea053SToby Isaac   const PetscInt    ***perms;
20785fdea053SToby Isaac   const PetscScalar ***rots;
20795fdea053SToby Isaac   PetscInt          (*minMaxOrients)[2];
20805fdea053SToby Isaac   PetscInt          numStrata; /* numStrata is only increasing, functions as a state */
20815fdea053SToby Isaac } PetscSectionSym_Label;
20825fdea053SToby Isaac 
20835fdea053SToby Isaac static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym)
20845fdea053SToby Isaac {
20855fdea053SToby Isaac   PetscInt              i, j;
20865fdea053SToby Isaac   PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data;
20875fdea053SToby Isaac   PetscErrorCode        ierr;
20885fdea053SToby Isaac 
20895fdea053SToby Isaac   PetscFunctionBegin;
20905fdea053SToby Isaac   for (i = 0; i <= sl->numStrata; i++) {
20915fdea053SToby Isaac     if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) {
20925fdea053SToby Isaac       for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) {
20935fdea053SToby Isaac         if (sl->perms[i]) {ierr = PetscFree(sl->perms[i][j]);CHKERRQ(ierr);}
20945fdea053SToby Isaac         if (sl->rots[i]) {ierr = PetscFree(sl->rots[i][j]);CHKERRQ(ierr);}
20955fdea053SToby Isaac       }
20965fdea053SToby Isaac       if (sl->perms[i]) {
20975fdea053SToby Isaac         const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]];
20985fdea053SToby Isaac 
20995fdea053SToby Isaac         ierr = PetscFree(perms);CHKERRQ(ierr);
21005fdea053SToby Isaac       }
21015fdea053SToby Isaac       if (sl->rots[i]) {
21025fdea053SToby Isaac         const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]];
21035fdea053SToby Isaac 
21045fdea053SToby Isaac         ierr = PetscFree(rots);CHKERRQ(ierr);
21055fdea053SToby Isaac       }
21065fdea053SToby Isaac     }
21075fdea053SToby Isaac   }
21085fdea053SToby Isaac   ierr = PetscFree5(sl->modes,sl->sizes,sl->perms,sl->rots,sl->minMaxOrients);CHKERRQ(ierr);
21095fdea053SToby Isaac   ierr = DMLabelDestroy(&sl->label);CHKERRQ(ierr);
21105fdea053SToby Isaac   sl->numStrata = 0;
21115fdea053SToby Isaac   PetscFunctionReturn(0);
21125fdea053SToby Isaac }
21135fdea053SToby Isaac 
21145fdea053SToby Isaac static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym)
21155fdea053SToby Isaac {
21165fdea053SToby Isaac   PetscErrorCode ierr;
21175fdea053SToby Isaac 
21185fdea053SToby Isaac   PetscFunctionBegin;
21195fdea053SToby Isaac   ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr);
21205fdea053SToby Isaac   ierr = PetscFree(sym->data);CHKERRQ(ierr);
21215fdea053SToby Isaac   PetscFunctionReturn(0);
21225fdea053SToby Isaac }
21235fdea053SToby Isaac 
21245fdea053SToby Isaac static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer)
21255fdea053SToby Isaac {
21265fdea053SToby Isaac   PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data;
21275fdea053SToby Isaac   PetscBool             isAscii;
21285fdea053SToby Isaac   DMLabel               label = sl->label;
2129d67d17b1SMatthew G. Knepley   const char           *name;
21305fdea053SToby Isaac   PetscErrorCode        ierr;
21315fdea053SToby Isaac 
21325fdea053SToby Isaac   PetscFunctionBegin;
21335fdea053SToby Isaac   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isAscii);CHKERRQ(ierr);
21345fdea053SToby Isaac   if (isAscii) {
21355fdea053SToby Isaac     PetscInt          i, j, k;
21365fdea053SToby Isaac     PetscViewerFormat format;
21375fdea053SToby Isaac 
21385fdea053SToby Isaac     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
21395fdea053SToby Isaac     if (label) {
21405fdea053SToby Isaac       ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
21415fdea053SToby Isaac       if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
21425fdea053SToby Isaac         ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
21435fdea053SToby Isaac         ierr = DMLabelView(label, viewer);CHKERRQ(ierr);
21445fdea053SToby Isaac         ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
21455fdea053SToby Isaac       } else {
2146d67d17b1SMatthew G. Knepley         ierr = PetscObjectGetName((PetscObject) sl->label, &name);CHKERRQ(ierr);
2147d67d17b1SMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"  Label '%s'\n",name);CHKERRQ(ierr);
21485fdea053SToby Isaac       }
21495fdea053SToby Isaac     } else {
21505fdea053SToby Isaac       ierr = PetscViewerASCIIPrintf(viewer, "No label given\n");CHKERRQ(ierr);
21515fdea053SToby Isaac     }
21525fdea053SToby Isaac     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
21535fdea053SToby Isaac     for (i = 0; i <= sl->numStrata; i++) {
21545fdea053SToby Isaac       PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue;
21555fdea053SToby Isaac 
21565fdea053SToby Isaac       if (!(sl->perms[i] || sl->rots[i])) {
21575fdea053SToby Isaac         ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point): no symmetries\n", value, sl->sizes[i]);CHKERRQ(ierr);
21585fdea053SToby Isaac       } else {
21595fdea053SToby Isaac       ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point):\n", value, sl->sizes[i]);CHKERRQ(ierr);
21605fdea053SToby Isaac         ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
21615fdea053SToby Isaac         ierr = PetscViewerASCIIPrintf(viewer, "Orientation range: [%D, %D)\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1]);CHKERRQ(ierr);
21625fdea053SToby Isaac         if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
21635fdea053SToby Isaac           ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
21645fdea053SToby Isaac           for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) {
21655fdea053SToby Isaac             if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) {
21665fdea053SToby Isaac               ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D: identity\n",j);CHKERRQ(ierr);
21675fdea053SToby Isaac             } else {
21685fdea053SToby Isaac               PetscInt tab;
21695fdea053SToby Isaac 
21705fdea053SToby Isaac               ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D:\n",j);CHKERRQ(ierr);
21715fdea053SToby Isaac               ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
21725fdea053SToby Isaac               ierr = PetscViewerASCIIGetTab(viewer,&tab);CHKERRQ(ierr);
21735fdea053SToby Isaac               if (sl->perms[i] && sl->perms[i][j]) {
21745fdea053SToby Isaac                 ierr = PetscViewerASCIIPrintf(viewer,"Permutation:");CHKERRQ(ierr);
21755fdea053SToby Isaac                 ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr);
21765fdea053SToby Isaac                 for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %D",sl->perms[i][j][k]);CHKERRQ(ierr);}
21775fdea053SToby Isaac                 ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
21785fdea053SToby Isaac                 ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr);
21795fdea053SToby Isaac               }
21805fdea053SToby Isaac               if (sl->rots[i] && sl->rots[i][j]) {
21815fdea053SToby Isaac                 ierr = PetscViewerASCIIPrintf(viewer,"Rotations:  ");CHKERRQ(ierr);
21825fdea053SToby Isaac                 ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr);
21835fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX)
21845fdea053SToby Isaac                 for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %+f+i*%+f",PetscRealPart(sl->rots[i][j][k]),PetscImaginaryPart(sl->rots[i][j][k]));CHKERRQ(ierr);}
21855fdea053SToby Isaac #else
21865fdea053SToby Isaac                 for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %+f",sl->rots[i][j][k]);CHKERRQ(ierr);}
21875fdea053SToby Isaac #endif
21885fdea053SToby Isaac                 ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
21895fdea053SToby Isaac                 ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr);
21905fdea053SToby Isaac               }
21915fdea053SToby Isaac               ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
21925fdea053SToby Isaac             }
21935fdea053SToby Isaac           }
21945fdea053SToby Isaac           ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
21955fdea053SToby Isaac         }
21965fdea053SToby Isaac         ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
21975fdea053SToby Isaac       }
21985fdea053SToby Isaac     }
21995fdea053SToby Isaac     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
22005fdea053SToby Isaac   }
22015fdea053SToby Isaac   PetscFunctionReturn(0);
22025fdea053SToby Isaac }
22035fdea053SToby Isaac 
22045fdea053SToby Isaac /*@
22055fdea053SToby Isaac   PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries
22065fdea053SToby Isaac 
22075fdea053SToby Isaac   Logically collective on sym
22085fdea053SToby Isaac 
22095fdea053SToby Isaac   Input parameters:
22105fdea053SToby Isaac + sym - the section symmetries
22115fdea053SToby Isaac - label - the DMLabel describing the types of points
22125fdea053SToby Isaac 
22135fdea053SToby Isaac   Level: developer:
22145fdea053SToby Isaac 
22155fdea053SToby Isaac .seealso: PetscSectionSymLabelSetStratum(), PetscSectionSymCreateLabel(), PetscSectionGetPointSyms()
22165fdea053SToby Isaac @*/
22175fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label)
22185fdea053SToby Isaac {
22195fdea053SToby Isaac   PetscSectionSym_Label *sl;
22205fdea053SToby Isaac   PetscErrorCode        ierr;
22215fdea053SToby Isaac 
22225fdea053SToby Isaac   PetscFunctionBegin;
22235fdea053SToby Isaac   PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1);
22245fdea053SToby Isaac   sl = (PetscSectionSym_Label *) sym->data;
22255fdea053SToby Isaac   if (sl->label && sl->label != label) {ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr);}
22265fdea053SToby Isaac   if (label) {
22275fdea053SToby Isaac     sl->label = label;
2228d67d17b1SMatthew G. Knepley     ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
22295fdea053SToby Isaac     ierr = DMLabelGetNumValues(label,&sl->numStrata);CHKERRQ(ierr);
22301a834cf9SToby Isaac     ierr = PetscMalloc5(sl->numStrata+1,&sl->modes,sl->numStrata+1,&sl->sizes,sl->numStrata+1,&sl->perms,sl->numStrata+1,&sl->rots,sl->numStrata+1,&sl->minMaxOrients);CHKERRQ(ierr);
22311a834cf9SToby Isaac     ierr = PetscMemzero((void *) sl->modes,(sl->numStrata+1)*sizeof(PetscCopyMode));CHKERRQ(ierr);
22321a834cf9SToby Isaac     ierr = PetscMemzero((void *) sl->sizes,(sl->numStrata+1)*sizeof(PetscInt));CHKERRQ(ierr);
22331a834cf9SToby Isaac     ierr = PetscMemzero((void *) sl->perms,(sl->numStrata+1)*sizeof(const PetscInt **));CHKERRQ(ierr);
22341a834cf9SToby Isaac     ierr = PetscMemzero((void *) sl->rots,(sl->numStrata+1)*sizeof(const PetscScalar **));CHKERRQ(ierr);
22351a834cf9SToby Isaac     ierr = PetscMemzero((void *) sl->minMaxOrients,(sl->numStrata+1)*sizeof(PetscInt[2]));CHKERRQ(ierr);
22365fdea053SToby Isaac   }
22375fdea053SToby Isaac   PetscFunctionReturn(0);
22385fdea053SToby Isaac }
22395fdea053SToby Isaac 
22405fdea053SToby Isaac /*@C
22415fdea053SToby Isaac   PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum
22425fdea053SToby Isaac 
22435b5e7992SMatthew G. Knepley   Logically collective on sym
22445fdea053SToby Isaac 
22455fdea053SToby Isaac   InputParameters:
22465b5e7992SMatthew G. Knepley + sym       - the section symmetries
22475fdea053SToby Isaac . stratum   - the stratum value in the label that we are assigning symmetries for
22485fdea053SToby Isaac . size      - the number of dofs for points in the stratum of the label
22495fdea053SToby Isaac . minOrient - the smallest orientation for a point in this stratum
22505fdea053SToby Isaac . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient))
22515fdea053SToby Isaac . mode      - how sym should copy the perms and rots arrays
22525fdea053SToby Isaac . perms     - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation.  A NULL permutation is the identity
2253a2b725a8SWilliam Gropp - rots      - NULL if there are no rotations, or (maxOrient - minOrient) sets of rotations, one for each orientation.  A NULL set of orientations is the identity
22545fdea053SToby Isaac 
22555fdea053SToby Isaac   Level: developer
22565fdea053SToby Isaac 
22575fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetPointSyms(), PetscSectionSymCreateLabel()
22585fdea053SToby Isaac @*/
22595fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots)
22605fdea053SToby Isaac {
22615fdea053SToby Isaac   PetscSectionSym_Label *sl;
2262d67d17b1SMatthew G. Knepley   const char            *name;
2263d67d17b1SMatthew G. Knepley   PetscInt               i, j, k;
22645fdea053SToby Isaac   PetscErrorCode         ierr;
22655fdea053SToby Isaac 
22665fdea053SToby Isaac   PetscFunctionBegin;
22675fdea053SToby Isaac   PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1);
22685fdea053SToby Isaac   sl = (PetscSectionSym_Label *) sym->data;
22692c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!sl->label,PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_WRONGSTATE,"No label set yet");
22705fdea053SToby Isaac   for (i = 0; i <= sl->numStrata; i++) {
22715fdea053SToby Isaac     PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue;
22725fdea053SToby Isaac 
22735fdea053SToby Isaac     if (stratum == value) break;
22745fdea053SToby Isaac   }
2275d67d17b1SMatthew G. Knepley   ierr = PetscObjectGetName((PetscObject) sl->label, &name);CHKERRQ(ierr);
22762c71b3e2SJacob Faibussowitsch   PetscCheckFalse(i > sl->numStrata,PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_OUTOFRANGE,"Stratum %D not found in label %s",stratum,name);
22775fdea053SToby Isaac   sl->sizes[i] = size;
22785fdea053SToby Isaac   sl->modes[i] = mode;
22795fdea053SToby Isaac   sl->minMaxOrients[i][0] = minOrient;
22805fdea053SToby Isaac   sl->minMaxOrients[i][1] = maxOrient;
22815fdea053SToby Isaac   if (mode == PETSC_COPY_VALUES) {
22825fdea053SToby Isaac     if (perms) {
22835fdea053SToby Isaac       PetscInt    **ownPerms;
22845fdea053SToby Isaac 
22855fdea053SToby Isaac       ierr = PetscCalloc1(maxOrient - minOrient,&ownPerms);CHKERRQ(ierr);
22865fdea053SToby Isaac       for (j = 0; j < maxOrient-minOrient; j++) {
22875fdea053SToby Isaac         if (perms[j]) {
22885fdea053SToby Isaac           ierr = PetscMalloc1(size,&ownPerms[j]);CHKERRQ(ierr);
22895fdea053SToby Isaac           for (k = 0; k < size; k++) {ownPerms[j][k] = perms[j][k];}
22905fdea053SToby Isaac         }
22915fdea053SToby Isaac       }
22925fdea053SToby Isaac       sl->perms[i] = (const PetscInt **) &ownPerms[-minOrient];
22935fdea053SToby Isaac     }
22945fdea053SToby Isaac     if (rots) {
22955fdea053SToby Isaac       PetscScalar **ownRots;
22965fdea053SToby Isaac 
22975fdea053SToby Isaac       ierr = PetscCalloc1(maxOrient - minOrient,&ownRots);CHKERRQ(ierr);
22985fdea053SToby Isaac       for (j = 0; j < maxOrient-minOrient; j++) {
22995fdea053SToby Isaac         if (rots[j]) {
23005fdea053SToby Isaac           ierr = PetscMalloc1(size,&ownRots[j]);CHKERRQ(ierr);
23015fdea053SToby Isaac           for (k = 0; k < size; k++) {ownRots[j][k] = rots[j][k];}
23025fdea053SToby Isaac         }
23035fdea053SToby Isaac       }
23045fdea053SToby Isaac       sl->rots[i] = (const PetscScalar **) &ownRots[-minOrient];
23055fdea053SToby Isaac     }
23065fdea053SToby Isaac   } else {
23075fdea053SToby Isaac     sl->perms[i] = perms ? &perms[-minOrient] : NULL;
23085fdea053SToby Isaac     sl->rots[i]  = rots ? &rots[-minOrient] : NULL;
23095fdea053SToby Isaac   }
23105fdea053SToby Isaac   PetscFunctionReturn(0);
23115fdea053SToby Isaac }
23125fdea053SToby Isaac 
23135fdea053SToby Isaac static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots)
23145fdea053SToby Isaac {
23155fdea053SToby Isaac   PetscInt              i, j, numStrata;
23165fdea053SToby Isaac   PetscSectionSym_Label *sl;
23175fdea053SToby Isaac   DMLabel               label;
23185fdea053SToby Isaac   PetscErrorCode        ierr;
23195fdea053SToby Isaac 
23205fdea053SToby Isaac   PetscFunctionBegin;
23215fdea053SToby Isaac   sl = (PetscSectionSym_Label *) sym->data;
23225fdea053SToby Isaac   numStrata = sl->numStrata;
23235fdea053SToby Isaac   label     = sl->label;
23245fdea053SToby Isaac   for (i = 0; i < numPoints; i++) {
23255fdea053SToby Isaac     PetscInt point = points[2*i];
23265fdea053SToby Isaac     PetscInt ornt  = points[2*i+1];
23275fdea053SToby Isaac 
23285fdea053SToby Isaac     for (j = 0; j < numStrata; j++) {
23295fdea053SToby Isaac       if (label->validIS[j]) {
23305fdea053SToby Isaac         PetscInt k;
23315fdea053SToby Isaac 
23325fdea053SToby Isaac         ierr = ISLocate(label->points[j],point,&k);CHKERRQ(ierr);
23335fdea053SToby Isaac         if (k >= 0) break;
23345fdea053SToby Isaac       } else {
23355fdea053SToby Isaac         PetscBool has;
23365fdea053SToby Isaac 
2337b9907514SLisandro Dalcin         ierr = PetscHSetIHas(label->ht[j], point, &has);CHKERRQ(ierr);
23385fdea053SToby Isaac         if (has) break;
23395fdea053SToby Isaac       }
23405fdea053SToby Isaac     }
23412c71b3e2SJacob Faibussowitsch     PetscCheckFalse((sl->minMaxOrients[j][1] > sl->minMaxOrients[j][0]) && (ornt < sl->minMaxOrients[j][0] || ornt >= sl->minMaxOrients[j][1]),PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"point %D orientation %D not in range [%D, %D) for stratum %D",point,ornt,sl->minMaxOrients[j][0],sl->minMaxOrients[j][1],j < numStrata ? label->stratumValues[j] : label->defaultValue);
23425fdea053SToby Isaac     if (perms) {perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL;}
23435fdea053SToby Isaac     if (rots) {rots[i]  = sl->rots[j] ? sl->rots[j][ornt] : NULL;}
23445fdea053SToby Isaac   }
23455fdea053SToby Isaac   PetscFunctionReturn(0);
23465fdea053SToby Isaac }
23475fdea053SToby Isaac 
23485fdea053SToby Isaac PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym)
23495fdea053SToby Isaac {
23505fdea053SToby Isaac   PetscSectionSym_Label *sl;
23515fdea053SToby Isaac   PetscErrorCode        ierr;
23525fdea053SToby Isaac 
23535fdea053SToby Isaac   PetscFunctionBegin;
23545fdea053SToby Isaac   ierr = PetscNewLog(sym,&sl);CHKERRQ(ierr);
23555fdea053SToby Isaac   sym->ops->getpoints = PetscSectionSymGetPoints_Label;
23565fdea053SToby Isaac   sym->ops->view      = PetscSectionSymView_Label;
23575fdea053SToby Isaac   sym->ops->destroy   = PetscSectionSymDestroy_Label;
23585fdea053SToby Isaac   sym->data           = (void *) sl;
23595fdea053SToby Isaac   PetscFunctionReturn(0);
23605fdea053SToby Isaac }
23615fdea053SToby Isaac 
23625fdea053SToby Isaac /*@
23635fdea053SToby Isaac   PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label
23645fdea053SToby Isaac 
23655fdea053SToby Isaac   Collective
23665fdea053SToby Isaac 
23675fdea053SToby Isaac   Input Parameters:
23685fdea053SToby Isaac + comm - the MPI communicator for the new symmetry
23695fdea053SToby Isaac - label - the label defining the strata
23705fdea053SToby Isaac 
23715fdea053SToby Isaac   Output Parameters:
23725fdea053SToby Isaac . sym - the section symmetries
23735fdea053SToby Isaac 
23745fdea053SToby Isaac   Level: developer
23755fdea053SToby Isaac 
23765fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetSym(), PetscSectionSymLabelSetStratum(), PetscSectionGetPointSyms()
23775fdea053SToby Isaac @*/
23785fdea053SToby Isaac PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym)
23795fdea053SToby Isaac {
23805fdea053SToby Isaac   PetscErrorCode        ierr;
23815fdea053SToby Isaac 
23825fdea053SToby Isaac   PetscFunctionBegin;
23835fdea053SToby Isaac   ierr = DMInitializePackage();CHKERRQ(ierr);
23845fdea053SToby Isaac   ierr = PetscSectionSymCreate(comm,sym);CHKERRQ(ierr);
23855fdea053SToby Isaac   ierr = PetscSectionSymSetType(*sym,PETSCSECTIONSYMLABEL);CHKERRQ(ierr);
23865fdea053SToby Isaac   ierr = PetscSectionSymLabelSetLabel(*sym,label);CHKERRQ(ierr);
23875fdea053SToby Isaac   PetscFunctionReturn(0);
23885fdea053SToby Isaac }
2389