xref: /petsc/src/dm/label/dmlabel.c (revision 05ab7a9f6ebf616e66f7cf98327844f9f1e8d2ff)
15fdea053SToby Isaac #include <petscdm.h>
2c58f1c22SToby Isaac #include <petsc/private/dmlabelimpl.h>   /*I      "petscdmlabel.h"   I*/
3c58f1c22SToby Isaac #include <petsc/private/isimpl.h>        /*I      "petscis.h"        I*/
4c58f1c22SToby Isaac #include <petscsf.h>
5c58f1c22SToby Isaac 
6c58f1c22SToby Isaac /*@C
7c58f1c22SToby Isaac   DMLabelCreate - Create a DMLabel object, which is a multimap
8c58f1c22SToby Isaac 
95b5e7992SMatthew G. Knepley   Collective
105b5e7992SMatthew G. Knepley 
11d67d17b1SMatthew G. Knepley   Input parameters:
12d67d17b1SMatthew G. Knepley + comm - The communicator, usually PETSC_COMM_SELF
13d67d17b1SMatthew G. Knepley - name - The label name
14c58f1c22SToby Isaac 
15c58f1c22SToby Isaac   Output parameter:
16c58f1c22SToby Isaac . label - The DMLabel
17c58f1c22SToby Isaac 
18c58f1c22SToby Isaac   Level: beginner
19c58f1c22SToby Isaac 
20*05ab7a9fSVaclav Hapla   Notes:
21*05ab7a9fSVaclav Hapla   The label name is actually usual PetscObject name.
22*05ab7a9fSVaclav Hapla   One can get/set it with PetscObjectGetName()/PetscObjectSetName().
23*05ab7a9fSVaclav Hapla 
24c58f1c22SToby Isaac .seealso: DMLabelDestroy()
25c58f1c22SToby Isaac @*/
26d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelCreate(MPI_Comm comm, const char name[], DMLabel *label)
27c58f1c22SToby Isaac {
28c58f1c22SToby Isaac   PetscErrorCode ierr;
29c58f1c22SToby Isaac 
30c58f1c22SToby Isaac   PetscFunctionBegin;
31d67d17b1SMatthew G. Knepley   PetscValidPointer(label,2);
32d67d17b1SMatthew G. Knepley   ierr = DMInitializePackage();CHKERRQ(ierr);
33c58f1c22SToby Isaac 
34d67d17b1SMatthew G. Knepley   ierr = PetscHeaderCreate(*label,DMLABEL_CLASSID,"DMLabel","DMLabel","DM",comm,DMLabelDestroy,DMLabelView);CHKERRQ(ierr);
35d67d17b1SMatthew G. Knepley 
36c58f1c22SToby Isaac   (*label)->numStrata      = 0;
375aa44df4SToby Isaac   (*label)->defaultValue   = -1;
38c58f1c22SToby Isaac   (*label)->stratumValues  = NULL;
39ad8374ffSToby Isaac   (*label)->validIS        = NULL;
40c58f1c22SToby Isaac   (*label)->stratumSizes   = NULL;
41c58f1c22SToby Isaac   (*label)->points         = NULL;
42c58f1c22SToby Isaac   (*label)->ht             = NULL;
43c58f1c22SToby Isaac   (*label)->pStart         = -1;
44c58f1c22SToby Isaac   (*label)->pEnd           = -1;
45c58f1c22SToby Isaac   (*label)->bt             = NULL;
46b9907514SLisandro Dalcin   ierr = PetscHMapICreate(&(*label)->hmap);CHKERRQ(ierr);
47d67d17b1SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *label, name);CHKERRQ(ierr);
48c58f1c22SToby Isaac   PetscFunctionReturn(0);
49c58f1c22SToby Isaac }
50c58f1c22SToby Isaac 
51c58f1c22SToby Isaac /*
52c58f1c22SToby Isaac   DMLabelMakeValid_Private - Transfer stratum data from the hash format to the sorted list format
53c58f1c22SToby Isaac 
545b5e7992SMatthew G. Knepley   Not collective
555b5e7992SMatthew G. Knepley 
56c58f1c22SToby Isaac   Input parameter:
57c58f1c22SToby Isaac + label - The DMLabel
58c58f1c22SToby Isaac - v - The stratum value
59c58f1c22SToby Isaac 
60c58f1c22SToby Isaac   Output parameter:
61c58f1c22SToby Isaac . label - The DMLabel with stratum in sorted list format
62c58f1c22SToby Isaac 
63c58f1c22SToby Isaac   Level: developer
64c58f1c22SToby Isaac 
65c58f1c22SToby Isaac .seealso: DMLabelCreate()
66c58f1c22SToby Isaac */
67c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeValid_Private(DMLabel label, PetscInt v)
68c58f1c22SToby Isaac {
69277ea44aSLisandro Dalcin   IS             is;
70b9907514SLisandro Dalcin   PetscInt       off = 0, *pointArray, p;
71c58f1c22SToby Isaac   PetscErrorCode ierr;
72c58f1c22SToby Isaac 
73b9907514SLisandro Dalcin   if (PetscLikely(v >= 0 && v < label->numStrata) && label->validIS[v]) return 0;
74c58f1c22SToby Isaac   PetscFunctionBegin;
750c3c4a36SLisandro Dalcin   if (v < 0 || v >= label->numStrata) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %D in DMLabelMakeValid_Private\n", v);
76e8f14785SLisandro Dalcin   ierr = PetscHSetIGetSize(label->ht[v], &label->stratumSizes[v]);CHKERRQ(ierr);
77ad8374ffSToby Isaac   ierr = PetscMalloc1(label->stratumSizes[v], &pointArray);CHKERRQ(ierr);
78e8f14785SLisandro Dalcin   ierr = PetscHSetIGetElems(label->ht[v], &off, pointArray);CHKERRQ(ierr);
79b9907514SLisandro Dalcin   ierr = PetscHSetIClear(label->ht[v]);CHKERRQ(ierr);
80ad8374ffSToby Isaac   ierr = PetscSortInt(label->stratumSizes[v], pointArray);CHKERRQ(ierr);
81c58f1c22SToby Isaac   if (label->bt) {
82c58f1c22SToby Isaac     for (p = 0; p < label->stratumSizes[v]; ++p) {
83ad8374ffSToby Isaac       const PetscInt point = pointArray[p];
84c58f1c22SToby Isaac       if ((point < label->pStart) || (point >= label->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd);
85c58f1c22SToby Isaac       ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr);
86c58f1c22SToby Isaac     }
87c58f1c22SToby Isaac   }
88277ea44aSLisandro Dalcin   ierr = ISCreateGeneral(PETSC_COMM_SELF, label->stratumSizes[v], pointArray, PETSC_OWN_POINTER, &is);CHKERRQ(ierr);
89277ea44aSLisandro Dalcin   ierr = PetscObjectSetName((PetscObject) is, "indices");CHKERRQ(ierr);
90277ea44aSLisandro Dalcin   label->points[v]  = is;
91ad8374ffSToby Isaac   label->validIS[v] = PETSC_TRUE;
92d67d17b1SMatthew G. Knepley   ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr);
93c58f1c22SToby Isaac   PetscFunctionReturn(0);
94c58f1c22SToby Isaac }
95c58f1c22SToby Isaac 
96c58f1c22SToby Isaac /*
97c58f1c22SToby Isaac   DMLabelMakeAllValid_Private - Transfer all strata from the hash format to the sorted list format
98c58f1c22SToby Isaac 
995b5e7992SMatthew G. Knepley   Not collective
1005b5e7992SMatthew G. Knepley 
101c58f1c22SToby Isaac   Input parameter:
102c58f1c22SToby Isaac . label - The DMLabel
103c58f1c22SToby Isaac 
104c58f1c22SToby Isaac   Output parameter:
105c58f1c22SToby Isaac . label - The DMLabel with all strata in sorted list format
106c58f1c22SToby Isaac 
107c58f1c22SToby Isaac   Level: developer
108c58f1c22SToby Isaac 
109c58f1c22SToby Isaac .seealso: DMLabelCreate()
110c58f1c22SToby Isaac */
111c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeAllValid_Private(DMLabel label)
112c58f1c22SToby Isaac {
113c58f1c22SToby Isaac   PetscInt       v;
114c58f1c22SToby Isaac   PetscErrorCode ierr;
115c58f1c22SToby Isaac 
116c58f1c22SToby Isaac   PetscFunctionBegin;
117c58f1c22SToby Isaac   for (v = 0; v < label->numStrata; v++){
118c58f1c22SToby Isaac     ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr);
119c58f1c22SToby Isaac   }
120c58f1c22SToby Isaac   PetscFunctionReturn(0);
121c58f1c22SToby Isaac }
122c58f1c22SToby Isaac 
123c58f1c22SToby Isaac /*
124c58f1c22SToby Isaac   DMLabelMakeInvalid_Private - Transfer stratum data from the sorted list format to the hash format
125c58f1c22SToby Isaac 
1265b5e7992SMatthew G. Knepley   Not collective
1275b5e7992SMatthew G. Knepley 
128c58f1c22SToby Isaac   Input parameter:
129c58f1c22SToby Isaac + label - The DMLabel
130c58f1c22SToby Isaac - v - The stratum value
131c58f1c22SToby Isaac 
132c58f1c22SToby Isaac   Output parameter:
133c58f1c22SToby Isaac . label - The DMLabel with stratum in hash format
134c58f1c22SToby Isaac 
135c58f1c22SToby Isaac   Level: developer
136c58f1c22SToby Isaac 
137c58f1c22SToby Isaac .seealso: DMLabelCreate()
138c58f1c22SToby Isaac */
139c58f1c22SToby Isaac static PetscErrorCode DMLabelMakeInvalid_Private(DMLabel label, PetscInt v)
140c58f1c22SToby Isaac {
141c58f1c22SToby Isaac   PetscInt       p;
142ad8374ffSToby Isaac   const PetscInt *points;
143c58f1c22SToby Isaac   PetscErrorCode ierr;
144c58f1c22SToby Isaac 
145b9907514SLisandro Dalcin   if (PetscLikely(v >= 0 && v < label->numStrata) && !label->validIS[v]) return 0;
146c58f1c22SToby Isaac   PetscFunctionBegin;
1470c3c4a36SLisandro Dalcin   if (v < 0 || v >= label->numStrata) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Trying to access invalid stratum %D in DMLabelMakeInvalid_Private\n", v);
148ad8374ffSToby Isaac   if (label->points[v]) {
149ad8374ffSToby Isaac     ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr);
150e8f14785SLisandro Dalcin     for (p = 0; p < label->stratumSizes[v]; ++p) {
151e8f14785SLisandro Dalcin       ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr);
152e8f14785SLisandro Dalcin     }
153ad8374ffSToby Isaac     ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr);
154ad8374ffSToby Isaac     ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr);
155ad8374ffSToby Isaac   }
156ad8374ffSToby Isaac   label->validIS[v] = PETSC_FALSE;
157c58f1c22SToby Isaac   PetscFunctionReturn(0);
158c58f1c22SToby Isaac }
159c58f1c22SToby Isaac 
160b9907514SLisandro Dalcin #if !defined(DMLABEL_LOOKUP_THRESHOLD)
161b9907514SLisandro Dalcin #define DMLABEL_LOOKUP_THRESHOLD 16
162b9907514SLisandro Dalcin #endif
163b9907514SLisandro Dalcin 
1640c3c4a36SLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode DMLabelLookupStratum(DMLabel label, PetscInt value, PetscInt *index)
1650c3c4a36SLisandro Dalcin {
1660c3c4a36SLisandro Dalcin   PetscInt       v;
167b9907514SLisandro Dalcin   PetscErrorCode ierr;
1680e79e033SBarry Smith 
1690c3c4a36SLisandro Dalcin   PetscFunctionBegin;
1700e79e033SBarry Smith   *index = -1;
171b9907514SLisandro Dalcin   if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) {
172b9907514SLisandro Dalcin     for (v = 0; v < label->numStrata; ++v)
173b9907514SLisandro Dalcin       if (label->stratumValues[v] == value) {*index = v; break;}
174b9907514SLisandro Dalcin   } else {
175b9907514SLisandro Dalcin     ierr = PetscHMapIGet(label->hmap, value, index);CHKERRQ(ierr);
1760e79e033SBarry Smith   }
17790e9b2aeSLisandro Dalcin #if defined(PETSC_USE_DEBUG)
17890e9b2aeSLisandro Dalcin   { /* Check strata hash map consistency */
17990e9b2aeSLisandro Dalcin     PetscInt len, loc = -1;
18090e9b2aeSLisandro Dalcin     ierr = PetscHMapIGetSize(label->hmap, &len);CHKERRQ(ierr);
18190e9b2aeSLisandro Dalcin     if (len != label->numStrata) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map size");
18290e9b2aeSLisandro Dalcin     if (label->numStrata <= DMLABEL_LOOKUP_THRESHOLD) {
18390e9b2aeSLisandro Dalcin       ierr = PetscHMapIGet(label->hmap, value, &loc);CHKERRQ(ierr);
18490e9b2aeSLisandro Dalcin     } else {
18590e9b2aeSLisandro Dalcin       for (v = 0; v < label->numStrata; ++v)
18690e9b2aeSLisandro Dalcin         if (label->stratumValues[v] == value) {loc = v; break;}
18790e9b2aeSLisandro Dalcin     }
18890e9b2aeSLisandro Dalcin     if (loc != *index) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Inconsistent strata hash map lookup");
18990e9b2aeSLisandro Dalcin   }
19090e9b2aeSLisandro Dalcin #endif
1910c3c4a36SLisandro Dalcin   PetscFunctionReturn(0);
1920c3c4a36SLisandro Dalcin }
1930c3c4a36SLisandro Dalcin 
194b9907514SLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode DMLabelNewStratum(DMLabel label, PetscInt value, PetscInt *index)
195c58f1c22SToby Isaac {
196b9907514SLisandro Dalcin   PetscInt       v;
197b9907514SLisandro Dalcin   PetscInt      *tmpV;
198b9907514SLisandro Dalcin   PetscInt      *tmpS;
199b9907514SLisandro Dalcin   PetscHSetI    *tmpH, ht;
200b9907514SLisandro Dalcin   IS            *tmpP, is;
201c58f1c22SToby Isaac   PetscBool     *tmpB;
202b9907514SLisandro Dalcin   PetscHMapI     hmap = label->hmap;
203c58f1c22SToby Isaac   PetscErrorCode ierr;
204c58f1c22SToby Isaac 
205c58f1c22SToby Isaac   PetscFunctionBegin;
206b9907514SLisandro Dalcin   v    = label->numStrata;
207b9907514SLisandro Dalcin   tmpV = label->stratumValues;
208b9907514SLisandro Dalcin   tmpS = label->stratumSizes;
209b9907514SLisandro Dalcin   tmpH = label->ht;
210b9907514SLisandro Dalcin   tmpP = label->points;
211b9907514SLisandro Dalcin   tmpB = label->validIS;
2128e1f8cf0SLisandro Dalcin   { /* TODO: PetscRealloc() is broken, use malloc+memcpy+free  */
2138e1f8cf0SLisandro Dalcin     PetscInt   *oldV = tmpV;
2148e1f8cf0SLisandro Dalcin     PetscInt   *oldS = tmpS;
2158e1f8cf0SLisandro Dalcin     PetscHSetI *oldH = tmpH;
2168e1f8cf0SLisandro Dalcin     IS         *oldP = tmpP;
2178e1f8cf0SLisandro Dalcin     PetscBool  *oldB = tmpB;
2188e1f8cf0SLisandro Dalcin     ierr = PetscMalloc((v+1)*sizeof(*tmpV), &tmpV);CHKERRQ(ierr);
2198e1f8cf0SLisandro Dalcin     ierr = PetscMalloc((v+1)*sizeof(*tmpS), &tmpS);CHKERRQ(ierr);
2208e1f8cf0SLisandro Dalcin     ierr = PetscMalloc((v+1)*sizeof(*tmpH), &tmpH);CHKERRQ(ierr);
2218e1f8cf0SLisandro Dalcin     ierr = PetscMalloc((v+1)*sizeof(*tmpP), &tmpP);CHKERRQ(ierr);
2228e1f8cf0SLisandro Dalcin     ierr = PetscMalloc((v+1)*sizeof(*tmpB), &tmpB);CHKERRQ(ierr);
223580bdb30SBarry Smith     ierr = PetscArraycpy(tmpV, oldV, v);CHKERRQ(ierr);
224580bdb30SBarry Smith     ierr = PetscArraycpy(tmpS, oldS, v);CHKERRQ(ierr);
225580bdb30SBarry Smith     ierr = PetscArraycpy(tmpH, oldH, v);CHKERRQ(ierr);
226580bdb30SBarry Smith     ierr = PetscArraycpy(tmpP, oldP, v);CHKERRQ(ierr);
227580bdb30SBarry Smith     ierr = PetscArraycpy(tmpB, oldB, v);CHKERRQ(ierr);
2288e1f8cf0SLisandro Dalcin     ierr = PetscFree(oldV);CHKERRQ(ierr);
2298e1f8cf0SLisandro Dalcin     ierr = PetscFree(oldS);CHKERRQ(ierr);
2308e1f8cf0SLisandro Dalcin     ierr = PetscFree(oldH);CHKERRQ(ierr);
2318e1f8cf0SLisandro Dalcin     ierr = PetscFree(oldP);CHKERRQ(ierr);
2328e1f8cf0SLisandro Dalcin     ierr = PetscFree(oldB);CHKERRQ(ierr);
2338e1f8cf0SLisandro Dalcin   }
234b9907514SLisandro Dalcin   label->numStrata     = v+1;
235c58f1c22SToby Isaac   label->stratumValues = tmpV;
236c58f1c22SToby Isaac   label->stratumSizes  = tmpS;
237c58f1c22SToby Isaac   label->ht            = tmpH;
238c58f1c22SToby Isaac   label->points        = tmpP;
239ad8374ffSToby Isaac   label->validIS       = tmpB;
240b9907514SLisandro Dalcin   ierr = PetscHSetICreate(&ht);CHKERRQ(ierr);
241b9907514SLisandro Dalcin   ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is);CHKERRQ(ierr);
242b9907514SLisandro Dalcin   ierr = PetscHMapISet(hmap, value, v);CHKERRQ(ierr);
243b9907514SLisandro Dalcin   tmpV[v] = value;
244b9907514SLisandro Dalcin   tmpS[v] = 0;
245b9907514SLisandro Dalcin   tmpH[v] = ht;
246b9907514SLisandro Dalcin   tmpP[v] = is;
247b9907514SLisandro Dalcin   tmpB[v] = PETSC_TRUE;
248277ea44aSLisandro Dalcin   ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr);
2490c3c4a36SLisandro Dalcin   *index = v;
2500c3c4a36SLisandro Dalcin   PetscFunctionReturn(0);
2510c3c4a36SLisandro Dalcin }
2520c3c4a36SLisandro Dalcin 
253b9907514SLisandro Dalcin PETSC_STATIC_INLINE PetscErrorCode DMLabelLookupAddStratum(DMLabel label, PetscInt value, PetscInt *index)
254b9907514SLisandro Dalcin {
255b9907514SLisandro Dalcin   PetscErrorCode ierr;
256b9907514SLisandro Dalcin   PetscFunctionBegin;
257b9907514SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, index);CHKERRQ(ierr);
258b9907514SLisandro Dalcin   if (*index < 0) {ierr = DMLabelNewStratum(label, value, index);CHKERRQ(ierr);}
259b9907514SLisandro Dalcin   PetscFunctionReturn(0);
260b9907514SLisandro Dalcin }
261b9907514SLisandro Dalcin 
262b9907514SLisandro Dalcin /*@
263b9907514SLisandro Dalcin   DMLabelAddStratum - Adds a new stratum value in a DMLabel
264b9907514SLisandro Dalcin 
265b9907514SLisandro Dalcin   Input Parameter:
266b9907514SLisandro Dalcin + label - The DMLabel
267b9907514SLisandro Dalcin - value - The stratum value
268b9907514SLisandro Dalcin 
269b9907514SLisandro Dalcin   Level: beginner
270b9907514SLisandro Dalcin 
271b9907514SLisandro Dalcin .seealso:  DMLabelCreate(), DMLabelDestroy()
272b9907514SLisandro Dalcin @*/
2730c3c4a36SLisandro Dalcin PetscErrorCode DMLabelAddStratum(DMLabel label, PetscInt value)
2740c3c4a36SLisandro Dalcin {
2750c3c4a36SLisandro Dalcin   PetscInt       v;
2760c3c4a36SLisandro Dalcin   PetscErrorCode ierr;
2770c3c4a36SLisandro Dalcin 
2780c3c4a36SLisandro Dalcin   PetscFunctionBegin;
279d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
280b9907514SLisandro Dalcin   ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr);
281b9907514SLisandro Dalcin   PetscFunctionReturn(0);
282b9907514SLisandro Dalcin }
283b9907514SLisandro Dalcin 
284b9907514SLisandro Dalcin /*@
285b9907514SLisandro Dalcin   DMLabelAddStrata - Adds new stratum values in a DMLabel
286b9907514SLisandro Dalcin 
2875b5e7992SMatthew G. Knepley   Not collective
2885b5e7992SMatthew G. Knepley 
289b9907514SLisandro Dalcin   Input Parameter:
290b9907514SLisandro Dalcin + label - The DMLabel
291b9907514SLisandro Dalcin . numStrata - The number of stratum values
292b9907514SLisandro Dalcin - stratumValues - The stratum values
293b9907514SLisandro Dalcin 
294b9907514SLisandro Dalcin   Level: beginner
295b9907514SLisandro Dalcin 
296b9907514SLisandro Dalcin .seealso:  DMLabelCreate(), DMLabelDestroy()
297b9907514SLisandro Dalcin @*/
298b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrata(DMLabel label, PetscInt numStrata, const PetscInt stratumValues[])
299b9907514SLisandro Dalcin {
300b9907514SLisandro Dalcin   PetscInt       *values, v;
301b9907514SLisandro Dalcin   PetscErrorCode ierr;
302b9907514SLisandro Dalcin 
303b9907514SLisandro Dalcin   PetscFunctionBegin;
304b9907514SLisandro Dalcin   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
305b9907514SLisandro Dalcin   if (numStrata) PetscValidIntPointer(stratumValues, 3);
306b9907514SLisandro Dalcin   ierr = PetscMalloc1(numStrata, &values);CHKERRQ(ierr);
307580bdb30SBarry Smith   ierr = PetscArraycpy(values, stratumValues, numStrata);CHKERRQ(ierr);
308b9907514SLisandro Dalcin   ierr = PetscSortRemoveDupsInt(&numStrata, values);CHKERRQ(ierr);
309b9907514SLisandro Dalcin   if (!label->numStrata) { /* Fast preallocation */
310b9907514SLisandro Dalcin     PetscInt   *tmpV;
311b9907514SLisandro Dalcin     PetscInt   *tmpS;
312b9907514SLisandro Dalcin     PetscHSetI *tmpH, ht;
313b9907514SLisandro Dalcin     IS         *tmpP, is;
314b9907514SLisandro Dalcin     PetscBool  *tmpB;
315b9907514SLisandro Dalcin     PetscHMapI  hmap = label->hmap;
316b9907514SLisandro Dalcin 
317b9907514SLisandro Dalcin     ierr = PetscMalloc1(numStrata, &tmpV);CHKERRQ(ierr);
318b9907514SLisandro Dalcin     ierr = PetscMalloc1(numStrata, &tmpS);CHKERRQ(ierr);
319b9907514SLisandro Dalcin     ierr = PetscMalloc1(numStrata, &tmpH);CHKERRQ(ierr);
320b9907514SLisandro Dalcin     ierr = PetscMalloc1(numStrata, &tmpP);CHKERRQ(ierr);
321b9907514SLisandro Dalcin     ierr = PetscMalloc1(numStrata, &tmpB);CHKERRQ(ierr);
322b9907514SLisandro Dalcin     label->numStrata     = numStrata;
323b9907514SLisandro Dalcin     label->stratumValues = tmpV;
324b9907514SLisandro Dalcin     label->stratumSizes  = tmpS;
325b9907514SLisandro Dalcin     label->ht            = tmpH;
326b9907514SLisandro Dalcin     label->points        = tmpP;
327b9907514SLisandro Dalcin     label->validIS       = tmpB;
328b9907514SLisandro Dalcin     for (v = 0; v < numStrata; ++v) {
329b9907514SLisandro Dalcin       ierr = PetscHSetICreate(&ht);CHKERRQ(ierr);
330b9907514SLisandro Dalcin       ierr = ISCreateStride(PETSC_COMM_SELF,0,0,1,&is);CHKERRQ(ierr);
331b9907514SLisandro Dalcin       ierr = PetscHMapISet(hmap, values[v], v);CHKERRQ(ierr);
332b9907514SLisandro Dalcin       tmpV[v] = values[v];
333b9907514SLisandro Dalcin       tmpS[v] = 0;
334b9907514SLisandro Dalcin       tmpH[v] = ht;
335b9907514SLisandro Dalcin       tmpP[v] = is;
336b9907514SLisandro Dalcin       tmpB[v] = PETSC_TRUE;
337b9907514SLisandro Dalcin     }
338277ea44aSLisandro Dalcin     ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr);
339b9907514SLisandro Dalcin   } else {
340b9907514SLisandro Dalcin     for (v = 0; v < numStrata; ++v) {
341b9907514SLisandro Dalcin       ierr = DMLabelAddStratum(label, values[v]);CHKERRQ(ierr);
342b9907514SLisandro Dalcin     }
343b9907514SLisandro Dalcin   }
344b9907514SLisandro Dalcin   ierr = PetscFree(values);CHKERRQ(ierr);
345b9907514SLisandro Dalcin   PetscFunctionReturn(0);
346b9907514SLisandro Dalcin }
347b9907514SLisandro Dalcin 
348b9907514SLisandro Dalcin /*@
349b9907514SLisandro Dalcin   DMLabelAddStrataIS - Adds new stratum values in a DMLabel
350b9907514SLisandro Dalcin 
3515b5e7992SMatthew G. Knepley   Not collective
3525b5e7992SMatthew G. Knepley 
353b9907514SLisandro Dalcin   Input Parameter:
354b9907514SLisandro Dalcin + label - The DMLabel
355b9907514SLisandro Dalcin - valueIS - Index set with stratum values
356b9907514SLisandro Dalcin 
357b9907514SLisandro Dalcin   Level: beginner
358b9907514SLisandro Dalcin 
359b9907514SLisandro Dalcin .seealso:  DMLabelCreate(), DMLabelDestroy()
360b9907514SLisandro Dalcin @*/
361b9907514SLisandro Dalcin PetscErrorCode DMLabelAddStrataIS(DMLabel label, IS valueIS)
362b9907514SLisandro Dalcin {
363b9907514SLisandro Dalcin   PetscInt       numStrata;
364b9907514SLisandro Dalcin   const PetscInt *stratumValues;
365b9907514SLisandro Dalcin   PetscErrorCode ierr;
366b9907514SLisandro Dalcin 
367b9907514SLisandro Dalcin   PetscFunctionBegin;
368b9907514SLisandro Dalcin   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
369b9907514SLisandro Dalcin   PetscValidHeaderSpecific(valueIS, IS_CLASSID, 2);
370b9907514SLisandro Dalcin   ierr = ISGetLocalSize(valueIS, &numStrata);CHKERRQ(ierr);
371b9907514SLisandro Dalcin   ierr = ISGetIndices(valueIS, &stratumValues);CHKERRQ(ierr);
372b9907514SLisandro Dalcin   ierr = DMLabelAddStrata(label, numStrata, stratumValues);CHKERRQ(ierr);
373c58f1c22SToby Isaac   PetscFunctionReturn(0);
374c58f1c22SToby Isaac }
375c58f1c22SToby Isaac 
376c58f1c22SToby Isaac static PetscErrorCode DMLabelView_Ascii(DMLabel label, PetscViewer viewer)
377c58f1c22SToby Isaac {
378c58f1c22SToby Isaac   PetscInt       v;
379c58f1c22SToby Isaac   PetscMPIInt    rank;
380c58f1c22SToby Isaac   PetscErrorCode ierr;
381c58f1c22SToby Isaac 
382c58f1c22SToby Isaac   PetscFunctionBegin;
383c58f1c22SToby Isaac   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank);CHKERRQ(ierr);
384c58f1c22SToby Isaac   ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
385c58f1c22SToby Isaac   if (label) {
386d67d17b1SMatthew G. Knepley     const char *name;
387d67d17b1SMatthew G. Knepley 
388d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr);
389d67d17b1SMatthew G. Knepley     ierr = PetscViewerASCIIPrintf(viewer, "Label '%s':\n", name);CHKERRQ(ierr);
390c58f1c22SToby Isaac     if (label->bt) {ierr = PetscViewerASCIIPrintf(viewer, "  Index has been calculated in [%D, %D)\n", label->pStart, label->pEnd);CHKERRQ(ierr);}
391c58f1c22SToby Isaac     for (v = 0; v < label->numStrata; ++v) {
392c58f1c22SToby Isaac       const PetscInt value = label->stratumValues[v];
393ad8374ffSToby Isaac       const PetscInt *points;
394c58f1c22SToby Isaac       PetscInt       p;
395c58f1c22SToby Isaac 
396ad8374ffSToby Isaac       ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr);
397c58f1c22SToby Isaac       for (p = 0; p < label->stratumSizes[v]; ++p) {
398ad8374ffSToby Isaac         ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]: %D (%D)\n", rank, points[p], value);CHKERRQ(ierr);
399c58f1c22SToby Isaac       }
400ad8374ffSToby Isaac       ierr = ISRestoreIndices(label->points[v],&points);CHKERRQ(ierr);
401c58f1c22SToby Isaac     }
402c58f1c22SToby Isaac   }
403c58f1c22SToby Isaac   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
404c58f1c22SToby Isaac   ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
405c58f1c22SToby Isaac   PetscFunctionReturn(0);
406c58f1c22SToby Isaac }
407c58f1c22SToby Isaac 
408c58f1c22SToby Isaac /*@C
409c58f1c22SToby Isaac   DMLabelView - View the label
410c58f1c22SToby Isaac 
4115b5e7992SMatthew G. Knepley   Collective on viewer
4125b5e7992SMatthew G. Knepley 
413c58f1c22SToby Isaac   Input Parameters:
414c58f1c22SToby Isaac + label - The DMLabel
415c58f1c22SToby Isaac - viewer - The PetscViewer
416c58f1c22SToby Isaac 
417c58f1c22SToby Isaac   Level: intermediate
418c58f1c22SToby Isaac 
419c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelDestroy()
420c58f1c22SToby Isaac @*/
421c58f1c22SToby Isaac PetscErrorCode DMLabelView(DMLabel label, PetscViewer viewer)
422c58f1c22SToby Isaac {
423c58f1c22SToby Isaac   PetscBool      iascii;
424c58f1c22SToby Isaac   PetscErrorCode ierr;
425c58f1c22SToby Isaac 
426c58f1c22SToby Isaac   PetscFunctionBegin;
427d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
428b9907514SLisandro Dalcin   if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)label), &viewer);CHKERRQ(ierr);}
429c58f1c22SToby Isaac   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
430c58f1c22SToby Isaac   if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);}
431c58f1c22SToby Isaac   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
432c58f1c22SToby Isaac   if (iascii) {
433c58f1c22SToby Isaac     ierr = DMLabelView_Ascii(label, viewer);CHKERRQ(ierr);
434c58f1c22SToby Isaac   }
435c58f1c22SToby Isaac   PetscFunctionReturn(0);
436c58f1c22SToby Isaac }
437c58f1c22SToby Isaac 
43884f0b6dfSMatthew G. Knepley /*@
439d67d17b1SMatthew G. Knepley   DMLabelReset - Destroys internal data structures in a DMLabel
440d67d17b1SMatthew G. Knepley 
4415b5e7992SMatthew G. Knepley   Not collective
4425b5e7992SMatthew G. Knepley 
443d67d17b1SMatthew G. Knepley   Input Parameter:
444d67d17b1SMatthew G. Knepley . label - The DMLabel
445d67d17b1SMatthew G. Knepley 
446d67d17b1SMatthew G. Knepley   Level: beginner
447d67d17b1SMatthew G. Knepley 
448d67d17b1SMatthew G. Knepley .seealso: DMLabelDestroy(), DMLabelCreate()
449d67d17b1SMatthew G. Knepley @*/
450d67d17b1SMatthew G. Knepley PetscErrorCode DMLabelReset(DMLabel label)
451d67d17b1SMatthew G. Knepley {
452d67d17b1SMatthew G. Knepley   PetscInt       v;
453d67d17b1SMatthew G. Knepley   PetscErrorCode ierr;
454d67d17b1SMatthew G. Knepley 
455d67d17b1SMatthew G. Knepley   PetscFunctionBegin;
456d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
457d67d17b1SMatthew G. Knepley   for (v = 0; v < label->numStrata; ++v) {
458d67d17b1SMatthew G. Knepley     ierr = PetscHSetIDestroy(&label->ht[v]);CHKERRQ(ierr);
459d67d17b1SMatthew G. Knepley     ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr);
460d67d17b1SMatthew G. Knepley   }
461b9907514SLisandro Dalcin   label->numStrata = 0;
462b9907514SLisandro Dalcin   ierr = PetscFree(label->stratumValues);CHKERRQ(ierr);
463b9907514SLisandro Dalcin   ierr = PetscFree(label->stratumSizes);CHKERRQ(ierr);
464d67d17b1SMatthew G. Knepley   ierr = PetscFree(label->ht);CHKERRQ(ierr);
465d67d17b1SMatthew G. Knepley   ierr = PetscFree(label->points);CHKERRQ(ierr);
466d67d17b1SMatthew G. Knepley   ierr = PetscFree(label->validIS);CHKERRQ(ierr);
467b9907514SLisandro Dalcin   ierr = PetscHMapIReset(label->hmap);CHKERRQ(ierr);
468b9907514SLisandro Dalcin   label->pStart = -1;
469b9907514SLisandro Dalcin   label->pEnd   = -1;
470d67d17b1SMatthew G. Knepley   ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr);
471d67d17b1SMatthew G. Knepley   PetscFunctionReturn(0);
472d67d17b1SMatthew G. Knepley }
473d67d17b1SMatthew G. Knepley 
474d67d17b1SMatthew G. Knepley /*@
47584f0b6dfSMatthew G. Knepley   DMLabelDestroy - Destroys a DMLabel
47684f0b6dfSMatthew G. Knepley 
4775b5e7992SMatthew G. Knepley   Collective on label
4785b5e7992SMatthew G. Knepley 
47984f0b6dfSMatthew G. Knepley   Input Parameter:
48084f0b6dfSMatthew G. Knepley . label - The DMLabel
48184f0b6dfSMatthew G. Knepley 
48284f0b6dfSMatthew G. Knepley   Level: beginner
48384f0b6dfSMatthew G. Knepley 
484d67d17b1SMatthew G. Knepley .seealso: DMLabelReset(), DMLabelCreate()
48584f0b6dfSMatthew G. Knepley @*/
486c58f1c22SToby Isaac PetscErrorCode DMLabelDestroy(DMLabel *label)
487c58f1c22SToby Isaac {
488c58f1c22SToby Isaac   PetscErrorCode ierr;
489c58f1c22SToby Isaac 
490c58f1c22SToby Isaac   PetscFunctionBegin;
491d67d17b1SMatthew G. Knepley   if (!*label) PetscFunctionReturn(0);
492d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific((*label),DMLABEL_CLASSID,1);
493b9907514SLisandro Dalcin   if (--((PetscObject)(*label))->refct > 0) {*label = NULL; PetscFunctionReturn(0);}
494d67d17b1SMatthew G. Knepley   ierr = DMLabelReset(*label);CHKERRQ(ierr);
495b9907514SLisandro Dalcin   ierr = PetscHMapIDestroy(&(*label)->hmap);CHKERRQ(ierr);
496d67d17b1SMatthew G. Knepley   ierr = PetscHeaderDestroy(label);CHKERRQ(ierr);
497c58f1c22SToby Isaac   PetscFunctionReturn(0);
498c58f1c22SToby Isaac }
499c58f1c22SToby Isaac 
50084f0b6dfSMatthew G. Knepley /*@
50184f0b6dfSMatthew G. Knepley   DMLabelDuplicate - Duplicates a DMLabel
50284f0b6dfSMatthew G. Knepley 
5035b5e7992SMatthew G. Knepley   Collective on label
5045b5e7992SMatthew G. Knepley 
50584f0b6dfSMatthew G. Knepley   Input Parameter:
50684f0b6dfSMatthew G. Knepley . label - The DMLabel
50784f0b6dfSMatthew G. Knepley 
50884f0b6dfSMatthew G. Knepley   Output Parameter:
50984f0b6dfSMatthew G. Knepley . labelnew - location to put new vector
51084f0b6dfSMatthew G. Knepley 
51184f0b6dfSMatthew G. Knepley   Level: intermediate
51284f0b6dfSMatthew G. Knepley 
51384f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelDestroy()
51484f0b6dfSMatthew G. Knepley @*/
515c58f1c22SToby Isaac PetscErrorCode DMLabelDuplicate(DMLabel label, DMLabel *labelnew)
516c58f1c22SToby Isaac {
517d67d17b1SMatthew G. Knepley   const char    *name;
518ad8374ffSToby Isaac   PetscInt       v;
519c58f1c22SToby Isaac   PetscErrorCode ierr;
520c58f1c22SToby Isaac 
521c58f1c22SToby Isaac   PetscFunctionBegin;
522d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
523c58f1c22SToby Isaac   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
524d67d17b1SMatthew G. Knepley   ierr = PetscObjectGetName((PetscObject) label, &name);CHKERRQ(ierr);
525d67d17b1SMatthew G. Knepley   ierr = DMLabelCreate(PetscObjectComm((PetscObject) label), name, labelnew);CHKERRQ(ierr);
526c58f1c22SToby Isaac 
527c58f1c22SToby Isaac   (*labelnew)->numStrata    = label->numStrata;
5285aa44df4SToby Isaac   (*labelnew)->defaultValue = label->defaultValue;
529c58f1c22SToby Isaac   ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumValues);CHKERRQ(ierr);
530c58f1c22SToby Isaac   ierr = PetscMalloc1(label->numStrata, &(*labelnew)->stratumSizes);CHKERRQ(ierr);
531c58f1c22SToby Isaac   ierr = PetscMalloc1(label->numStrata, &(*labelnew)->ht);CHKERRQ(ierr);
532c58f1c22SToby Isaac   ierr = PetscMalloc1(label->numStrata, &(*labelnew)->points);CHKERRQ(ierr);
533ad8374ffSToby Isaac   ierr = PetscMalloc1(label->numStrata, &(*labelnew)->validIS);CHKERRQ(ierr);
534c58f1c22SToby Isaac   for (v = 0; v < label->numStrata; ++v) {
535e8f14785SLisandro Dalcin     ierr = PetscHSetICreate(&(*labelnew)->ht[v]);CHKERRQ(ierr);
536c58f1c22SToby Isaac     (*labelnew)->stratumValues[v]  = label->stratumValues[v];
537c58f1c22SToby Isaac     (*labelnew)->stratumSizes[v]   = label->stratumSizes[v];
538ad8374ffSToby Isaac     ierr = PetscObjectReference((PetscObject) (label->points[v]));CHKERRQ(ierr);
539ad8374ffSToby Isaac     (*labelnew)->points[v]         = label->points[v];
540b9907514SLisandro Dalcin     (*labelnew)->validIS[v]        = PETSC_TRUE;
541c58f1c22SToby Isaac   }
542f14fe40dSLisandro Dalcin   ierr = PetscHMapIDestroy(&(*labelnew)->hmap);CHKERRQ(ierr);
543b9907514SLisandro Dalcin   ierr = PetscHMapIDuplicate(label->hmap,&(*labelnew)->hmap);CHKERRQ(ierr);
544c58f1c22SToby Isaac   (*labelnew)->pStart = -1;
545c58f1c22SToby Isaac   (*labelnew)->pEnd   = -1;
546c58f1c22SToby Isaac   (*labelnew)->bt     = NULL;
547c58f1c22SToby Isaac   PetscFunctionReturn(0);
548c58f1c22SToby Isaac }
549c58f1c22SToby Isaac 
550c6a43d28SMatthew G. Knepley /*@
551c6a43d28SMatthew G. Knepley   DMLabelComputeIndex - Create an index structure for membership determination, automatically determining the bounds
552c6a43d28SMatthew G. Knepley 
5535b5e7992SMatthew G. Knepley   Not collective
5545b5e7992SMatthew G. Knepley 
555c6a43d28SMatthew G. Knepley   Input Parameter:
556c6a43d28SMatthew G. Knepley . label  - The DMLabel
557c6a43d28SMatthew G. Knepley 
558c6a43d28SMatthew G. Knepley   Level: intermediate
559c6a43d28SMatthew G. Knepley 
560c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue()
561c6a43d28SMatthew G. Knepley @*/
562c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelComputeIndex(DMLabel label)
563c6a43d28SMatthew G. Knepley {
564c6a43d28SMatthew G. Knepley   PetscInt       pStart = PETSC_MAX_INT, pEnd = -1, v;
565c6a43d28SMatthew G. Knepley   PetscErrorCode ierr;
566c6a43d28SMatthew G. Knepley 
567c6a43d28SMatthew G. Knepley   PetscFunctionBegin;
568c6a43d28SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
569c6a43d28SMatthew G. Knepley   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
570c6a43d28SMatthew G. Knepley   for (v = 0; v < label->numStrata; ++v) {
571c6a43d28SMatthew G. Knepley     const PetscInt *points;
572c6a43d28SMatthew G. Knepley     PetscInt       i;
573c6a43d28SMatthew G. Knepley 
574c6a43d28SMatthew G. Knepley     ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr);
575c6a43d28SMatthew G. Knepley     for (i = 0; i < label->stratumSizes[v]; ++i) {
576c6a43d28SMatthew G. Knepley       const PetscInt point = points[i];
577c6a43d28SMatthew G. Knepley 
578c6a43d28SMatthew G. Knepley       pStart = PetscMin(point,   pStart);
579c6a43d28SMatthew G. Knepley       pEnd   = PetscMax(point+1, pEnd);
580c6a43d28SMatthew G. Knepley     }
581c6a43d28SMatthew G. Knepley     ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr);
582c6a43d28SMatthew G. Knepley   }
583c6a43d28SMatthew G. Knepley   label->pStart = pStart == PETSC_MAX_INT ? -1 : pStart;
584c6a43d28SMatthew G. Knepley   label->pEnd   = pEnd;
585c6a43d28SMatthew G. Knepley   ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr);
586c6a43d28SMatthew G. Knepley   PetscFunctionReturn(0);
587c6a43d28SMatthew G. Knepley }
588c6a43d28SMatthew G. Knepley 
589c6a43d28SMatthew G. Knepley /*@
590c6a43d28SMatthew G. Knepley   DMLabelCreateIndex - Create an index structure for membership determination
591c6a43d28SMatthew G. Knepley 
5925b5e7992SMatthew G. Knepley   Not collective
5935b5e7992SMatthew G. Knepley 
594c6a43d28SMatthew G. Knepley   Input Parameters:
595c6a43d28SMatthew G. Knepley + label  - The DMLabel
596c6a43d28SMatthew G. Knepley . pStart - The smallest point
597c6a43d28SMatthew G. Knepley - pEnd   - The largest point + 1
598c6a43d28SMatthew G. Knepley 
599c6a43d28SMatthew G. Knepley   Level: intermediate
600c6a43d28SMatthew G. Knepley 
601c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelComputeIndex(), DMLabelDestroyIndex(), DMLabelGetValue(), DMLabelSetValue()
602c6a43d28SMatthew G. Knepley @*/
603c58f1c22SToby Isaac PetscErrorCode DMLabelCreateIndex(DMLabel label, PetscInt pStart, PetscInt pEnd)
604c58f1c22SToby Isaac {
605c58f1c22SToby Isaac   PetscInt       v;
606c58f1c22SToby Isaac   PetscErrorCode ierr;
607c58f1c22SToby Isaac 
608c58f1c22SToby Isaac   PetscFunctionBegin;
609d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
6100c3c4a36SLisandro Dalcin   ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr);
611c58f1c22SToby Isaac   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
612c58f1c22SToby Isaac   label->pStart = pStart;
613c58f1c22SToby Isaac   label->pEnd   = pEnd;
614c6a43d28SMatthew G. Knepley   /* This can be hooked into SetValue(),  ClearValue(), etc. for updating */
615c58f1c22SToby Isaac   ierr = PetscBTCreate(pEnd - pStart, &label->bt);CHKERRQ(ierr);
616c58f1c22SToby Isaac   for (v = 0; v < label->numStrata; ++v) {
617ad8374ffSToby Isaac     const PetscInt *points;
618c58f1c22SToby Isaac     PetscInt       i;
619c58f1c22SToby Isaac 
620ad8374ffSToby Isaac     ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr);
621c58f1c22SToby Isaac     for (i = 0; i < label->stratumSizes[v]; ++i) {
622ad8374ffSToby Isaac       const PetscInt point = points[i];
623c58f1c22SToby Isaac 
624c58f1c22SToby Isaac       if ((point < pStart) || (point >= pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, pStart, pEnd);
625c58f1c22SToby Isaac       ierr = PetscBTSet(label->bt, point - pStart);CHKERRQ(ierr);
626c58f1c22SToby Isaac     }
627ad8374ffSToby Isaac     ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr);
628c58f1c22SToby Isaac   }
629c58f1c22SToby Isaac   PetscFunctionReturn(0);
630c58f1c22SToby Isaac }
631c58f1c22SToby Isaac 
632c6a43d28SMatthew G. Knepley /*@
633c6a43d28SMatthew G. Knepley   DMLabelDestroyIndex - Destroy the index structure
634c6a43d28SMatthew G. Knepley 
6355b5e7992SMatthew G. Knepley   Not collective
6365b5e7992SMatthew G. Knepley 
637c6a43d28SMatthew G. Knepley   Input Parameter:
638c6a43d28SMatthew G. Knepley . label - the DMLabel
639c6a43d28SMatthew G. Knepley 
640c6a43d28SMatthew G. Knepley   Level: intermediate
641c6a43d28SMatthew G. Knepley 
642c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue()
643c6a43d28SMatthew G. Knepley @*/
644c58f1c22SToby Isaac PetscErrorCode DMLabelDestroyIndex(DMLabel label)
645c58f1c22SToby Isaac {
646c58f1c22SToby Isaac   PetscErrorCode ierr;
647c58f1c22SToby Isaac 
648c58f1c22SToby Isaac   PetscFunctionBegin;
649d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
650c58f1c22SToby Isaac   label->pStart = -1;
651c58f1c22SToby Isaac   label->pEnd   = -1;
6520c3c4a36SLisandro Dalcin   ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr);
653c58f1c22SToby Isaac   PetscFunctionReturn(0);
654c58f1c22SToby Isaac }
655c58f1c22SToby Isaac 
656c58f1c22SToby Isaac /*@
657c6a43d28SMatthew G. Knepley   DMLabelGetBounds - Return the smallest and largest point in the label
658c6a43d28SMatthew G. Knepley 
6595b5e7992SMatthew G. Knepley   Not collective
6605b5e7992SMatthew G. Knepley 
661c6a43d28SMatthew G. Knepley   Input Parameter:
662c6a43d28SMatthew G. Knepley . label - the DMLabel
663c6a43d28SMatthew G. Knepley 
664c6a43d28SMatthew G. Knepley   Output Parameters:
665c6a43d28SMatthew G. Knepley + pStart - The smallest point
666c6a43d28SMatthew G. Knepley - pEnd   - The largest point + 1
667c6a43d28SMatthew G. Knepley 
668c6a43d28SMatthew G. Knepley   Note: This will compute an index for the label if one does not exist.
669c6a43d28SMatthew G. Knepley 
670c6a43d28SMatthew G. Knepley   Level: intermediate
671c6a43d28SMatthew G. Knepley 
672c6a43d28SMatthew G. Knepley .seealso: DMLabelHasPoint(), DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue()
673c6a43d28SMatthew G. Knepley @*/
674c6a43d28SMatthew G. Knepley PetscErrorCode DMLabelGetBounds(DMLabel label, PetscInt *pStart, PetscInt *pEnd)
675c6a43d28SMatthew G. Knepley {
676c6a43d28SMatthew G. Knepley   PetscErrorCode ierr;
677c6a43d28SMatthew G. Knepley 
678c6a43d28SMatthew G. Knepley   PetscFunctionBegin;
679c6a43d28SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
680c6a43d28SMatthew G. Knepley   if ((label->pStart == -1) && (label->pEnd == -1)) {ierr = DMLabelComputeIndex(label);CHKERRQ(ierr);}
681c6a43d28SMatthew G. Knepley   if (pStart) {
682534a8f05SLisandro Dalcin     PetscValidIntPointer(pStart, 2);
683c6a43d28SMatthew G. Knepley     *pStart = label->pStart;
684c6a43d28SMatthew G. Knepley   }
685c6a43d28SMatthew G. Knepley   if (pEnd) {
686534a8f05SLisandro Dalcin     PetscValidIntPointer(pEnd, 3);
687c6a43d28SMatthew G. Knepley     *pEnd = label->pEnd;
688c6a43d28SMatthew G. Knepley   }
689c6a43d28SMatthew G. Knepley   PetscFunctionReturn(0);
690c6a43d28SMatthew G. Knepley }
691c6a43d28SMatthew G. Knepley 
692c6a43d28SMatthew G. Knepley /*@
693c58f1c22SToby Isaac   DMLabelHasValue - Determine whether a label assigns the value to any point
694c58f1c22SToby Isaac 
6955b5e7992SMatthew G. Knepley   Not collective
6965b5e7992SMatthew G. Knepley 
697c58f1c22SToby Isaac   Input Parameters:
698c58f1c22SToby Isaac + label - the DMLabel
699c58f1c22SToby Isaac - value - the value
700c58f1c22SToby Isaac 
701c58f1c22SToby Isaac   Output Parameter:
702c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this value to any point
703c58f1c22SToby Isaac 
704c58f1c22SToby Isaac   Level: developer
705c58f1c22SToby Isaac 
706c58f1c22SToby Isaac .seealso: DMLabelHasPoint(), DMLabelGetValue(), DMLabelSetValue()
707c58f1c22SToby Isaac @*/
708c58f1c22SToby Isaac PetscErrorCode DMLabelHasValue(DMLabel label, PetscInt value, PetscBool *contains)
709c58f1c22SToby Isaac {
710c58f1c22SToby Isaac   PetscInt v;
7110c3c4a36SLisandro Dalcin   PetscErrorCode ierr;
712c58f1c22SToby Isaac 
713c58f1c22SToby Isaac   PetscFunctionBegin;
714d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
715534a8f05SLisandro Dalcin   PetscValidBoolPointer(contains, 3);
7160c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
7170c3c4a36SLisandro Dalcin   *contains = v < 0 ? PETSC_FALSE : PETSC_TRUE;
718c58f1c22SToby Isaac   PetscFunctionReturn(0);
719c58f1c22SToby Isaac }
720c58f1c22SToby Isaac 
721c58f1c22SToby Isaac /*@
722c58f1c22SToby Isaac   DMLabelHasPoint - Determine whether a label assigns a value to a point
723c58f1c22SToby Isaac 
7245b5e7992SMatthew G. Knepley   Not collective
7255b5e7992SMatthew G. Knepley 
726c58f1c22SToby Isaac   Input Parameters:
727c58f1c22SToby Isaac + label - the DMLabel
728c58f1c22SToby Isaac - point - the point
729c58f1c22SToby Isaac 
730c58f1c22SToby Isaac   Output Parameter:
731c58f1c22SToby Isaac . contains - Flag indicating whether the label maps this point to a value
732c58f1c22SToby Isaac 
733c58f1c22SToby Isaac   Note: The user must call DMLabelCreateIndex() before this function.
734c58f1c22SToby Isaac 
735c58f1c22SToby Isaac   Level: developer
736c58f1c22SToby Isaac 
737c58f1c22SToby Isaac .seealso: DMLabelCreateIndex(), DMLabelGetValue(), DMLabelSetValue()
738c58f1c22SToby Isaac @*/
739c58f1c22SToby Isaac PetscErrorCode DMLabelHasPoint(DMLabel label, PetscInt point, PetscBool *contains)
740c58f1c22SToby Isaac {
741c58f1c22SToby Isaac   PetscErrorCode ierr;
742c58f1c22SToby Isaac 
743c58f1c22SToby Isaac   PetscFunctionBeginHot;
744d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
745534a8f05SLisandro Dalcin   PetscValidBoolPointer(contains, 3);
746c58f1c22SToby Isaac   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
747c58f1c22SToby Isaac #if defined(PETSC_USE_DEBUG)
748c58f1c22SToby Isaac   if (!label->bt) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call DMLabelCreateIndex() before DMLabelHasPoint()");
749c58f1c22SToby Isaac   if ((point < label->pStart) || (point >= label->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd);
750c58f1c22SToby Isaac #endif
751c58f1c22SToby Isaac   *contains = PetscBTLookup(label->bt, point - label->pStart) ? PETSC_TRUE : PETSC_FALSE;
752c58f1c22SToby Isaac   PetscFunctionReturn(0);
753c58f1c22SToby Isaac }
754c58f1c22SToby Isaac 
755c58f1c22SToby Isaac /*@
756c58f1c22SToby Isaac   DMLabelStratumHasPoint - Return true if the stratum contains a point
757c58f1c22SToby Isaac 
7585b5e7992SMatthew G. Knepley   Not collective
7595b5e7992SMatthew G. Knepley 
760c58f1c22SToby Isaac   Input Parameters:
761c58f1c22SToby Isaac + label - the DMLabel
762c58f1c22SToby Isaac . value - the stratum value
763c58f1c22SToby Isaac - point - the point
764c58f1c22SToby Isaac 
765c58f1c22SToby Isaac   Output Parameter:
766c58f1c22SToby Isaac . contains - true if the stratum contains the point
767c58f1c22SToby Isaac 
768c58f1c22SToby Isaac   Level: intermediate
769c58f1c22SToby Isaac 
770c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue()
771c58f1c22SToby Isaac @*/
772c58f1c22SToby Isaac PetscErrorCode DMLabelStratumHasPoint(DMLabel label, PetscInt value, PetscInt point, PetscBool *contains)
773c58f1c22SToby Isaac {
774c58f1c22SToby Isaac   PetscInt       v;
775c58f1c22SToby Isaac   PetscErrorCode ierr;
776c58f1c22SToby Isaac 
7770c3c4a36SLisandro Dalcin   PetscFunctionBeginHot;
778d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
779534a8f05SLisandro Dalcin   PetscValidBoolPointer(contains, 4);
780c58f1c22SToby Isaac   *contains = PETSC_FALSE;
7810c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
7820c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
7830c3c4a36SLisandro Dalcin 
784ad8374ffSToby Isaac   if (label->validIS[v]) {
785c58f1c22SToby Isaac     PetscInt i;
786c58f1c22SToby Isaac 
787a2d74346SToby Isaac     ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr);
7880c3c4a36SLisandro Dalcin     if (i >= 0) *contains = PETSC_TRUE;
789c58f1c22SToby Isaac   } else {
790c58f1c22SToby Isaac     PetscBool has;
791c58f1c22SToby Isaac 
792b9907514SLisandro Dalcin     ierr = PetscHSetIHas(label->ht[v], point, &has);CHKERRQ(ierr);
7930c3c4a36SLisandro Dalcin     if (has) *contains = PETSC_TRUE;
794c58f1c22SToby Isaac   }
795c58f1c22SToby Isaac   PetscFunctionReturn(0);
796c58f1c22SToby Isaac }
797c58f1c22SToby Isaac 
79884f0b6dfSMatthew G. Knepley /*@
7995aa44df4SToby Isaac   DMLabelGetDefaultValue - Get the default value returned by DMLabelGetValue() if a point has not been explicitly given a value.
8005aa44df4SToby Isaac   When a label is created, it is initialized to -1.
8015aa44df4SToby Isaac 
8025b5e7992SMatthew G. Knepley   Not collective
8035b5e7992SMatthew G. Knepley 
8045aa44df4SToby Isaac   Input parameter:
8055aa44df4SToby Isaac . label - a DMLabel object
8065aa44df4SToby Isaac 
8075aa44df4SToby Isaac   Output parameter:
8085aa44df4SToby Isaac . defaultValue - the default value
8095aa44df4SToby Isaac 
8105aa44df4SToby Isaac   Level: beginner
8115aa44df4SToby Isaac 
8125aa44df4SToby Isaac .seealso: DMLabelSetDefaultValue(), DMLabelGetValue(), DMLabelSetValue()
81384f0b6dfSMatthew G. Knepley @*/
8145aa44df4SToby Isaac PetscErrorCode DMLabelGetDefaultValue(DMLabel label, PetscInt *defaultValue)
8155aa44df4SToby Isaac {
8165aa44df4SToby Isaac   PetscFunctionBegin;
817d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
8185aa44df4SToby Isaac   *defaultValue = label->defaultValue;
8195aa44df4SToby Isaac   PetscFunctionReturn(0);
8205aa44df4SToby Isaac }
8215aa44df4SToby Isaac 
82284f0b6dfSMatthew G. Knepley /*@
8235aa44df4SToby Isaac   DMLabelSetDefaultValue - Set the default value returned by DMLabelGetValue() if a point has not been explicitly given a value.
8245aa44df4SToby Isaac   When a label is created, it is initialized to -1.
8255aa44df4SToby Isaac 
8265b5e7992SMatthew G. Knepley   Not collective
8275b5e7992SMatthew G. Knepley 
8285aa44df4SToby Isaac   Input parameter:
8295aa44df4SToby Isaac . label - a DMLabel object
8305aa44df4SToby Isaac 
8315aa44df4SToby Isaac   Output parameter:
8325aa44df4SToby Isaac . defaultValue - the default value
8335aa44df4SToby Isaac 
8345aa44df4SToby Isaac   Level: beginner
8355aa44df4SToby Isaac 
8365aa44df4SToby Isaac .seealso: DMLabelGetDefaultValue(), DMLabelGetValue(), DMLabelSetValue()
83784f0b6dfSMatthew G. Knepley @*/
8385aa44df4SToby Isaac PetscErrorCode DMLabelSetDefaultValue(DMLabel label, PetscInt defaultValue)
8395aa44df4SToby Isaac {
8405aa44df4SToby Isaac   PetscFunctionBegin;
841d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
8425aa44df4SToby Isaac   label->defaultValue = defaultValue;
8435aa44df4SToby Isaac   PetscFunctionReturn(0);
8445aa44df4SToby Isaac }
8455aa44df4SToby Isaac 
846c58f1c22SToby Isaac /*@
8475aa44df4SToby 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())
848c58f1c22SToby Isaac 
8495b5e7992SMatthew G. Knepley   Not collective
8505b5e7992SMatthew G. Knepley 
851c58f1c22SToby Isaac   Input Parameters:
852c58f1c22SToby Isaac + label - the DMLabel
853c58f1c22SToby Isaac - point - the point
854c58f1c22SToby Isaac 
855c58f1c22SToby Isaac   Output Parameter:
8568e68afcfSMatthew G. Knepley . value - The point value, or the default value (-1 by default)
857c58f1c22SToby Isaac 
858c58f1c22SToby Isaac   Level: intermediate
859c58f1c22SToby Isaac 
8605aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelSetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue()
861c58f1c22SToby Isaac @*/
862c58f1c22SToby Isaac PetscErrorCode DMLabelGetValue(DMLabel label, PetscInt point, PetscInt *value)
863c58f1c22SToby Isaac {
864c58f1c22SToby Isaac   PetscInt       v;
865c58f1c22SToby Isaac   PetscErrorCode ierr;
866c58f1c22SToby Isaac 
8670c3c4a36SLisandro Dalcin   PetscFunctionBeginHot;
868d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
869c58f1c22SToby Isaac   PetscValidPointer(value, 3);
8705aa44df4SToby Isaac   *value = label->defaultValue;
871c58f1c22SToby Isaac   for (v = 0; v < label->numStrata; ++v) {
872ad8374ffSToby Isaac     if (label->validIS[v]) {
873c58f1c22SToby Isaac       PetscInt i;
874c58f1c22SToby Isaac 
875a2d74346SToby Isaac       ierr = ISLocate(label->points[v], point, &i);CHKERRQ(ierr);
876c58f1c22SToby Isaac       if (i >= 0) {
877c58f1c22SToby Isaac         *value = label->stratumValues[v];
878c58f1c22SToby Isaac         break;
879c58f1c22SToby Isaac       }
880c58f1c22SToby Isaac     } else {
881c58f1c22SToby Isaac       PetscBool has;
882c58f1c22SToby Isaac 
883b9907514SLisandro Dalcin       ierr = PetscHSetIHas(label->ht[v], point, &has);CHKERRQ(ierr);
884c58f1c22SToby Isaac       if (has) {
885c58f1c22SToby Isaac         *value = label->stratumValues[v];
886c58f1c22SToby Isaac         break;
887c58f1c22SToby Isaac       }
888c58f1c22SToby Isaac     }
889c58f1c22SToby Isaac   }
890c58f1c22SToby Isaac   PetscFunctionReturn(0);
891c58f1c22SToby Isaac }
892c58f1c22SToby Isaac 
893c58f1c22SToby Isaac /*@
894367003a6SStefano 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.
895c58f1c22SToby Isaac 
8965b5e7992SMatthew G. Knepley   Not collective
8975b5e7992SMatthew G. Knepley 
898c58f1c22SToby Isaac   Input Parameters:
899c58f1c22SToby Isaac + label - the DMLabel
900c58f1c22SToby Isaac . point - the point
901c58f1c22SToby Isaac - value - The point value
902c58f1c22SToby Isaac 
903c58f1c22SToby Isaac   Level: intermediate
904c58f1c22SToby Isaac 
9055aa44df4SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelClearValue(), DMLabelGetDefaultValue(), DMLabelSetDefaultValue()
906c58f1c22SToby Isaac @*/
907c58f1c22SToby Isaac PetscErrorCode DMLabelSetValue(DMLabel label, PetscInt point, PetscInt value)
908c58f1c22SToby Isaac {
909c58f1c22SToby Isaac   PetscInt       v;
910c58f1c22SToby Isaac   PetscErrorCode ierr;
911c58f1c22SToby Isaac 
912c58f1c22SToby Isaac   PetscFunctionBegin;
913d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
9140c3c4a36SLisandro Dalcin   /* Find label value, add new entry if needed */
9155aa44df4SToby Isaac   if (value == label->defaultValue) PetscFunctionReturn(0);
916b9907514SLisandro Dalcin   ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr);
917c58f1c22SToby Isaac   /* Set key */
9180c3c4a36SLisandro Dalcin   ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr);
919e8f14785SLisandro Dalcin   ierr = PetscHSetIAdd(label->ht[v], point);CHKERRQ(ierr);
920c58f1c22SToby Isaac   PetscFunctionReturn(0);
921c58f1c22SToby Isaac }
922c58f1c22SToby Isaac 
923c58f1c22SToby Isaac /*@
924c58f1c22SToby Isaac   DMLabelClearValue - Clear the value a label assigns to a point
925c58f1c22SToby Isaac 
9265b5e7992SMatthew G. Knepley   Not collective
9275b5e7992SMatthew G. Knepley 
928c58f1c22SToby Isaac   Input Parameters:
929c58f1c22SToby Isaac + label - the DMLabel
930c58f1c22SToby Isaac . point - the point
931c58f1c22SToby Isaac - value - The point value
932c58f1c22SToby Isaac 
933c58f1c22SToby Isaac   Level: intermediate
934c58f1c22SToby Isaac 
935c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue()
936c58f1c22SToby Isaac @*/
937c58f1c22SToby Isaac PetscErrorCode DMLabelClearValue(DMLabel label, PetscInt point, PetscInt value)
938c58f1c22SToby Isaac {
939ad8374ffSToby Isaac   PetscInt       v;
940c58f1c22SToby Isaac   PetscErrorCode ierr;
941c58f1c22SToby Isaac 
942c58f1c22SToby Isaac   PetscFunctionBegin;
943d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
944c58f1c22SToby Isaac   /* Find label value */
9450c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
9460c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
9470c3c4a36SLisandro Dalcin 
948eeed21e7SToby Isaac   if (label->bt) {
949eeed21e7SToby Isaac     if ((point < label->pStart) || (point >= label->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd);
950eeed21e7SToby Isaac     ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr);
951eeed21e7SToby Isaac   }
9520c3c4a36SLisandro Dalcin 
9530c3c4a36SLisandro Dalcin   /* Delete key */
9540c3c4a36SLisandro Dalcin   ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr);
955e8f14785SLisandro Dalcin   ierr = PetscHSetIDel(label->ht[v], point);CHKERRQ(ierr);
956c58f1c22SToby Isaac   PetscFunctionReturn(0);
957c58f1c22SToby Isaac }
958c58f1c22SToby Isaac 
959c58f1c22SToby Isaac /*@
960c58f1c22SToby Isaac   DMLabelInsertIS - Set all points in the IS to a value
961c58f1c22SToby Isaac 
9625b5e7992SMatthew G. Knepley   Not collective
9635b5e7992SMatthew G. Knepley 
964c58f1c22SToby Isaac   Input Parameters:
965c58f1c22SToby Isaac + label - the DMLabel
966c58f1c22SToby Isaac . is    - the point IS
967c58f1c22SToby Isaac - value - The point value
968c58f1c22SToby Isaac 
969c58f1c22SToby Isaac   Level: intermediate
970c58f1c22SToby Isaac 
971c58f1c22SToby Isaac .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
972c58f1c22SToby Isaac @*/
973c58f1c22SToby Isaac PetscErrorCode DMLabelInsertIS(DMLabel label, IS is, PetscInt value)
974c58f1c22SToby Isaac {
9750c3c4a36SLisandro Dalcin   PetscInt        v, n, p;
976c58f1c22SToby Isaac   const PetscInt *points;
977c58f1c22SToby Isaac   PetscErrorCode  ierr;
978c58f1c22SToby Isaac 
979c58f1c22SToby Isaac   PetscFunctionBegin;
980d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
981c58f1c22SToby Isaac   PetscValidHeaderSpecific(is, IS_CLASSID, 2);
9820c3c4a36SLisandro Dalcin   /* Find label value, add new entry if needed */
9830c3c4a36SLisandro Dalcin   if (value == label->defaultValue) PetscFunctionReturn(0);
984b9907514SLisandro Dalcin   ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr);
9850c3c4a36SLisandro Dalcin   /* Set keys */
9860c3c4a36SLisandro Dalcin   ierr = DMLabelMakeInvalid_Private(label, v);CHKERRQ(ierr);
987c58f1c22SToby Isaac   ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr);
988c58f1c22SToby Isaac   ierr = ISGetIndices(is, &points);CHKERRQ(ierr);
989e8f14785SLisandro Dalcin   for (p = 0; p < n; ++p) {ierr = PetscHSetIAdd(label->ht[v], points[p]);CHKERRQ(ierr);}
990c58f1c22SToby Isaac   ierr = ISRestoreIndices(is, &points);CHKERRQ(ierr);
991c58f1c22SToby Isaac   PetscFunctionReturn(0);
992c58f1c22SToby Isaac }
993c58f1c22SToby Isaac 
99484f0b6dfSMatthew G. Knepley /*@
99584f0b6dfSMatthew G. Knepley   DMLabelGetNumValues - Get the number of values that the DMLabel takes
99684f0b6dfSMatthew G. Knepley 
9975b5e7992SMatthew G. Knepley   Not collective
9985b5e7992SMatthew G. Knepley 
99984f0b6dfSMatthew G. Knepley   Input Parameter:
100084f0b6dfSMatthew G. Knepley . label - the DMLabel
100184f0b6dfSMatthew G. Knepley 
100284f0b6dfSMatthew G. Knepley   Output Paramater:
100384f0b6dfSMatthew G. Knepley . numValues - the number of values
100484f0b6dfSMatthew G. Knepley 
100584f0b6dfSMatthew G. Knepley   Level: intermediate
100684f0b6dfSMatthew G. Knepley 
100784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
100884f0b6dfSMatthew G. Knepley @*/
1009c58f1c22SToby Isaac PetscErrorCode DMLabelGetNumValues(DMLabel label, PetscInt *numValues)
1010c58f1c22SToby Isaac {
1011c58f1c22SToby Isaac   PetscFunctionBegin;
1012d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1013c58f1c22SToby Isaac   PetscValidPointer(numValues, 2);
1014c58f1c22SToby Isaac   *numValues = label->numStrata;
1015c58f1c22SToby Isaac   PetscFunctionReturn(0);
1016c58f1c22SToby Isaac }
1017c58f1c22SToby Isaac 
101884f0b6dfSMatthew G. Knepley /*@
101984f0b6dfSMatthew G. Knepley   DMLabelGetValueIS - Get an IS of all values that the DMlabel takes
102084f0b6dfSMatthew G. Knepley 
10215b5e7992SMatthew G. Knepley   Not collective
10225b5e7992SMatthew G. Knepley 
102384f0b6dfSMatthew G. Knepley   Input Parameter:
102484f0b6dfSMatthew G. Knepley . label - the DMLabel
102584f0b6dfSMatthew G. Knepley 
102684f0b6dfSMatthew G. Knepley   Output Paramater:
102784f0b6dfSMatthew G. Knepley . is    - the value IS
102884f0b6dfSMatthew G. Knepley 
102984f0b6dfSMatthew G. Knepley   Level: intermediate
103084f0b6dfSMatthew G. Knepley 
103184f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
103284f0b6dfSMatthew G. Knepley @*/
1033c58f1c22SToby Isaac PetscErrorCode DMLabelGetValueIS(DMLabel label, IS *values)
1034c58f1c22SToby Isaac {
1035c58f1c22SToby Isaac   PetscErrorCode ierr;
1036c58f1c22SToby Isaac 
1037c58f1c22SToby Isaac   PetscFunctionBegin;
1038d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1039c58f1c22SToby Isaac   PetscValidPointer(values, 2);
1040c58f1c22SToby Isaac   ierr = ISCreateGeneral(PETSC_COMM_SELF, label->numStrata, label->stratumValues, PETSC_USE_POINTER, values);CHKERRQ(ierr);
1041c58f1c22SToby Isaac   PetscFunctionReturn(0);
1042c58f1c22SToby Isaac }
1043c58f1c22SToby Isaac 
104484f0b6dfSMatthew G. Knepley /*@
104584f0b6dfSMatthew G. Knepley   DMLabelHasStratum - Determine whether points exist with the given value
104684f0b6dfSMatthew G. Knepley 
10475b5e7992SMatthew G. Knepley   Not collective
10485b5e7992SMatthew G. Knepley 
104984f0b6dfSMatthew G. Knepley   Input Parameters:
105084f0b6dfSMatthew G. Knepley + label - the DMLabel
105184f0b6dfSMatthew G. Knepley - value - the stratum value
105284f0b6dfSMatthew G. Knepley 
105384f0b6dfSMatthew G. Knepley   Output Paramater:
105484f0b6dfSMatthew G. Knepley . exists - Flag saying whether points exist
105584f0b6dfSMatthew G. Knepley 
105684f0b6dfSMatthew G. Knepley   Level: intermediate
105784f0b6dfSMatthew G. Knepley 
105884f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
105984f0b6dfSMatthew G. Knepley @*/
1060fada774cSMatthew G. Knepley PetscErrorCode DMLabelHasStratum(DMLabel label, PetscInt value, PetscBool *exists)
1061fada774cSMatthew G. Knepley {
1062fada774cSMatthew G. Knepley   PetscInt       v;
10630c3c4a36SLisandro Dalcin   PetscErrorCode ierr;
1064fada774cSMatthew G. Knepley 
1065fada774cSMatthew G. Knepley   PetscFunctionBegin;
1066d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1067fada774cSMatthew G. Knepley   PetscValidPointer(exists, 3);
10680c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
10690c3c4a36SLisandro Dalcin   *exists = v < 0 ? PETSC_FALSE : PETSC_TRUE;
1070fada774cSMatthew G. Knepley   PetscFunctionReturn(0);
1071fada774cSMatthew G. Knepley }
1072fada774cSMatthew G. Knepley 
107384f0b6dfSMatthew G. Knepley /*@
107484f0b6dfSMatthew G. Knepley   DMLabelGetStratumSize - Get the size of a stratum
107584f0b6dfSMatthew G. Knepley 
10765b5e7992SMatthew G. Knepley   Not collective
10775b5e7992SMatthew G. Knepley 
107884f0b6dfSMatthew G. Knepley   Input Parameters:
107984f0b6dfSMatthew G. Knepley + label - the DMLabel
108084f0b6dfSMatthew G. Knepley - value - the stratum value
108184f0b6dfSMatthew G. Knepley 
108284f0b6dfSMatthew G. Knepley   Output Paramater:
108384f0b6dfSMatthew G. Knepley . size - The number of points in the stratum
108484f0b6dfSMatthew G. Knepley 
108584f0b6dfSMatthew G. Knepley   Level: intermediate
108684f0b6dfSMatthew G. Knepley 
108784f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
108884f0b6dfSMatthew G. Knepley @*/
1089c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumSize(DMLabel label, PetscInt value, PetscInt *size)
1090c58f1c22SToby Isaac {
1091c58f1c22SToby Isaac   PetscInt       v;
1092c58f1c22SToby Isaac   PetscErrorCode ierr;
1093c58f1c22SToby Isaac 
1094c58f1c22SToby Isaac   PetscFunctionBegin;
1095d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1096c58f1c22SToby Isaac   PetscValidPointer(size, 3);
1097c58f1c22SToby Isaac   *size = 0;
10980c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
10990c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
1100c58f1c22SToby Isaac   ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr);
1101c58f1c22SToby Isaac   *size = label->stratumSizes[v];
1102c58f1c22SToby Isaac   PetscFunctionReturn(0);
1103c58f1c22SToby Isaac }
1104c58f1c22SToby Isaac 
110584f0b6dfSMatthew G. Knepley /*@
110684f0b6dfSMatthew G. Knepley   DMLabelGetStratumBounds - Get the largest and smallest point of a stratum
110784f0b6dfSMatthew G. Knepley 
11085b5e7992SMatthew G. Knepley   Not collective
11095b5e7992SMatthew G. Knepley 
111084f0b6dfSMatthew G. Knepley   Input Parameters:
111184f0b6dfSMatthew G. Knepley + label - the DMLabel
111284f0b6dfSMatthew G. Knepley - value - the stratum value
111384f0b6dfSMatthew G. Knepley 
111484f0b6dfSMatthew G. Knepley   Output Paramaters:
111584f0b6dfSMatthew G. Knepley + start - the smallest point in the stratum
111684f0b6dfSMatthew G. Knepley - end - the largest point in the stratum
111784f0b6dfSMatthew G. Knepley 
111884f0b6dfSMatthew G. Knepley   Level: intermediate
111984f0b6dfSMatthew G. Knepley 
112084f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
112184f0b6dfSMatthew G. Knepley @*/
1122c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumBounds(DMLabel label, PetscInt value, PetscInt *start, PetscInt *end)
1123c58f1c22SToby Isaac {
11240c3c4a36SLisandro Dalcin   PetscInt       v, min, max;
1125c58f1c22SToby Isaac   PetscErrorCode ierr;
1126c58f1c22SToby Isaac 
1127c58f1c22SToby Isaac   PetscFunctionBegin;
1128d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1129c58f1c22SToby Isaac   if (start) {PetscValidPointer(start, 3); *start = 0;}
1130c58f1c22SToby Isaac   if (end)   {PetscValidPointer(end,   4); *end   = 0;}
11310c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
11320c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
1133c58f1c22SToby Isaac   ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr);
11340c3c4a36SLisandro Dalcin   if (label->stratumSizes[v] <= 0) PetscFunctionReturn(0);
1135d6cb179aSToby Isaac   ierr = ISGetMinMax(label->points[v], &min, &max);CHKERRQ(ierr);
1136d6cb179aSToby Isaac   if (start) *start = min;
1137d6cb179aSToby Isaac   if (end)   *end   = max+1;
1138c58f1c22SToby Isaac   PetscFunctionReturn(0);
1139c58f1c22SToby Isaac }
1140c58f1c22SToby Isaac 
114184f0b6dfSMatthew G. Knepley /*@
114284f0b6dfSMatthew G. Knepley   DMLabelGetStratumIS - Get an IS with the stratum points
114384f0b6dfSMatthew G. Knepley 
11445b5e7992SMatthew G. Knepley   Not collective
11455b5e7992SMatthew G. Knepley 
114684f0b6dfSMatthew G. Knepley   Input Parameters:
114784f0b6dfSMatthew G. Knepley + label - the DMLabel
114884f0b6dfSMatthew G. Knepley - value - the stratum value
114984f0b6dfSMatthew G. Knepley 
115084f0b6dfSMatthew G. Knepley   Output Paramater:
115184f0b6dfSMatthew G. Knepley . points - The stratum points
115284f0b6dfSMatthew G. Knepley 
115384f0b6dfSMatthew G. Knepley   Level: intermediate
115484f0b6dfSMatthew G. Knepley 
1155593ce467SVaclav Hapla   Notes:
1156593ce467SVaclav Hapla   The output IS should be destroyed when no longer needed.
1157593ce467SVaclav Hapla   Returns NULL if the stratum is empty.
1158593ce467SVaclav Hapla 
115984f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
116084f0b6dfSMatthew G. Knepley @*/
1161c58f1c22SToby Isaac PetscErrorCode DMLabelGetStratumIS(DMLabel label, PetscInt value, IS *points)
1162c58f1c22SToby Isaac {
1163c58f1c22SToby Isaac   PetscInt       v;
1164c58f1c22SToby Isaac   PetscErrorCode ierr;
1165c58f1c22SToby Isaac 
1166c58f1c22SToby Isaac   PetscFunctionBegin;
1167d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1168c58f1c22SToby Isaac   PetscValidPointer(points, 3);
1169c58f1c22SToby Isaac   *points = NULL;
11700c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
11710c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
1172c58f1c22SToby Isaac   ierr = DMLabelMakeValid_Private(label, v);CHKERRQ(ierr);
1173ad8374ffSToby Isaac   ierr = PetscObjectReference((PetscObject) label->points[v]);CHKERRQ(ierr);
1174ad8374ffSToby Isaac   *points = label->points[v];
1175c58f1c22SToby Isaac   PetscFunctionReturn(0);
1176c58f1c22SToby Isaac }
1177c58f1c22SToby Isaac 
117884f0b6dfSMatthew G. Knepley /*@
117984f0b6dfSMatthew G. Knepley   DMLabelSetStratumIS - Set the stratum points using an IS
118084f0b6dfSMatthew G. Knepley 
11815b5e7992SMatthew G. Knepley   Not collective
11825b5e7992SMatthew G. Knepley 
118384f0b6dfSMatthew G. Knepley   Input Parameters:
118484f0b6dfSMatthew G. Knepley + label - the DMLabel
118584f0b6dfSMatthew G. Knepley . value - the stratum value
118684f0b6dfSMatthew G. Knepley - points - The stratum points
118784f0b6dfSMatthew G. Knepley 
118884f0b6dfSMatthew G. Knepley   Level: intermediate
118984f0b6dfSMatthew G. Knepley 
119084f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
119184f0b6dfSMatthew G. Knepley @*/
11924de306b1SToby Isaac PetscErrorCode DMLabelSetStratumIS(DMLabel label, PetscInt value, IS is)
11934de306b1SToby Isaac {
11940c3c4a36SLisandro Dalcin   PetscInt       v;
11954de306b1SToby Isaac   PetscErrorCode ierr;
11964de306b1SToby Isaac 
11974de306b1SToby Isaac   PetscFunctionBegin;
1198d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1199d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(is, IS_CLASSID, 3);
1200b9907514SLisandro Dalcin   ierr = DMLabelLookupAddStratum(label, value, &v);CHKERRQ(ierr);
12014de306b1SToby Isaac   if (is == label->points[v]) PetscFunctionReturn(0);
12024de306b1SToby Isaac   ierr = DMLabelClearStratum(label, value);CHKERRQ(ierr);
12034de306b1SToby Isaac   ierr = ISGetLocalSize(is, &(label->stratumSizes[v]));CHKERRQ(ierr);
12044de306b1SToby Isaac   ierr = PetscObjectReference((PetscObject)is);CHKERRQ(ierr);
12054de306b1SToby Isaac   ierr = ISDestroy(&(label->points[v]));CHKERRQ(ierr);
12060c3c4a36SLisandro Dalcin   label->points[v]  = is;
12070c3c4a36SLisandro Dalcin   label->validIS[v] = PETSC_TRUE;
1208277ea44aSLisandro Dalcin   ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr);
12094de306b1SToby Isaac   if (label->bt) {
12104de306b1SToby Isaac     const PetscInt *points;
12114de306b1SToby Isaac     PetscInt p;
12124de306b1SToby Isaac 
12134de306b1SToby Isaac     ierr = ISGetIndices(is,&points);CHKERRQ(ierr);
12144de306b1SToby Isaac     for (p = 0; p < label->stratumSizes[v]; ++p) {
12154de306b1SToby Isaac       const PetscInt point = points[p];
12164de306b1SToby Isaac 
12174de306b1SToby Isaac       if ((point < label->pStart) || (point >= label->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd);
12184de306b1SToby Isaac       ierr = PetscBTSet(label->bt, point - label->pStart);CHKERRQ(ierr);
12194de306b1SToby Isaac     }
12204de306b1SToby Isaac   }
12214de306b1SToby Isaac   PetscFunctionReturn(0);
12224de306b1SToby Isaac }
12234de306b1SToby Isaac 
122484f0b6dfSMatthew G. Knepley /*@
122584f0b6dfSMatthew G. Knepley   DMLabelClearStratum - Remove a stratum
12264de306b1SToby Isaac 
12275b5e7992SMatthew G. Knepley   Not collective
12285b5e7992SMatthew G. Knepley 
122984f0b6dfSMatthew G. Knepley   Input Parameters:
123084f0b6dfSMatthew G. Knepley + label - the DMLabel
123184f0b6dfSMatthew G. Knepley - value - the stratum value
123284f0b6dfSMatthew G. Knepley 
123384f0b6dfSMatthew G. Knepley   Level: intermediate
123484f0b6dfSMatthew G. Knepley 
123584f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
123684f0b6dfSMatthew G. Knepley @*/
1237c58f1c22SToby Isaac PetscErrorCode DMLabelClearStratum(DMLabel label, PetscInt value)
1238c58f1c22SToby Isaac {
1239c58f1c22SToby Isaac   PetscInt       v;
1240c58f1c22SToby Isaac   PetscErrorCode ierr;
1241c58f1c22SToby Isaac 
1242c58f1c22SToby Isaac   PetscFunctionBegin;
1243d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
12440c3c4a36SLisandro Dalcin   ierr = DMLabelLookupStratum(label, value, &v);CHKERRQ(ierr);
12450c3c4a36SLisandro Dalcin   if (v < 0) PetscFunctionReturn(0);
12464de306b1SToby Isaac   if (label->validIS[v]) {
12474de306b1SToby Isaac     if (label->bt) {
1248c58f1c22SToby Isaac       PetscInt       i;
1249ad8374ffSToby Isaac       const PetscInt *points;
1250c58f1c22SToby Isaac 
1251ad8374ffSToby Isaac       ierr = ISGetIndices(label->points[v], &points);CHKERRQ(ierr);
1252c58f1c22SToby Isaac       for (i = 0; i < label->stratumSizes[v]; ++i) {
1253ad8374ffSToby Isaac         const PetscInt point = points[i];
1254c58f1c22SToby Isaac 
1255c58f1c22SToby Isaac         if ((point < label->pStart) || (point >= label->pEnd)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [%D, %D)", point, label->pStart, label->pEnd);
1256c58f1c22SToby Isaac         ierr = PetscBTClear(label->bt, point - label->pStart);CHKERRQ(ierr);
1257c58f1c22SToby Isaac       }
1258ad8374ffSToby Isaac       ierr = ISRestoreIndices(label->points[v], &points);CHKERRQ(ierr);
1259c58f1c22SToby Isaac     }
1260c58f1c22SToby Isaac     label->stratumSizes[v] = 0;
12610c3c4a36SLisandro Dalcin     ierr = ISDestroy(&label->points[v]);CHKERRQ(ierr);
1262277ea44aSLisandro Dalcin     ierr = ISCreateStride(PETSC_COMM_SELF, 0, 0, 1, &label->points[v]);CHKERRQ(ierr);
12630c3c4a36SLisandro Dalcin     ierr = PetscObjectSetName((PetscObject) label->points[v], "indices");CHKERRQ(ierr);
1264277ea44aSLisandro Dalcin     ierr = PetscObjectStateIncrease((PetscObject) label);CHKERRQ(ierr);
1265c58f1c22SToby Isaac   } else {
1266b9907514SLisandro Dalcin     ierr = PetscHSetIClear(label->ht[v]);CHKERRQ(ierr);
1267c58f1c22SToby Isaac   }
1268c58f1c22SToby Isaac   PetscFunctionReturn(0);
1269c58f1c22SToby Isaac }
1270c58f1c22SToby Isaac 
127184f0b6dfSMatthew G. Knepley /*@
127284f0b6dfSMatthew G. Knepley   DMLabelFilter - Remove all points outside of [start, end)
127384f0b6dfSMatthew G. Knepley 
12745b5e7992SMatthew G. Knepley   Not collective
12755b5e7992SMatthew G. Knepley 
127684f0b6dfSMatthew G. Knepley   Input Parameters:
127784f0b6dfSMatthew G. Knepley + label - the DMLabel
127822cd2cdaSVaclav Hapla . start - the first point kept
127922cd2cdaSVaclav Hapla - end - one more than the last point kept
128084f0b6dfSMatthew G. Knepley 
128184f0b6dfSMatthew G. Knepley   Level: intermediate
128284f0b6dfSMatthew G. Knepley 
128384f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
128484f0b6dfSMatthew G. Knepley @*/
1285c58f1c22SToby Isaac PetscErrorCode DMLabelFilter(DMLabel label, PetscInt start, PetscInt end)
1286c58f1c22SToby Isaac {
1287c58f1c22SToby Isaac   PetscInt       v;
1288c58f1c22SToby Isaac   PetscErrorCode ierr;
1289c58f1c22SToby Isaac 
1290c58f1c22SToby Isaac   PetscFunctionBegin;
1291d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
12920c3c4a36SLisandro Dalcin   ierr = DMLabelDestroyIndex(label);CHKERRQ(ierr);
1293c58f1c22SToby Isaac   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
1294c58f1c22SToby Isaac   for (v = 0; v < label->numStrata; ++v) {
12959106b633SVaclav Hapla     ierr = ISGeneralFilter(label->points[v], start, end);CHKERRQ(ierr);
1296c58f1c22SToby Isaac   }
1297c58f1c22SToby Isaac   ierr = DMLabelCreateIndex(label, start, end);CHKERRQ(ierr);
1298c58f1c22SToby Isaac   PetscFunctionReturn(0);
1299c58f1c22SToby Isaac }
1300c58f1c22SToby Isaac 
130184f0b6dfSMatthew G. Knepley /*@
130284f0b6dfSMatthew G. Knepley   DMLabelPermute - Create a new label with permuted points
130384f0b6dfSMatthew G. Knepley 
13045b5e7992SMatthew G. Knepley   Not collective
13055b5e7992SMatthew G. Knepley 
130684f0b6dfSMatthew G. Knepley   Input Parameters:
130784f0b6dfSMatthew G. Knepley + label - the DMLabel
130884f0b6dfSMatthew G. Knepley - permutation - the point permutation
130984f0b6dfSMatthew G. Knepley 
131084f0b6dfSMatthew G. Knepley   Output Parameter:
131184f0b6dfSMatthew G. Knepley . labelnew - the new label containing the permuted points
131284f0b6dfSMatthew G. Knepley 
131384f0b6dfSMatthew G. Knepley   Level: intermediate
131484f0b6dfSMatthew G. Knepley 
131584f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
131684f0b6dfSMatthew G. Knepley @*/
1317c58f1c22SToby Isaac PetscErrorCode DMLabelPermute(DMLabel label, IS permutation, DMLabel *labelNew)
1318c58f1c22SToby Isaac {
1319c58f1c22SToby Isaac   const PetscInt *perm;
1320c58f1c22SToby Isaac   PetscInt        numValues, numPoints, v, q;
1321c58f1c22SToby Isaac   PetscErrorCode  ierr;
1322c58f1c22SToby Isaac 
1323c58f1c22SToby Isaac   PetscFunctionBegin;
1324d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1325d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(permutation, IS_CLASSID, 2);
1326c58f1c22SToby Isaac   ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
1327c58f1c22SToby Isaac   ierr = DMLabelDuplicate(label, labelNew);CHKERRQ(ierr);
1328c58f1c22SToby Isaac   ierr = DMLabelGetNumValues(*labelNew, &numValues);CHKERRQ(ierr);
1329c58f1c22SToby Isaac   ierr = ISGetLocalSize(permutation, &numPoints);CHKERRQ(ierr);
1330c58f1c22SToby Isaac   ierr = ISGetIndices(permutation, &perm);CHKERRQ(ierr);
1331c58f1c22SToby Isaac   for (v = 0; v < numValues; ++v) {
1332c58f1c22SToby Isaac     const PetscInt size   = (*labelNew)->stratumSizes[v];
1333ad8374ffSToby Isaac     const PetscInt *points;
1334ad8374ffSToby Isaac     PetscInt *pointsNew;
1335c58f1c22SToby Isaac 
1336ad8374ffSToby Isaac     ierr = ISGetIndices((*labelNew)->points[v],&points);CHKERRQ(ierr);
1337ad8374ffSToby Isaac     ierr = PetscMalloc1(size,&pointsNew);CHKERRQ(ierr);
1338c58f1c22SToby Isaac     for (q = 0; q < size; ++q) {
1339ad8374ffSToby Isaac       const PetscInt point = points[q];
1340c58f1c22SToby Isaac 
1341c58f1c22SToby Isaac       if ((point < 0) || (point >= numPoints)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Label point %D is not in [0, %D) for the remapping", point, numPoints);
1342ad8374ffSToby Isaac       pointsNew[q] = perm[point];
1343c58f1c22SToby Isaac     }
1344ad8374ffSToby Isaac     ierr = ISRestoreIndices((*labelNew)->points[v],&points);CHKERRQ(ierr);
1345ad8374ffSToby Isaac     ierr = PetscSortInt(size, pointsNew);CHKERRQ(ierr);
1346ad8374ffSToby Isaac     ierr = ISDestroy(&((*labelNew)->points[v]));CHKERRQ(ierr);
1347fa8e8ae5SToby Isaac     if (size > 0 && pointsNew[size - 1] == pointsNew[0] + size - 1) {
1348fa8e8ae5SToby Isaac       ierr = ISCreateStride(PETSC_COMM_SELF,size,pointsNew[0],1,&((*labelNew)->points[v]));CHKERRQ(ierr);
1349fa8e8ae5SToby Isaac       ierr = PetscFree(pointsNew);CHKERRQ(ierr);
1350fa8e8ae5SToby Isaac     } else {
1351ad8374ffSToby Isaac       ierr = ISCreateGeneral(PETSC_COMM_SELF,size,pointsNew,PETSC_OWN_POINTER,&((*labelNew)->points[v]));CHKERRQ(ierr);
1352fa8e8ae5SToby Isaac     }
1353ad8374ffSToby Isaac     ierr = PetscObjectSetName((PetscObject) ((*labelNew)->points[v]), "indices");CHKERRQ(ierr);
1354c58f1c22SToby Isaac   }
1355c58f1c22SToby Isaac   ierr = ISRestoreIndices(permutation, &perm);CHKERRQ(ierr);
1356c58f1c22SToby Isaac   if (label->bt) {
1357c58f1c22SToby Isaac     ierr = PetscBTDestroy(&label->bt);CHKERRQ(ierr);
1358c58f1c22SToby Isaac     ierr = DMLabelCreateIndex(label, label->pStart, label->pEnd);CHKERRQ(ierr);
1359c58f1c22SToby Isaac   }
1360c58f1c22SToby Isaac   PetscFunctionReturn(0);
1361c58f1c22SToby Isaac }
1362c58f1c22SToby Isaac 
136326c55118SMichael Lange PetscErrorCode DMLabelDistribute_Internal(DMLabel label, PetscSF sf, PetscSection *leafSection, PetscInt **leafStrata)
136426c55118SMichael Lange {
136526c55118SMichael Lange   MPI_Comm       comm;
136626c55118SMichael Lange   PetscInt       s, l, nroots, nleaves, dof, offset, size;
136726c55118SMichael Lange   PetscInt      *remoteOffsets, *rootStrata, *rootIdx;
136826c55118SMichael Lange   PetscSection   rootSection;
136926c55118SMichael Lange   PetscSF        labelSF;
137026c55118SMichael Lange   PetscErrorCode ierr;
137126c55118SMichael Lange 
137226c55118SMichael Lange   PetscFunctionBegin;
137326c55118SMichael Lange   if (label) {ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);}
137426c55118SMichael Lange   ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr);
137526c55118SMichael Lange   /* Build a section of stratum values per point, generate the according SF
137626c55118SMichael Lange      and distribute point-wise stratum values to leaves. */
137726c55118SMichael Lange   ierr = PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL);CHKERRQ(ierr);
137826c55118SMichael Lange   ierr = PetscSectionCreate(comm, &rootSection);CHKERRQ(ierr);
137926c55118SMichael Lange   ierr = PetscSectionSetChart(rootSection, 0, nroots);CHKERRQ(ierr);
138026c55118SMichael Lange   if (label) {
138126c55118SMichael Lange     for (s = 0; s < label->numStrata; ++s) {
1382ad8374ffSToby Isaac       const PetscInt *points;
1383ad8374ffSToby Isaac 
1384ad8374ffSToby Isaac       ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr);
138526c55118SMichael Lange       for (l = 0; l < label->stratumSizes[s]; l++) {
1386ad8374ffSToby Isaac         ierr = PetscSectionGetDof(rootSection, points[l], &dof);CHKERRQ(ierr);
1387ad8374ffSToby Isaac         ierr = PetscSectionSetDof(rootSection, points[l], dof+1);CHKERRQ(ierr);
138826c55118SMichael Lange       }
1389ad8374ffSToby Isaac       ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr);
139026c55118SMichael Lange     }
139126c55118SMichael Lange   }
139226c55118SMichael Lange   ierr = PetscSectionSetUp(rootSection);CHKERRQ(ierr);
139326c55118SMichael Lange   /* Create a point-wise array of stratum values */
139426c55118SMichael Lange   ierr = PetscSectionGetStorageSize(rootSection, &size);CHKERRQ(ierr);
139526c55118SMichael Lange   ierr = PetscMalloc1(size, &rootStrata);CHKERRQ(ierr);
139626c55118SMichael Lange   ierr = PetscCalloc1(nroots, &rootIdx);CHKERRQ(ierr);
139726c55118SMichael Lange   if (label) {
139826c55118SMichael Lange     for (s = 0; s < label->numStrata; ++s) {
1399ad8374ffSToby Isaac       const PetscInt *points;
1400ad8374ffSToby Isaac 
1401ad8374ffSToby Isaac       ierr = ISGetIndices(label->points[s], &points);CHKERRQ(ierr);
140226c55118SMichael Lange       for (l = 0; l < label->stratumSizes[s]; l++) {
1403ad8374ffSToby Isaac         const PetscInt p = points[l];
140426c55118SMichael Lange         ierr = PetscSectionGetOffset(rootSection, p, &offset);CHKERRQ(ierr);
140526c55118SMichael Lange         rootStrata[offset+rootIdx[p]++] = label->stratumValues[s];
140626c55118SMichael Lange       }
1407ad8374ffSToby Isaac       ierr = ISRestoreIndices(label->points[s], &points);CHKERRQ(ierr);
140826c55118SMichael Lange     }
140926c55118SMichael Lange   }
141026c55118SMichael Lange   /* Build SF that maps label points to remote processes */
141126c55118SMichael Lange   ierr = PetscSectionCreate(comm, leafSection);CHKERRQ(ierr);
141226c55118SMichael Lange   ierr = PetscSFDistributeSection(sf, rootSection, &remoteOffsets, *leafSection);CHKERRQ(ierr);
141326c55118SMichael Lange   ierr = PetscSFCreateSectionSF(sf, rootSection, remoteOffsets, *leafSection, &labelSF);CHKERRQ(ierr);
141426c55118SMichael Lange   ierr = PetscFree(remoteOffsets);CHKERRQ(ierr);
141526c55118SMichael Lange   /* Send the strata for each point over the derived SF */
141626c55118SMichael Lange   ierr = PetscSectionGetStorageSize(*leafSection, &size);CHKERRQ(ierr);
141726c55118SMichael Lange   ierr = PetscMalloc1(size, leafStrata);CHKERRQ(ierr);
141826c55118SMichael Lange   ierr = PetscSFBcastBegin(labelSF, MPIU_INT, rootStrata, *leafStrata);CHKERRQ(ierr);
141926c55118SMichael Lange   ierr = PetscSFBcastEnd(labelSF, MPIU_INT, rootStrata, *leafStrata);CHKERRQ(ierr);
142026c55118SMichael Lange   /* Clean up */
142126c55118SMichael Lange   ierr = PetscFree(rootStrata);CHKERRQ(ierr);
142226c55118SMichael Lange   ierr = PetscFree(rootIdx);CHKERRQ(ierr);
142326c55118SMichael Lange   ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr);
142426c55118SMichael Lange   ierr = PetscSFDestroy(&labelSF);CHKERRQ(ierr);
142526c55118SMichael Lange   PetscFunctionReturn(0);
142626c55118SMichael Lange }
142726c55118SMichael Lange 
142884f0b6dfSMatthew G. Knepley /*@
142984f0b6dfSMatthew G. Knepley   DMLabelDistribute - Create a new label pushed forward over the PetscSF
143084f0b6dfSMatthew G. Knepley 
14315b5e7992SMatthew G. Knepley   Collective on sf
14325b5e7992SMatthew G. Knepley 
143384f0b6dfSMatthew G. Knepley   Input Parameters:
143484f0b6dfSMatthew G. Knepley + label - the DMLabel
143584f0b6dfSMatthew G. Knepley - sf    - the map from old to new distribution
143684f0b6dfSMatthew G. Knepley 
143784f0b6dfSMatthew G. Knepley   Output Parameter:
143884f0b6dfSMatthew G. Knepley . labelnew - the new redistributed label
143984f0b6dfSMatthew G. Knepley 
144084f0b6dfSMatthew G. Knepley   Level: intermediate
144184f0b6dfSMatthew G. Knepley 
144284f0b6dfSMatthew G. Knepley .seealso: DMLabelCreate(), DMLabelGetValue(), DMLabelSetValue(), DMLabelClearValue()
144384f0b6dfSMatthew G. Knepley @*/
1444c58f1c22SToby Isaac PetscErrorCode DMLabelDistribute(DMLabel label, PetscSF sf, DMLabel *labelNew)
1445c58f1c22SToby Isaac {
1446c58f1c22SToby Isaac   MPI_Comm       comm;
144726c55118SMichael Lange   PetscSection   leafSection;
144826c55118SMichael Lange   PetscInt       p, pStart, pEnd, s, size, dof, offset, stratum;
144926c55118SMichael Lange   PetscInt      *leafStrata, *strataIdx;
1450ad8374ffSToby Isaac   PetscInt     **points;
1451d67d17b1SMatthew G. Knepley   const char    *lname = NULL;
1452c58f1c22SToby Isaac   char          *name;
1453c58f1c22SToby Isaac   PetscInt       nameSize;
1454e8f14785SLisandro Dalcin   PetscHSetI     stratumHash;
1455c58f1c22SToby Isaac   size_t         len = 0;
145626c55118SMichael Lange   PetscMPIInt    rank;
1457c58f1c22SToby Isaac   PetscErrorCode ierr;
1458c58f1c22SToby Isaac 
1459c58f1c22SToby Isaac   PetscFunctionBegin;
1460d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
1461f018e600SMatthew G. Knepley   if (label) {
1462f018e600SMatthew G. Knepley     PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1463f018e600SMatthew G. Knepley     ierr = DMLabelMakeAllValid_Private(label);CHKERRQ(ierr);
1464f018e600SMatthew G. Knepley   }
1465c58f1c22SToby Isaac   ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr);
1466c58f1c22SToby Isaac   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
1467c58f1c22SToby Isaac   /* Bcast name */
1468d67d17b1SMatthew G. Knepley   if (!rank) {
1469d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
1470d67d17b1SMatthew G. Knepley     ierr = PetscStrlen(lname, &len);CHKERRQ(ierr);
1471d67d17b1SMatthew G. Knepley   }
1472c58f1c22SToby Isaac   nameSize = len;
1473c58f1c22SToby Isaac   ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRQ(ierr);
1474c58f1c22SToby Isaac   ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr);
1475580bdb30SBarry Smith   if (!rank) {ierr = PetscArraycpy(name, lname, nameSize+1);CHKERRQ(ierr);}
1476c58f1c22SToby Isaac   ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRQ(ierr);
1477d67d17b1SMatthew G. Knepley   ierr = DMLabelCreate(PETSC_COMM_SELF, name, labelNew);CHKERRQ(ierr);
1478c58f1c22SToby Isaac   ierr = PetscFree(name);CHKERRQ(ierr);
147977d236dfSMichael Lange   /* Bcast defaultValue */
148077d236dfSMichael Lange   if (!rank) (*labelNew)->defaultValue = label->defaultValue;
148177d236dfSMichael Lange   ierr = MPI_Bcast(&(*labelNew)->defaultValue, 1, MPIU_INT, 0, comm);CHKERRQ(ierr);
148226c55118SMichael Lange   /* Distribute stratum values over the SF and get the point mapping on the receiver */
148326c55118SMichael Lange   ierr = DMLabelDistribute_Internal(label, sf, &leafSection, &leafStrata);CHKERRQ(ierr);
14845cbdf6fcSMichael Lange   /* Determine received stratum values and initialise new label*/
1485e8f14785SLisandro Dalcin   ierr = PetscHSetICreate(&stratumHash);CHKERRQ(ierr);
148626c55118SMichael Lange   ierr = PetscSectionGetStorageSize(leafSection, &size);CHKERRQ(ierr);
1487e8f14785SLisandro Dalcin   for (p = 0; p < size; ++p) {ierr = PetscHSetIAdd(stratumHash, leafStrata[p]);CHKERRQ(ierr);}
1488e8f14785SLisandro Dalcin   ierr = PetscHSetIGetSize(stratumHash, &(*labelNew)->numStrata);CHKERRQ(ierr);
1489ad8374ffSToby Isaac   ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->validIS);CHKERRQ(ierr);
1490ad8374ffSToby Isaac   for (s = 0; s < (*labelNew)->numStrata; ++s) (*labelNew)->validIS[s] = PETSC_TRUE;
14915cbdf6fcSMichael Lange   ierr = PetscMalloc1((*labelNew)->numStrata, &(*labelNew)->stratumValues);CHKERRQ(ierr);
14925cbdf6fcSMichael Lange   /* Turn leafStrata into indices rather than stratum values */
14935cbdf6fcSMichael Lange   offset = 0;
1494e8f14785SLisandro Dalcin   ierr = PetscHSetIGetElems(stratumHash, &offset, (*labelNew)->stratumValues);CHKERRQ(ierr);
1495a205f1fdSToby Isaac   ierr = PetscSortInt((*labelNew)->numStrata,(*labelNew)->stratumValues);CHKERRQ(ierr);
149690e9b2aeSLisandro Dalcin   for (s = 0; s < (*labelNew)->numStrata; ++s) {
149790e9b2aeSLisandro Dalcin     ierr = PetscHMapISet((*labelNew)->hmap, (*labelNew)->stratumValues[s], s);CHKERRQ(ierr);
149890e9b2aeSLisandro Dalcin   }
14995cbdf6fcSMichael Lange   for (p = 0; p < size; ++p) {
1500231b9e6fSMatthew G. Knepley     for (s = 0; s < (*labelNew)->numStrata; ++s) {
1501231b9e6fSMatthew G. Knepley       if (leafStrata[p] == (*labelNew)->stratumValues[s]) {leafStrata[p] = s; break;}
15025cbdf6fcSMichael Lange     }
15035cbdf6fcSMichael Lange   }
1504c58f1c22SToby Isaac   /* Rebuild the point strata on the receiver */
1505c58f1c22SToby Isaac   ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->stratumSizes);CHKERRQ(ierr);
1506c58f1c22SToby Isaac   ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr);
1507c58f1c22SToby Isaac   for (p=pStart; p<pEnd; p++) {
1508c58f1c22SToby Isaac     ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr);
1509c58f1c22SToby Isaac     ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr);
1510c58f1c22SToby Isaac     for (s=0; s<dof; s++) {
1511c58f1c22SToby Isaac       (*labelNew)->stratumSizes[leafStrata[offset+s]]++;
1512c58f1c22SToby Isaac     }
1513c58f1c22SToby Isaac   }
1514c58f1c22SToby Isaac   ierr = PetscCalloc1((*labelNew)->numStrata,&(*labelNew)->ht);CHKERRQ(ierr);
1515c58f1c22SToby Isaac   ierr = PetscMalloc1((*labelNew)->numStrata,&(*labelNew)->points);CHKERRQ(ierr);
1516ad8374ffSToby Isaac   ierr = PetscMalloc1((*labelNew)->numStrata,&points);CHKERRQ(ierr);
1517c58f1c22SToby Isaac   for (s = 0; s < (*labelNew)->numStrata; ++s) {
1518e8f14785SLisandro Dalcin     ierr = PetscHSetICreate(&(*labelNew)->ht[s]);CHKERRQ(ierr);
1519ad8374ffSToby Isaac     ierr = PetscMalloc1((*labelNew)->stratumSizes[s], &(points[s]));CHKERRQ(ierr);
1520c58f1c22SToby Isaac   }
1521c58f1c22SToby Isaac   /* Insert points into new strata */
1522c58f1c22SToby Isaac   ierr = PetscCalloc1((*labelNew)->numStrata, &strataIdx);CHKERRQ(ierr);
1523c58f1c22SToby Isaac   ierr = PetscSectionGetChart(leafSection, &pStart, &pEnd);CHKERRQ(ierr);
1524c58f1c22SToby Isaac   for (p=pStart; p<pEnd; p++) {
1525c58f1c22SToby Isaac     ierr = PetscSectionGetDof(leafSection, p, &dof);CHKERRQ(ierr);
1526c58f1c22SToby Isaac     ierr = PetscSectionGetOffset(leafSection, p, &offset);CHKERRQ(ierr);
1527c58f1c22SToby Isaac     for (s=0; s<dof; s++) {
1528c58f1c22SToby Isaac       stratum = leafStrata[offset+s];
1529ad8374ffSToby Isaac       points[stratum][strataIdx[stratum]++] = p;
1530c58f1c22SToby Isaac     }
1531c58f1c22SToby Isaac   }
1532ad8374ffSToby Isaac   for (s = 0; s < (*labelNew)->numStrata; s++) {
1533ad8374ffSToby Isaac     ierr = ISCreateGeneral(PETSC_COMM_SELF,(*labelNew)->stratumSizes[s],&(points[s][0]),PETSC_OWN_POINTER,&((*labelNew)->points[s]));CHKERRQ(ierr);
1534ad8374ffSToby Isaac     ierr = PetscObjectSetName((PetscObject)((*labelNew)->points[s]),"indices");CHKERRQ(ierr);
1535ad8374ffSToby Isaac   }
1536ad8374ffSToby Isaac   ierr = PetscFree(points);CHKERRQ(ierr);
1537e8f14785SLisandro Dalcin   ierr = PetscHSetIDestroy(&stratumHash);CHKERRQ(ierr);
1538c58f1c22SToby Isaac   ierr = PetscFree(leafStrata);CHKERRQ(ierr);
1539c58f1c22SToby Isaac   ierr = PetscFree(strataIdx);CHKERRQ(ierr);
1540c58f1c22SToby Isaac   ierr = PetscSectionDestroy(&leafSection);CHKERRQ(ierr);
1541c58f1c22SToby Isaac   PetscFunctionReturn(0);
1542c58f1c22SToby Isaac }
1543c58f1c22SToby Isaac 
15447937d9ceSMichael Lange /*@
15457937d9ceSMichael Lange   DMLabelGather - Gather all label values from leafs into roots
15467937d9ceSMichael Lange 
15475b5e7992SMatthew G. Knepley   Collective on sf
15485b5e7992SMatthew G. Knepley 
15497937d9ceSMichael Lange   Input Parameters:
15507937d9ceSMichael Lange + label - the DMLabel
155184f0b6dfSMatthew G. Knepley - sf - the Star Forest point communication map
15527937d9ceSMichael Lange 
155384f0b6dfSMatthew G. Knepley   Output Parameters:
155484f0b6dfSMatthew G. Knepley . labelNew - the new DMLabel with localised leaf values
15557937d9ceSMichael Lange 
15567937d9ceSMichael Lange   Level: developer
15577937d9ceSMichael Lange 
15587937d9ceSMichael Lange   Note: This is the inverse operation to DMLabelDistribute.
15597937d9ceSMichael Lange 
15607937d9ceSMichael Lange .seealso: DMLabelDistribute()
15617937d9ceSMichael Lange @*/
15627937d9ceSMichael Lange PetscErrorCode DMLabelGather(DMLabel label, PetscSF sf, DMLabel *labelNew)
15637937d9ceSMichael Lange {
15647937d9ceSMichael Lange   MPI_Comm       comm;
15657937d9ceSMichael Lange   PetscSection   rootSection;
15667937d9ceSMichael Lange   PetscSF        sfLabel;
15677937d9ceSMichael Lange   PetscSFNode   *rootPoints, *leafPoints;
15687937d9ceSMichael Lange   PetscInt       p, s, d, nroots, nleaves, nmultiroots, idx, dof, offset;
15697937d9ceSMichael Lange   const PetscInt *rootDegree, *ilocal;
15707937d9ceSMichael Lange   PetscInt       *rootStrata;
1571d67d17b1SMatthew G. Knepley   const char    *lname;
15727937d9ceSMichael Lange   char          *name;
15737937d9ceSMichael Lange   PetscInt       nameSize;
15747937d9ceSMichael Lange   size_t         len = 0;
15759852e123SBarry Smith   PetscMPIInt    rank, size;
15767937d9ceSMichael Lange   PetscErrorCode ierr;
15777937d9ceSMichael Lange 
15787937d9ceSMichael Lange   PetscFunctionBegin;
1579d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1580d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
15817937d9ceSMichael Lange   ierr = PetscObjectGetComm((PetscObject)sf, &comm);CHKERRQ(ierr);
15827937d9ceSMichael Lange   ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr);
15839852e123SBarry Smith   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
15847937d9ceSMichael Lange   /* Bcast name */
1585d67d17b1SMatthew G. Knepley   if (!rank) {
1586d67d17b1SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
1587d67d17b1SMatthew G. Knepley     ierr = PetscStrlen(lname, &len);CHKERRQ(ierr);
1588d67d17b1SMatthew G. Knepley   }
15897937d9ceSMichael Lange   nameSize = len;
15907937d9ceSMichael Lange   ierr = MPI_Bcast(&nameSize, 1, MPIU_INT, 0, comm);CHKERRQ(ierr);
15917937d9ceSMichael Lange   ierr = PetscMalloc1(nameSize+1, &name);CHKERRQ(ierr);
1592580bdb30SBarry Smith   if (!rank) {ierr = PetscArraycpy(name, lname, nameSize+1);CHKERRQ(ierr);}
15937937d9ceSMichael Lange   ierr = MPI_Bcast(name, nameSize+1, MPI_CHAR, 0, comm);CHKERRQ(ierr);
1594d67d17b1SMatthew G. Knepley   ierr = DMLabelCreate(PETSC_COMM_SELF, name, labelNew);CHKERRQ(ierr);
15957937d9ceSMichael Lange   ierr = PetscFree(name);CHKERRQ(ierr);
15967937d9ceSMichael Lange   /* Gather rank/index pairs of leaves into local roots to build
15977937d9ceSMichael Lange      an inverse, multi-rooted SF. Note that this ignores local leaf
15987937d9ceSMichael Lange      indexing due to the use of the multiSF in PetscSFGather. */
15997937d9ceSMichael Lange   ierr = PetscSFGetGraph(sf, &nroots, &nleaves, &ilocal, NULL);CHKERRQ(ierr);
1600dc53bc9bSMatthew G. Knepley   ierr = PetscMalloc1(nroots, &leafPoints);CHKERRQ(ierr);
1601dc53bc9bSMatthew G. Knepley   for (p = 0; p < nroots; ++p) leafPoints[p].rank = leafPoints[p].index = -1;
16027937d9ceSMichael Lange   for (p = 0; p < nleaves; p++) {
16038212dd46SStefano Zampini     PetscInt ilp = ilocal ? ilocal[p] : p;
16048212dd46SStefano Zampini 
16058212dd46SStefano Zampini     leafPoints[ilp].index = ilp;
16068212dd46SStefano Zampini     leafPoints[ilp].rank  = rank;
16077937d9ceSMichael Lange   }
16087937d9ceSMichael Lange   ierr = PetscSFComputeDegreeBegin(sf, &rootDegree);CHKERRQ(ierr);
16097937d9ceSMichael Lange   ierr = PetscSFComputeDegreeEnd(sf, &rootDegree);CHKERRQ(ierr);
16107937d9ceSMichael Lange   for (p = 0, nmultiroots = 0; p < nroots; ++p) nmultiroots += rootDegree[p];
16117937d9ceSMichael Lange   ierr = PetscMalloc1(nmultiroots, &rootPoints);CHKERRQ(ierr);
16127937d9ceSMichael Lange   ierr = PetscSFGatherBegin(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr);
16137937d9ceSMichael Lange   ierr = PetscSFGatherEnd(sf, MPIU_2INT, leafPoints, rootPoints);CHKERRQ(ierr);
16147937d9ceSMichael Lange   ierr = PetscSFCreate(comm,& sfLabel);CHKERRQ(ierr);
16157937d9ceSMichael Lange   ierr = PetscSFSetGraph(sfLabel, nroots, nmultiroots, NULL, PETSC_OWN_POINTER, rootPoints, PETSC_OWN_POINTER);CHKERRQ(ierr);
16167937d9ceSMichael Lange   /* Migrate label over inverted SF to pull stratum values at leaves into roots. */
16177937d9ceSMichael Lange   ierr = DMLabelDistribute_Internal(label, sfLabel, &rootSection, &rootStrata);CHKERRQ(ierr);
16187937d9ceSMichael Lange   /* Rebuild the point strata on the receiver */
16197937d9ceSMichael Lange   for (p = 0, idx = 0; p < nroots; p++) {
16207937d9ceSMichael Lange     for (d = 0; d < rootDegree[p]; d++) {
16217937d9ceSMichael Lange       ierr = PetscSectionGetDof(rootSection, idx+d, &dof);CHKERRQ(ierr);
16227937d9ceSMichael Lange       ierr = PetscSectionGetOffset(rootSection, idx+d, &offset);CHKERRQ(ierr);
16237937d9ceSMichael Lange       for (s = 0; s < dof; s++) {ierr = DMLabelSetValue(*labelNew, p, rootStrata[offset+s]);CHKERRQ(ierr);}
16247937d9ceSMichael Lange     }
16257937d9ceSMichael Lange     idx += rootDegree[p];
16267937d9ceSMichael Lange   }
162777e0c0e7SMichael Lange   ierr = PetscFree(leafPoints);CHKERRQ(ierr);
162877e0c0e7SMichael Lange   ierr = PetscFree(rootStrata);CHKERRQ(ierr);
162977e0c0e7SMichael Lange   ierr = PetscSectionDestroy(&rootSection);CHKERRQ(ierr);
163077e0c0e7SMichael Lange   ierr = PetscSFDestroy(&sfLabel);CHKERRQ(ierr);
16317937d9ceSMichael Lange   PetscFunctionReturn(0);
16327937d9ceSMichael Lange }
16337937d9ceSMichael Lange 
163484f0b6dfSMatthew G. Knepley /*@
163584f0b6dfSMatthew G. Knepley   DMLabelConvertToSection - Make a PetscSection/IS pair that encodes the label
163684f0b6dfSMatthew G. Knepley 
16375b5e7992SMatthew G. Knepley   Not collective
16385b5e7992SMatthew G. Knepley 
163984f0b6dfSMatthew G. Knepley   Input Parameter:
164084f0b6dfSMatthew G. Knepley . label - the DMLabel
164184f0b6dfSMatthew G. Knepley 
164284f0b6dfSMatthew G. Knepley   Output Parameters:
164384f0b6dfSMatthew G. Knepley + section - the section giving offsets for each stratum
164484f0b6dfSMatthew G. Knepley - is - An IS containing all the label points
164584f0b6dfSMatthew G. Knepley 
164684f0b6dfSMatthew G. Knepley   Level: developer
164784f0b6dfSMatthew G. Knepley 
164884f0b6dfSMatthew G. Knepley .seealso: DMLabelDistribute()
164984f0b6dfSMatthew G. Knepley @*/
1650c58f1c22SToby Isaac PetscErrorCode DMLabelConvertToSection(DMLabel label, PetscSection *section, IS *is)
1651c58f1c22SToby Isaac {
1652c58f1c22SToby Isaac   IS              vIS;
1653c58f1c22SToby Isaac   const PetscInt *values;
1654c58f1c22SToby Isaac   PetscInt       *points;
1655c58f1c22SToby Isaac   PetscInt        nV, vS = 0, vE = 0, v, N;
1656c58f1c22SToby Isaac   PetscErrorCode  ierr;
1657c58f1c22SToby Isaac 
1658c58f1c22SToby Isaac   PetscFunctionBegin;
1659d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 1);
1660c58f1c22SToby Isaac   ierr = DMLabelGetNumValues(label, &nV);CHKERRQ(ierr);
1661c58f1c22SToby Isaac   ierr = DMLabelGetValueIS(label, &vIS);CHKERRQ(ierr);
1662c58f1c22SToby Isaac   ierr = ISGetIndices(vIS, &values);CHKERRQ(ierr);
1663c58f1c22SToby Isaac   if (nV) {vS = values[0]; vE = values[0]+1;}
1664c58f1c22SToby Isaac   for (v = 1; v < nV; ++v) {
1665c58f1c22SToby Isaac     vS = PetscMin(vS, values[v]);
1666c58f1c22SToby Isaac     vE = PetscMax(vE, values[v]+1);
1667c58f1c22SToby Isaac   }
1668c58f1c22SToby Isaac   ierr = PetscSectionCreate(PETSC_COMM_SELF, section);CHKERRQ(ierr);
1669c58f1c22SToby Isaac   ierr = PetscSectionSetChart(*section, vS, vE);CHKERRQ(ierr);
1670c58f1c22SToby Isaac   for (v = 0; v < nV; ++v) {
1671c58f1c22SToby Isaac     PetscInt n;
1672c58f1c22SToby Isaac 
1673c58f1c22SToby Isaac     ierr = DMLabelGetStratumSize(label, values[v], &n);CHKERRQ(ierr);
1674c58f1c22SToby Isaac     ierr = PetscSectionSetDof(*section, values[v], n);CHKERRQ(ierr);
1675c58f1c22SToby Isaac   }
1676c58f1c22SToby Isaac   ierr = PetscSectionSetUp(*section);CHKERRQ(ierr);
1677c58f1c22SToby Isaac   ierr = PetscSectionGetStorageSize(*section, &N);CHKERRQ(ierr);
1678c58f1c22SToby Isaac   ierr = PetscMalloc1(N, &points);CHKERRQ(ierr);
1679c58f1c22SToby Isaac   for (v = 0; v < nV; ++v) {
1680c58f1c22SToby Isaac     IS              is;
1681c58f1c22SToby Isaac     const PetscInt *spoints;
1682c58f1c22SToby Isaac     PetscInt        dof, off, p;
1683c58f1c22SToby Isaac 
1684c58f1c22SToby Isaac     ierr = PetscSectionGetDof(*section, values[v], &dof);CHKERRQ(ierr);
1685c58f1c22SToby Isaac     ierr = PetscSectionGetOffset(*section, values[v], &off);CHKERRQ(ierr);
1686c58f1c22SToby Isaac     ierr = DMLabelGetStratumIS(label, values[v], &is);CHKERRQ(ierr);
1687c58f1c22SToby Isaac     ierr = ISGetIndices(is, &spoints);CHKERRQ(ierr);
1688c58f1c22SToby Isaac     for (p = 0; p < dof; ++p) points[off+p] = spoints[p];
1689c58f1c22SToby Isaac     ierr = ISRestoreIndices(is, &spoints);CHKERRQ(ierr);
1690c58f1c22SToby Isaac     ierr = ISDestroy(&is);CHKERRQ(ierr);
1691c58f1c22SToby Isaac   }
1692c58f1c22SToby Isaac   ierr = ISRestoreIndices(vIS, &values);CHKERRQ(ierr);
1693c58f1c22SToby Isaac   ierr = ISDestroy(&vIS);CHKERRQ(ierr);
1694c58f1c22SToby Isaac   ierr = ISCreateGeneral(PETSC_COMM_SELF, N, points, PETSC_OWN_POINTER, is);CHKERRQ(ierr);
1695c58f1c22SToby Isaac   PetscFunctionReturn(0);
1696c58f1c22SToby Isaac }
1697c58f1c22SToby Isaac 
169884f0b6dfSMatthew G. Knepley /*@
1699c58f1c22SToby Isaac   PetscSectionCreateGlobalSectionLabel - Create a section describing the global field layout using
1700c58f1c22SToby Isaac   the local section and an SF describing the section point overlap.
1701c58f1c22SToby Isaac 
17025b5e7992SMatthew G. Knepley   Collective on sf
17035b5e7992SMatthew G. Knepley 
1704c58f1c22SToby Isaac   Input Parameters:
1705c58f1c22SToby Isaac   + s - The PetscSection for the local field layout
1706c58f1c22SToby Isaac   . sf - The SF describing parallel layout of the section points
1707c58f1c22SToby Isaac   . includeConstraints - By default this is PETSC_FALSE, meaning that the global field vector will not possess constrained dofs
1708c58f1c22SToby Isaac   . label - The label specifying the points
1709c58f1c22SToby Isaac   - labelValue - The label stratum specifying the points
1710c58f1c22SToby Isaac 
1711c58f1c22SToby Isaac   Output Parameter:
1712c58f1c22SToby Isaac   . gsection - The PetscSection for the global field layout
1713c58f1c22SToby Isaac 
1714c58f1c22SToby Isaac   Note: This gives negative sizes and offsets to points not owned by this process
1715c58f1c22SToby Isaac 
1716c58f1c22SToby Isaac   Level: developer
1717c58f1c22SToby Isaac 
1718c58f1c22SToby Isaac .seealso: PetscSectionCreate()
1719c58f1c22SToby Isaac @*/
1720c58f1c22SToby Isaac PetscErrorCode PetscSectionCreateGlobalSectionLabel(PetscSection s, PetscSF sf, PetscBool includeConstraints, DMLabel label, PetscInt labelValue, PetscSection *gsection)
1721c58f1c22SToby Isaac {
1722c58f1c22SToby Isaac   PetscInt      *neg = NULL, *tmpOff = NULL;
1723c58f1c22SToby Isaac   PetscInt       pStart, pEnd, p, dof, cdof, off, globalOff = 0, nroots;
1724c58f1c22SToby Isaac   PetscErrorCode ierr;
1725c58f1c22SToby Isaac 
1726c58f1c22SToby Isaac   PetscFunctionBegin;
1727d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(s, PETSC_SECTION_CLASSID, 1);
1728d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 2);
1729d67d17b1SMatthew G. Knepley   PetscValidHeaderSpecific(label, DMLABEL_CLASSID, 4);
1730c58f1c22SToby Isaac   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) s), gsection);CHKERRQ(ierr);
1731c58f1c22SToby Isaac   ierr = PetscSectionGetChart(s, &pStart, &pEnd);CHKERRQ(ierr);
1732c58f1c22SToby Isaac   ierr = PetscSectionSetChart(*gsection, pStart, pEnd);CHKERRQ(ierr);
1733c58f1c22SToby Isaac   ierr = PetscSFGetGraph(sf, &nroots, NULL, NULL, NULL);CHKERRQ(ierr);
1734c58f1c22SToby Isaac   if (nroots >= 0) {
1735c58f1c22SToby Isaac     if (nroots < pEnd-pStart) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "PetscSF nroots %d < %d section size", nroots, pEnd-pStart);
1736c58f1c22SToby Isaac     ierr = PetscCalloc1(nroots, &neg);CHKERRQ(ierr);
1737c58f1c22SToby Isaac     if (nroots > pEnd-pStart) {
1738c58f1c22SToby Isaac       ierr = PetscCalloc1(nroots, &tmpOff);CHKERRQ(ierr);
1739c58f1c22SToby Isaac     } else {
1740c58f1c22SToby Isaac       tmpOff = &(*gsection)->atlasDof[-pStart];
1741c58f1c22SToby Isaac     }
1742c58f1c22SToby Isaac   }
1743c58f1c22SToby Isaac   /* Mark ghost points with negative dof */
1744c58f1c22SToby Isaac   for (p = pStart; p < pEnd; ++p) {
1745c58f1c22SToby Isaac     PetscInt value;
1746c58f1c22SToby Isaac 
1747c58f1c22SToby Isaac     ierr = DMLabelGetValue(label, p, &value);CHKERRQ(ierr);
1748c58f1c22SToby Isaac     if (value != labelValue) continue;
1749c58f1c22SToby Isaac     ierr = PetscSectionGetDof(s, p, &dof);CHKERRQ(ierr);
1750c58f1c22SToby Isaac     ierr = PetscSectionSetDof(*gsection, p, dof);CHKERRQ(ierr);
1751c58f1c22SToby Isaac     ierr = PetscSectionGetConstraintDof(s, p, &cdof);CHKERRQ(ierr);
1752c58f1c22SToby Isaac     if (!includeConstraints && cdof > 0) {ierr = PetscSectionSetConstraintDof(*gsection, p, cdof);CHKERRQ(ierr);}
1753c58f1c22SToby Isaac     if (neg) neg[p] = -(dof+1);
1754c58f1c22SToby Isaac   }
1755c58f1c22SToby Isaac   ierr = PetscSectionSetUpBC(*gsection);CHKERRQ(ierr);
1756c58f1c22SToby Isaac   if (nroots >= 0) {
1757c58f1c22SToby Isaac     ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr);
1758c58f1c22SToby Isaac     ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr);
1759c58f1c22SToby Isaac     if (nroots > pEnd-pStart) {
1760c58f1c22SToby Isaac       for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasDof[p-pStart] = tmpOff[p];}
1761c58f1c22SToby Isaac     }
1762c58f1c22SToby Isaac   }
1763c58f1c22SToby Isaac   /* Calculate new sizes, get proccess offset, and calculate point offsets */
1764c58f1c22SToby Isaac   for (p = 0, off = 0; p < pEnd-pStart; ++p) {
1765c58f1c22SToby Isaac     cdof = (!includeConstraints && s->bc) ? s->bc->atlasDof[p] : 0;
1766c58f1c22SToby Isaac     (*gsection)->atlasOff[p] = off;
1767c58f1c22SToby Isaac     off += (*gsection)->atlasDof[p] > 0 ? (*gsection)->atlasDof[p]-cdof : 0;
1768c58f1c22SToby Isaac   }
1769c58f1c22SToby Isaac   ierr       = MPI_Scan(&off, &globalOff, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject) s));CHKERRQ(ierr);
1770c58f1c22SToby Isaac   globalOff -= off;
1771c58f1c22SToby Isaac   for (p = 0, off = 0; p < pEnd-pStart; ++p) {
1772c58f1c22SToby Isaac     (*gsection)->atlasOff[p] += globalOff;
1773c58f1c22SToby Isaac     if (neg) neg[p] = -((*gsection)->atlasOff[p]+1);
1774c58f1c22SToby Isaac   }
1775c58f1c22SToby Isaac   /* Put in negative offsets for ghost points */
1776c58f1c22SToby Isaac   if (nroots >= 0) {
1777c58f1c22SToby Isaac     ierr = PetscSFBcastBegin(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr);
1778c58f1c22SToby Isaac     ierr = PetscSFBcastEnd(sf, MPIU_INT, neg, tmpOff);CHKERRQ(ierr);
1779c58f1c22SToby Isaac     if (nroots > pEnd-pStart) {
1780c58f1c22SToby Isaac       for (p = pStart; p < pEnd; ++p) {if (tmpOff[p] < 0) (*gsection)->atlasOff[p-pStart] = tmpOff[p];}
1781c58f1c22SToby Isaac     }
1782c58f1c22SToby Isaac   }
1783c58f1c22SToby Isaac   if (nroots >= 0 && nroots > pEnd-pStart) {ierr = PetscFree(tmpOff);CHKERRQ(ierr);}
1784c58f1c22SToby Isaac   ierr = PetscFree(neg);CHKERRQ(ierr);
1785c58f1c22SToby Isaac   PetscFunctionReturn(0);
1786c58f1c22SToby Isaac }
1787c58f1c22SToby Isaac 
17885fdea053SToby Isaac typedef struct _n_PetscSectionSym_Label
17895fdea053SToby Isaac {
17905fdea053SToby Isaac   DMLabel           label;
17915fdea053SToby Isaac   PetscCopyMode     *modes;
17925fdea053SToby Isaac   PetscInt          *sizes;
17935fdea053SToby Isaac   const PetscInt    ***perms;
17945fdea053SToby Isaac   const PetscScalar ***rots;
17955fdea053SToby Isaac   PetscInt          (*minMaxOrients)[2];
17965fdea053SToby Isaac   PetscInt          numStrata; /* numStrata is only increasing, functions as a state */
17975fdea053SToby Isaac } PetscSectionSym_Label;
17985fdea053SToby Isaac 
17995fdea053SToby Isaac static PetscErrorCode PetscSectionSymLabelReset(PetscSectionSym sym)
18005fdea053SToby Isaac {
18015fdea053SToby Isaac   PetscInt              i, j;
18025fdea053SToby Isaac   PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data;
18035fdea053SToby Isaac   PetscErrorCode        ierr;
18045fdea053SToby Isaac 
18055fdea053SToby Isaac   PetscFunctionBegin;
18065fdea053SToby Isaac   for (i = 0; i <= sl->numStrata; i++) {
18075fdea053SToby Isaac     if (sl->modes[i] == PETSC_OWN_POINTER || sl->modes[i] == PETSC_COPY_VALUES) {
18085fdea053SToby Isaac       for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) {
18095fdea053SToby Isaac         if (sl->perms[i]) {ierr = PetscFree(sl->perms[i][j]);CHKERRQ(ierr);}
18105fdea053SToby Isaac         if (sl->rots[i]) {ierr = PetscFree(sl->rots[i][j]);CHKERRQ(ierr);}
18115fdea053SToby Isaac       }
18125fdea053SToby Isaac       if (sl->perms[i]) {
18135fdea053SToby Isaac         const PetscInt **perms = &sl->perms[i][sl->minMaxOrients[i][0]];
18145fdea053SToby Isaac 
18155fdea053SToby Isaac         ierr = PetscFree(perms);CHKERRQ(ierr);
18165fdea053SToby Isaac       }
18175fdea053SToby Isaac       if (sl->rots[i]) {
18185fdea053SToby Isaac         const PetscScalar **rots = &sl->rots[i][sl->minMaxOrients[i][0]];
18195fdea053SToby Isaac 
18205fdea053SToby Isaac         ierr = PetscFree(rots);CHKERRQ(ierr);
18215fdea053SToby Isaac       }
18225fdea053SToby Isaac     }
18235fdea053SToby Isaac   }
18245fdea053SToby Isaac   ierr = PetscFree5(sl->modes,sl->sizes,sl->perms,sl->rots,sl->minMaxOrients);CHKERRQ(ierr);
18255fdea053SToby Isaac   ierr = DMLabelDestroy(&sl->label);CHKERRQ(ierr);
18265fdea053SToby Isaac   sl->numStrata = 0;
18275fdea053SToby Isaac   PetscFunctionReturn(0);
18285fdea053SToby Isaac }
18295fdea053SToby Isaac 
18305fdea053SToby Isaac static PetscErrorCode PetscSectionSymDestroy_Label(PetscSectionSym sym)
18315fdea053SToby Isaac {
18325fdea053SToby Isaac   PetscErrorCode ierr;
18335fdea053SToby Isaac 
18345fdea053SToby Isaac   PetscFunctionBegin;
18355fdea053SToby Isaac   ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr);
18365fdea053SToby Isaac   ierr = PetscFree(sym->data);CHKERRQ(ierr);
18375fdea053SToby Isaac   PetscFunctionReturn(0);
18385fdea053SToby Isaac }
18395fdea053SToby Isaac 
18405fdea053SToby Isaac static PetscErrorCode PetscSectionSymView_Label(PetscSectionSym sym, PetscViewer viewer)
18415fdea053SToby Isaac {
18425fdea053SToby Isaac   PetscSectionSym_Label *sl = (PetscSectionSym_Label *) sym->data;
18435fdea053SToby Isaac   PetscBool             isAscii;
18445fdea053SToby Isaac   DMLabel               label = sl->label;
1845d67d17b1SMatthew G. Knepley   const char           *name;
18465fdea053SToby Isaac   PetscErrorCode        ierr;
18475fdea053SToby Isaac 
18485fdea053SToby Isaac   PetscFunctionBegin;
18495fdea053SToby Isaac   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isAscii);CHKERRQ(ierr);
18505fdea053SToby Isaac   if (isAscii) {
18515fdea053SToby Isaac     PetscInt          i, j, k;
18525fdea053SToby Isaac     PetscViewerFormat format;
18535fdea053SToby Isaac 
18545fdea053SToby Isaac     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
18555fdea053SToby Isaac     if (label) {
18565fdea053SToby Isaac       ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
18575fdea053SToby Isaac       if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
18585fdea053SToby Isaac         ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
18595fdea053SToby Isaac         ierr = DMLabelView(label, viewer);CHKERRQ(ierr);
18605fdea053SToby Isaac         ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
18615fdea053SToby Isaac       } else {
1862d67d17b1SMatthew G. Knepley         ierr = PetscObjectGetName((PetscObject) sl->label, &name);CHKERRQ(ierr);
1863d67d17b1SMatthew G. Knepley         ierr = PetscViewerASCIIPrintf(viewer,"  Label '%s'\n",name);CHKERRQ(ierr);
18645fdea053SToby Isaac       }
18655fdea053SToby Isaac     } else {
18665fdea053SToby Isaac       ierr = PetscViewerASCIIPrintf(viewer, "No label given\n");CHKERRQ(ierr);
18675fdea053SToby Isaac     }
18685fdea053SToby Isaac     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
18695fdea053SToby Isaac     for (i = 0; i <= sl->numStrata; i++) {
18705fdea053SToby Isaac       PetscInt value = i < sl->numStrata ? label->stratumValues[i] : label->defaultValue;
18715fdea053SToby Isaac 
18725fdea053SToby Isaac       if (!(sl->perms[i] || sl->rots[i])) {
18735fdea053SToby Isaac         ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point): no symmetries\n", value, sl->sizes[i]);CHKERRQ(ierr);
18745fdea053SToby Isaac       } else {
18755fdea053SToby Isaac       ierr = PetscViewerASCIIPrintf(viewer, "Symmetry for stratum value %D (%D dofs per point):\n", value, sl->sizes[i]);CHKERRQ(ierr);
18765fdea053SToby Isaac         ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
18775fdea053SToby Isaac         ierr = PetscViewerASCIIPrintf(viewer, "Orientation range: [%D, %D)\n", sl->minMaxOrients[i][0], sl->minMaxOrients[i][1]);CHKERRQ(ierr);
18785fdea053SToby Isaac         if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
18795fdea053SToby Isaac           ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
18805fdea053SToby Isaac           for (j = sl->minMaxOrients[i][0]; j < sl->minMaxOrients[i][1]; j++) {
18815fdea053SToby Isaac             if (!((sl->perms[i] && sl->perms[i][j]) || (sl->rots[i] && sl->rots[i][j]))) {
18825fdea053SToby Isaac               ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D: identity\n",j);CHKERRQ(ierr);
18835fdea053SToby Isaac             } else {
18845fdea053SToby Isaac               PetscInt tab;
18855fdea053SToby Isaac 
18865fdea053SToby Isaac               ierr = PetscViewerASCIIPrintf(viewer, "Orientation %D:\n",j);CHKERRQ(ierr);
18875fdea053SToby Isaac               ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
18885fdea053SToby Isaac               ierr = PetscViewerASCIIGetTab(viewer,&tab);CHKERRQ(ierr);
18895fdea053SToby Isaac               if (sl->perms[i] && sl->perms[i][j]) {
18905fdea053SToby Isaac                 ierr = PetscViewerASCIIPrintf(viewer,"Permutation:");CHKERRQ(ierr);
18915fdea053SToby Isaac                 ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr);
18925fdea053SToby Isaac                 for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %D",sl->perms[i][j][k]);CHKERRQ(ierr);}
18935fdea053SToby Isaac                 ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
18945fdea053SToby Isaac                 ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr);
18955fdea053SToby Isaac               }
18965fdea053SToby Isaac               if (sl->rots[i] && sl->rots[i][j]) {
18975fdea053SToby Isaac                 ierr = PetscViewerASCIIPrintf(viewer,"Rotations:  ");CHKERRQ(ierr);
18985fdea053SToby Isaac                 ierr = PetscViewerASCIISetTab(viewer,0);CHKERRQ(ierr);
18995fdea053SToby Isaac #if defined(PETSC_USE_COMPLEX)
19005fdea053SToby 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);}
19015fdea053SToby Isaac #else
19025fdea053SToby Isaac                 for (k = 0; k < sl->sizes[i]; k++) {ierr = PetscViewerASCIIPrintf(viewer," %+f",sl->rots[i][j][k]);CHKERRQ(ierr);}
19035fdea053SToby Isaac #endif
19045fdea053SToby Isaac                 ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
19055fdea053SToby Isaac                 ierr = PetscViewerASCIISetTab(viewer,tab);CHKERRQ(ierr);
19065fdea053SToby Isaac               }
19075fdea053SToby Isaac               ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
19085fdea053SToby Isaac             }
19095fdea053SToby Isaac           }
19105fdea053SToby Isaac           ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
19115fdea053SToby Isaac         }
19125fdea053SToby Isaac         ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
19135fdea053SToby Isaac       }
19145fdea053SToby Isaac     }
19155fdea053SToby Isaac     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
19165fdea053SToby Isaac   }
19175fdea053SToby Isaac   PetscFunctionReturn(0);
19185fdea053SToby Isaac }
19195fdea053SToby Isaac 
19205fdea053SToby Isaac /*@
19215fdea053SToby Isaac   PetscSectionSymLabelSetLabel - set the label whose strata will define the points that receive symmetries
19225fdea053SToby Isaac 
19235fdea053SToby Isaac   Logically collective on sym
19245fdea053SToby Isaac 
19255fdea053SToby Isaac   Input parameters:
19265fdea053SToby Isaac + sym - the section symmetries
19275fdea053SToby Isaac - label - the DMLabel describing the types of points
19285fdea053SToby Isaac 
19295fdea053SToby Isaac   Level: developer:
19305fdea053SToby Isaac 
19315fdea053SToby Isaac .seealso: PetscSectionSymLabelSetStratum(), PetscSectionSymCreateLabel(), PetscSectionGetPointSyms()
19325fdea053SToby Isaac @*/
19335fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetLabel(PetscSectionSym sym, DMLabel label)
19345fdea053SToby Isaac {
19355fdea053SToby Isaac   PetscSectionSym_Label *sl;
19365fdea053SToby Isaac   PetscErrorCode        ierr;
19375fdea053SToby Isaac 
19385fdea053SToby Isaac   PetscFunctionBegin;
19395fdea053SToby Isaac   PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1);
19405fdea053SToby Isaac   sl = (PetscSectionSym_Label *) sym->data;
19415fdea053SToby Isaac   if (sl->label && sl->label != label) {ierr = PetscSectionSymLabelReset(sym);CHKERRQ(ierr);}
19425fdea053SToby Isaac   if (label) {
19435fdea053SToby Isaac     sl->label = label;
1944d67d17b1SMatthew G. Knepley     ierr = PetscObjectReference((PetscObject) label);CHKERRQ(ierr);
19455fdea053SToby Isaac     ierr = DMLabelGetNumValues(label,&sl->numStrata);CHKERRQ(ierr);
19461a834cf9SToby 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);
19471a834cf9SToby Isaac     ierr = PetscMemzero((void *) sl->modes,(sl->numStrata+1)*sizeof(PetscCopyMode));CHKERRQ(ierr);
19481a834cf9SToby Isaac     ierr = PetscMemzero((void *) sl->sizes,(sl->numStrata+1)*sizeof(PetscInt));CHKERRQ(ierr);
19491a834cf9SToby Isaac     ierr = PetscMemzero((void *) sl->perms,(sl->numStrata+1)*sizeof(const PetscInt **));CHKERRQ(ierr);
19501a834cf9SToby Isaac     ierr = PetscMemzero((void *) sl->rots,(sl->numStrata+1)*sizeof(const PetscScalar **));CHKERRQ(ierr);
19511a834cf9SToby Isaac     ierr = PetscMemzero((void *) sl->minMaxOrients,(sl->numStrata+1)*sizeof(PetscInt[2]));CHKERRQ(ierr);
19525fdea053SToby Isaac   }
19535fdea053SToby Isaac   PetscFunctionReturn(0);
19545fdea053SToby Isaac }
19555fdea053SToby Isaac 
19565fdea053SToby Isaac /*@C
19575fdea053SToby Isaac   PetscSectionSymLabelSetStratum - set the symmetries for the orientations of a stratum
19585fdea053SToby Isaac 
19595b5e7992SMatthew G. Knepley   Logically collective on sym
19605fdea053SToby Isaac 
19615fdea053SToby Isaac   InputParameters:
19625b5e7992SMatthew G. Knepley + sym       - the section symmetries
19635fdea053SToby Isaac . stratum   - the stratum value in the label that we are assigning symmetries for
19645fdea053SToby Isaac . size      - the number of dofs for points in the stratum of the label
19655fdea053SToby Isaac . minOrient - the smallest orientation for a point in this stratum
19665fdea053SToby Isaac . maxOrient - one greater than the largest orientation for a ppoint in this stratum (i.e., orientations are in the range [minOrient, maxOrient))
19675fdea053SToby Isaac . mode      - how sym should copy the perms and rots arrays
19685fdea053SToby Isaac . perms     - NULL if there are no permutations, or (maxOrient - minOrient) permutations, one for each orientation.  A NULL permutation is the identity
1969a2b725a8SWilliam 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
19705fdea053SToby Isaac 
19715fdea053SToby Isaac   Level: developer
19725fdea053SToby Isaac 
19735fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetPointSyms(), PetscSectionSymCreateLabel()
19745fdea053SToby Isaac @*/
19755fdea053SToby Isaac PetscErrorCode PetscSectionSymLabelSetStratum(PetscSectionSym sym, PetscInt stratum, PetscInt size, PetscInt minOrient, PetscInt maxOrient, PetscCopyMode mode, const PetscInt **perms, const PetscScalar **rots)
19765fdea053SToby Isaac {
19775fdea053SToby Isaac   PetscSectionSym_Label *sl;
1978d67d17b1SMatthew G. Knepley   const char            *name;
1979d67d17b1SMatthew G. Knepley   PetscInt               i, j, k;
19805fdea053SToby Isaac   PetscErrorCode         ierr;
19815fdea053SToby Isaac 
19825fdea053SToby Isaac   PetscFunctionBegin;
19835fdea053SToby Isaac   PetscValidHeaderSpecific(sym,PETSC_SECTION_SYM_CLASSID,1);
19845fdea053SToby Isaac   sl = (PetscSectionSym_Label *) sym->data;
19855fdea053SToby Isaac   if (!sl->label) SETERRQ(PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_WRONGSTATE,"No label set yet");
19865fdea053SToby Isaac   for (i = 0; i <= sl->numStrata; i++) {
19875fdea053SToby Isaac     PetscInt value = (i < sl->numStrata) ? sl->label->stratumValues[i] : sl->label->defaultValue;
19885fdea053SToby Isaac 
19895fdea053SToby Isaac     if (stratum == value) break;
19905fdea053SToby Isaac   }
1991d67d17b1SMatthew G. Knepley   ierr = PetscObjectGetName((PetscObject) sl->label, &name);CHKERRQ(ierr);
1992d67d17b1SMatthew G. Knepley   if (i > sl->numStrata) SETERRQ2(PetscObjectComm((PetscObject)sym),PETSC_ERR_ARG_OUTOFRANGE,"Stratum %D not found in label %s\n",stratum,name);
19935fdea053SToby Isaac   sl->sizes[i] = size;
19945fdea053SToby Isaac   sl->modes[i] = mode;
19955fdea053SToby Isaac   sl->minMaxOrients[i][0] = minOrient;
19965fdea053SToby Isaac   sl->minMaxOrients[i][1] = maxOrient;
19975fdea053SToby Isaac   if (mode == PETSC_COPY_VALUES) {
19985fdea053SToby Isaac     if (perms) {
19995fdea053SToby Isaac       PetscInt    **ownPerms;
20005fdea053SToby Isaac 
20015fdea053SToby Isaac       ierr = PetscCalloc1(maxOrient - minOrient,&ownPerms);CHKERRQ(ierr);
20025fdea053SToby Isaac       for (j = 0; j < maxOrient-minOrient; j++) {
20035fdea053SToby Isaac         if (perms[j]) {
20045fdea053SToby Isaac           ierr = PetscMalloc1(size,&ownPerms[j]);CHKERRQ(ierr);
20055fdea053SToby Isaac           for (k = 0; k < size; k++) {ownPerms[j][k] = perms[j][k];}
20065fdea053SToby Isaac         }
20075fdea053SToby Isaac       }
20085fdea053SToby Isaac       sl->perms[i] = (const PetscInt **) &ownPerms[-minOrient];
20095fdea053SToby Isaac     }
20105fdea053SToby Isaac     if (rots) {
20115fdea053SToby Isaac       PetscScalar **ownRots;
20125fdea053SToby Isaac 
20135fdea053SToby Isaac       ierr = PetscCalloc1(maxOrient - minOrient,&ownRots);CHKERRQ(ierr);
20145fdea053SToby Isaac       for (j = 0; j < maxOrient-minOrient; j++) {
20155fdea053SToby Isaac         if (rots[j]) {
20165fdea053SToby Isaac           ierr = PetscMalloc1(size,&ownRots[j]);CHKERRQ(ierr);
20175fdea053SToby Isaac           for (k = 0; k < size; k++) {ownRots[j][k] = rots[j][k];}
20185fdea053SToby Isaac         }
20195fdea053SToby Isaac       }
20205fdea053SToby Isaac       sl->rots[i] = (const PetscScalar **) &ownRots[-minOrient];
20215fdea053SToby Isaac     }
20225fdea053SToby Isaac   } else {
20235fdea053SToby Isaac     sl->perms[i] = perms ? &perms[-minOrient] : NULL;
20245fdea053SToby Isaac     sl->rots[i]  = rots ? &rots[-minOrient] : NULL;
20255fdea053SToby Isaac   }
20265fdea053SToby Isaac   PetscFunctionReturn(0);
20275fdea053SToby Isaac }
20285fdea053SToby Isaac 
20295fdea053SToby Isaac static PetscErrorCode PetscSectionSymGetPoints_Label(PetscSectionSym sym, PetscSection section, PetscInt numPoints, const PetscInt *points, const PetscInt **perms, const PetscScalar **rots)
20305fdea053SToby Isaac {
20315fdea053SToby Isaac   PetscInt              i, j, numStrata;
20325fdea053SToby Isaac   PetscSectionSym_Label *sl;
20335fdea053SToby Isaac   DMLabel               label;
20345fdea053SToby Isaac   PetscErrorCode        ierr;
20355fdea053SToby Isaac 
20365fdea053SToby Isaac   PetscFunctionBegin;
20375fdea053SToby Isaac   sl = (PetscSectionSym_Label *) sym->data;
20385fdea053SToby Isaac   numStrata = sl->numStrata;
20395fdea053SToby Isaac   label     = sl->label;
20405fdea053SToby Isaac   for (i = 0; i < numPoints; i++) {
20415fdea053SToby Isaac     PetscInt point = points[2*i];
20425fdea053SToby Isaac     PetscInt ornt  = points[2*i+1];
20435fdea053SToby Isaac 
20445fdea053SToby Isaac     for (j = 0; j < numStrata; j++) {
20455fdea053SToby Isaac       if (label->validIS[j]) {
20465fdea053SToby Isaac         PetscInt k;
20475fdea053SToby Isaac 
20485fdea053SToby Isaac         ierr = ISLocate(label->points[j],point,&k);CHKERRQ(ierr);
20495fdea053SToby Isaac         if (k >= 0) break;
20505fdea053SToby Isaac       } else {
20515fdea053SToby Isaac         PetscBool has;
20525fdea053SToby Isaac 
2053b9907514SLisandro Dalcin         ierr = PetscHSetIHas(label->ht[j], point, &has);CHKERRQ(ierr);
20545fdea053SToby Isaac         if (has) break;
20555fdea053SToby Isaac       }
20565fdea053SToby Isaac     }
20575fdea053SToby Isaac     if ((sl->minMaxOrients[j][1] > sl->minMaxOrients[j][0]) && (ornt < sl->minMaxOrients[j][0] || ornt >= sl->minMaxOrients[j][1])) SETERRQ5(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);
20585fdea053SToby Isaac     if (perms) {perms[i] = sl->perms[j] ? sl->perms[j][ornt] : NULL;}
20595fdea053SToby Isaac     if (rots) {rots[i]  = sl->rots[j] ? sl->rots[j][ornt] : NULL;}
20605fdea053SToby Isaac   }
20615fdea053SToby Isaac   PetscFunctionReturn(0);
20625fdea053SToby Isaac }
20635fdea053SToby Isaac 
20645fdea053SToby Isaac PetscErrorCode PetscSectionSymCreate_Label(PetscSectionSym sym)
20655fdea053SToby Isaac {
20665fdea053SToby Isaac   PetscSectionSym_Label *sl;
20675fdea053SToby Isaac   PetscErrorCode        ierr;
20685fdea053SToby Isaac 
20695fdea053SToby Isaac   PetscFunctionBegin;
20705fdea053SToby Isaac   ierr = PetscNewLog(sym,&sl);CHKERRQ(ierr);
20715fdea053SToby Isaac   sym->ops->getpoints = PetscSectionSymGetPoints_Label;
20725fdea053SToby Isaac   sym->ops->view      = PetscSectionSymView_Label;
20735fdea053SToby Isaac   sym->ops->destroy   = PetscSectionSymDestroy_Label;
20745fdea053SToby Isaac   sym->data           = (void *) sl;
20755fdea053SToby Isaac   PetscFunctionReturn(0);
20765fdea053SToby Isaac }
20775fdea053SToby Isaac 
20785fdea053SToby Isaac /*@
20795fdea053SToby Isaac   PetscSectionSymCreateLabel - Create a section symmetry that assigns one symmetry to each stratum of a label
20805fdea053SToby Isaac 
20815fdea053SToby Isaac   Collective
20825fdea053SToby Isaac 
20835fdea053SToby Isaac   Input Parameters:
20845fdea053SToby Isaac + comm - the MPI communicator for the new symmetry
20855fdea053SToby Isaac - label - the label defining the strata
20865fdea053SToby Isaac 
20875fdea053SToby Isaac   Output Parameters:
20885fdea053SToby Isaac . sym - the section symmetries
20895fdea053SToby Isaac 
20905fdea053SToby Isaac   Level: developer
20915fdea053SToby Isaac 
20925fdea053SToby Isaac .seealso: PetscSectionSymCreate(), PetscSectionSetSym(), PetscSectionGetSym(), PetscSectionSymLabelSetStratum(), PetscSectionGetPointSyms()
20935fdea053SToby Isaac @*/
20945fdea053SToby Isaac PetscErrorCode PetscSectionSymCreateLabel(MPI_Comm comm, DMLabel label, PetscSectionSym *sym)
20955fdea053SToby Isaac {
20965fdea053SToby Isaac   PetscErrorCode        ierr;
20975fdea053SToby Isaac 
20985fdea053SToby Isaac   PetscFunctionBegin;
20995fdea053SToby Isaac   ierr = DMInitializePackage();CHKERRQ(ierr);
21005fdea053SToby Isaac   ierr = PetscSectionSymCreate(comm,sym);CHKERRQ(ierr);
21015fdea053SToby Isaac   ierr = PetscSectionSymSetType(*sym,PETSCSECTIONSYMLABEL);CHKERRQ(ierr);
21025fdea053SToby Isaac   ierr = PetscSectionSymLabelSetLabel(*sym,label);CHKERRQ(ierr);
21035fdea053SToby Isaac   PetscFunctionReturn(0);
21045fdea053SToby Isaac }
2105